Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 30 mar 2026, o 22:38


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 6 ] 
Autor Wiadomość
PostNapisane: 22 gru 2017, o 18:35 
Offline
Nowy

Dołączył(a): 27 lis 2014
Posty: 11
Pomógł: 0

Mam problem z pamięcią programu kod

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Daje taki wynik. Pierwszy przebieg jest OK drugi jest obcięty.

Obrazek

a przebiegi powinny być takie same i nie wiem gdzie mam błąd. Kod pilota podany wprost do zmiennej działa a odczytany z Flash tylko częściowo.
Nie było by problemu gdyby nie mój upór na tiny 13 (64b RAM) . Może się nie da a ja za bardzo kombinuję . Za wszelką pomoc Dziękuje :)

Próbowałem jeszcze zapisać kod jako liczbę binarnie a potem skonwertować na string ale to też nie działa . Wysyłane dane muszą być takie send("000000000001010100010100").



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 gru 2017, o 19:58 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Przede wszystkim ATtiny13 ma tylko 64 bajty pamięci RAM. Ten kod jest wysoce nieoptymalny, szczególnie dla takiego małego mikrokontrolera.

czech_w napisał(a):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

To nie jest dobry pomysł. Definiujesz wskaźnik jako niezainicjowaną zmienną lokalną, a później używasz go jak tablicy znaków. Trudno przewidzieć, dokąd Ty w ogóle kopiujesz te znaki z tablicy we FLASH.
Powinno być na przyklad tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

choć i tak nie wiadomo czy wystarczy pamięci RAM. Ewentualnie można jeszcze spróbować usunąć zupełnie linijki:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


czech_w napisał(a):
Wysyłane dane muszą być takie send("000000000001010100010100").

To nieprawda. Można przekazać do funkcji dane binarne, tylko trzeba ją odpowiednio zmodyfikować. Nawet byłoby to wskazane przy tak małym mikrokontrolerze. Ogólnie, tak jak napisałem, ten kod jest nieoptymalny, a tutaj liczy się każdy bajt pamięci RAM. Jak będziesz próbował ten kod rozbudować, to i tak pewnie zabraknie RAM. Moim zdaniem najlepiej byłoby to wszystko napisać od nowa z uwzględnieniem bardzo ograniczonych zasobów tego mikrokontrolera.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 gru 2017, o 10:07 
Offline
Nowy

Dołączył(a): 27 lis 2014
Posty: 11
Pomógł: 0

na dwa kody RAM u wystarcza. Dlatego napisałem że się uparłem na AtTiny13a. Co do kodu masz rację to przenosiny z arduino (AtMega328) a tam nie ma problemu z RAM.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


ten kod to tylko do sprawdzenia czy działa :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 gru 2017, o 11:24 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

czech_w napisał(a):
na dwa kody RAM u wystarcza.

Ale jesteś pewien, czy tak Ci się wydaje?

To, że dwie tablice mają razem 50 bajtów, to jeszcze nie wszystko.
Każde wywołanie funkcji powoduje powiększenie stosu, który też jest w RAM.
Każde użycie zmiennej lokalnej (jeszcze w dodatku 16-bitowej, tam gdzie wystarczy 8-bitowa) wewnątrz funkcji zwykle powiększa stos.
Każde zagnieżdżenie (wywołanie funkcji wewnątrz funkcji) powoduje jeszcze znaczniejsze powiększenie stosu (na zasadzie kumulacji).
W Twoim kodzie z funkcji main() jest wywoływana funkcja send().
Wewnątrz funkcji send() jest wywoływana jedna z funkcji send0(), send1() lub sendSync().
Wewnątrz funkcji np. send0() jest wywoływana funkcja transmit().
Wewnątrz funkcji transmit() jest wywoływana funkcja delayus().
Łącznie poczwórne zagnieżdżenie.
We większości funkcji masz zmienne lokalne, które najprawdopodobniej znajdą się na stosie.
Zwykle każda funkcja korzysta z rejestrów, których zawartość musi być przywrócona po zakończeniu funkcji, więc są one zapamiętywane na stosie.

Nie twierdzę wcale, że nie masz racji. Być może tej pamięci jest wystarczająco dużo. Nie chce mi się tego dokładnie analizować i liczyć (może chodzić o pojedyncze bajty), ale pytanie jest takie: Czy Ty to dokładnie sprawdziłeś, czy tak sobie tylko założyłeś na podstawie szacunkowych obliczeń?
...bo to wcale nie jest takie pewne i oczywiste...

czech_w napisał(a):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

ten kod to tylko do sprawdzenia czy działa

A sprawdziłeś, co będzie po usunięciu tych dwóch linii i zmianie char* k1; na char k1[25]; tak jak radziłem, czy po prostu założyłeś z góry, że to nie zadziała?
Nawet jeśli pamięci jest dosyć, to i tak char* k1; to ewidentny błąd, więc może nie zaszkodziłoby spróbować to zmienić.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 gru 2017, o 20:27 
Offline
Nowy

Dołączył(a): 27 lis 2014
Posty: 11
Pomógł: 0

Sprawdziłem i działa

Pierwszy przebieg z k6 drugi z k1 jako k1[25]

Obrazek

andrews napisał(a):

czech_w napisał(a):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

ten kod to tylko do sprawdzenia czy działa

A sprawdziłeś, co będzie po usunięciu tych dwóch linii i zmianie char* k1; na char k1[25]; tak jak radziłem, czy po prostu założyłeś z góry, że to nie zadziała?
Nawet jeśli pamięci jest dosyć, to i tak char* k1; to ewidentny błąd, więc może nie zaszkodziłoby spróbować to zmienić.


Czyli tak mogę zarezerwować pamięć powiedzmy dynamicznie jak rozumiem. Ponieważ po kompilacji samej zmiennej(stałej) k1[25] mam Data: 0 Bytes a przy kompilacji k1[25] i k6 mam Data 26 Bytes.

Dziękuję za pomoc



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 gru 2017, o 10:42 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

czech_w napisał(a):
Czyli tak mogę zarezerwować pamięć powiedzmy dynamicznie jak rozumiem. Ponieważ po kompilacji samej zmiennej(stałej) k1[25] mam Data: 0 Bytes a przy kompilacji k1[25] i k6 mam Data 26 Bytes.

Chyba nie bardzo rozumiesz. Do dynamicznej alokacji pamięci służą np. funkcje malloc() i free() z biblioteki standardowej stdlib.h. Linijka char k1[25]; ma na celu po prostu zarezerwowanie 25 bajtów RAM na tablicę o nazwie k1. Miejsce, w którym zostanie tablica ulokowana (w sekcji .data, .bss czy na stosie) jest zależne od sposobu i miejsca zdefiniowania zmiennej.

Na wskazaniach zajętości pamięci obliczanych przez program avr-size zbytnio bym nie polegał. W tym przypadku zmienna (tablica) k1 zostanie najprawdopodobniej umieszczona przez kompilator na stosie, a stos nie jest uwzględniany przez avr-size. Gdybyś zdefiniował ją globalnie, wtedy zapewne zostałaby wliczona w zajętość RAM (w sekcji .bss, kiedy nie jest zainicjowana żadną wartością).

W tym przypadku problem polegał głównie na nieprawidłowym definiowaniu tablic, a właściwie braku ich definicji. Prawidłowe zdefiniowanie tablice powinno wyglądać tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


To co zrobiłeś natomiast wygląda tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Oczywiście w procesie optymalizacji kompilator może np. pewne zmienne usunąć, więc nie zawsze będzie dokładnie tak, jak to opisałem powyżej, niemniej tak kompilator interpretuje intencje programisty.

Podejrzewam, że w trakcie kompilacji otrzymałeś od kompilatora warning o niezainicjowanym wskaźniku, który najprawdopodobniej zignorowałeś.

Dodatkowo kod jest tak nieoptymalny, że osobiście nie napisałbym w ten sposób programu nawet mając do dyspozycji kilka KiB RAM. Używanie 25 bajtów RAM dla zmiennej mieszczącej się w czterech bajtach, tym bardziej kiedy nie jest to uzasadnione uzyskaniem jakiejś innej korzyści (np. w postaci szybkości wykonywania kodu), nigdy nie jest dobrą praktyką. To samo zresztą dotyczy np. używania w pętli wykonującej się kilka razy iteratora 16-bitowego. No ale to temat poboczny, więc nie będę się tu nad nim zbytnio rozwodził ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 6 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 3 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO