defioniowanie zmiennych w WINAVR

Jul 30, 2004 17 Replies

witam



jak to jest w winavr jak sobie zdefiniuje zmienna jako



char tablica[1000];



to gdzie ona zostanie umieszczona? w SRAM'ie czy we flashu? bo wykrylem taka prawidlowosc ze jezeli zainicjalizuje tablice a wiec wpisze char tablica[1000] = "\0"; wowczas tablica ta jest umieszczona w hexie po skompilowaniu a jezeli nie zainicjalizuje czyli wpisze: char tablica[1000]; to jej nie ma w hexie, czy to oznacza ze jest wowczas tworzona w pamieci SRAM?



Krzysztof



jak zainicjalizujesz to ta tablica zostanie przy starcie kopiowana z flasha do ramu. Je¿eli nie to kompilator zarezerwuje tylko dla niej miejsce w ramie.

Mister

U¿ytkownik "Mister" <wojpie@wywal_to.poczta.onet.pl> napisa³ w wiadomo¶ci news:cedlon$bei$ snipped-for-privacy@atlantis.news.tpi.pl...

dzieki chyba sam bym na to nie wpadl:)

Krzysztof

A co tu jest odkrywczego??;-) no przecie¿ jak inicjalizujesz tablicê jakimi¶ sta³ymi to po resecie trzeba to odtworzyæ i musz± byæ gdzie¶ zapamiêtane. Inna sprawa jest ze zmiennymi które s± inicjalizowane zerami wtedy najczê¶ciej kompilator robi pêtelkê w której zeruje ten obszar pamiêci.

Mister

Ale kod startowy zeruje caly ten zarezerwowany obszar.

Krzysiek Rudnik

Krzysztof Rudnik napisal(a):

Tylko w przypadku zmiennych globalnych i statycznych, nieprawdaz?

Tylko dla takich zmiennych jest rezerwowane miejsce przez kompilator. Inne zmienne rezerwowane sa w czasie wykonania.

Krzysiek Rudnik

Podczas kompilacji kompilator rozrzuca produkty kompilacji w (co najmniej) trzy miejsca zwane sekcjami:

- sekcja .text - tutaj ląduje kod programu,

- sekcja .data - tutaj lądują zmienne zainicjalizowane, czyli np. int x = 5;

- sekcja .bss - tutaj są umieszczane zmienne niezainicjalizowane, czyli np. int x;

Zawartość sekcji .data musi być umieszczona w pamięci nieulotnej ponieważ, tak jak to już zostało napisane, podczas startu programu musi ona być skopiowana w odpowiednie miejsce pamięci RAM. Natomiast sekcja .bss bywa traktowana różnie - podczas startu programu ten obszar RAM-u jest zazwyczaj zerowany (jakaś prosta pętelka), ale AFAIR standard C tego nie wymaga. Nie należy więc polegać na tym że po deklaracji int x, zmienna x zawsze będzie miała wartośc początkową 0.

Nazw .text, .data, .bss używa gcc, inne kompilatory mogą np. używać nazw CODE (lub TEXT), DATA, BSS. W każdym bądź razie idea jest taka sama.

Regards, /J.D.

On Fri, 30 Jul 2004 19:13:18 +0200, "Mister" snipped-for-privacy@poczta.onet.pl> wrote: [.....]

Kompilator nie robi żadnej pętelki. W przypadku programowania systemów embedded odpowiedni kod startowy musi zapewnić programista. Na szczęście jest tak, że producenci kompilatorów dodają do kompilatora również mniej lub bardziej użyteczną bibliotetę funcji (nazwijmy ją biblioteką standartową) oraz *kod startowy* który w zależności od konfiguracji sprzętu tudzież innych czynników programista czasami/często musi zmodyfikować.

Regards, /J.D.

Bardzo stara specyfikacja C mowila ze takie zmienne sa rzeczywiscie zerowane. Poniewaz jest to nieeleganckie i czesto niepotrzebne - co nowsze implementacje wcale nie musza zerowac.

J.

Szanowny Krzysztofie

Sprawa wyglada tak. Jezeli masz zmienne nieinicjowane, to w "heksie" nic nie ma bo nic nie inicjujesz. Jezeli natomiast masz zmienne inicjowane, wowczas gdzies musz± byc przechowane dane ktorymi inicjujesz, czyli we flash. Owa inicjalizacja jest realizowana przez tzw. rozbiegowkê, ktora jest wykonywana zanim nastapi skok do funkcji main i polega na przepisaniu tych danych z flash do obszarów pamiêci RAM, w których rezyduj± Twoje zmienne. Np, rozbiegówka w msp430 zaczyna sie ona od adresu 0, w AVR pod adresem zero jest do niej wskaznik, a potem dopiero wektor przerwan. Twoje zmienne, o ktore pytasz, zostan± umieszczone w RAMie - zarówno te inicjowane jak i nieinicjowane. Jezeli natomiast zalezy ci, aby zmienne inicjowane o wartosciach niezmiennych, czyli po polsku sta³e, leza³y wy³acznie we flash (np. ciagi znaków - teskty) to w normalnym przypadku wystarczy zapis:

const char *blabla = "blabla";

Jednak, AVR ma rozdieln± przestrzeñ adresow± dla flash i RAMu, wiêc wska¼nik do Ramu nie mo¿e dotyczyæ flash i na odwrót - s³owem zapis jak powy¿ej spowoduje, ze string "blabla" wyl±duje docelowo w RAMIE. Jest na to metoda:

const char *blabla PROGMEM = "blabla";

Teraz blabla pozostanie we flash, ale nie masz do niego bezposredniego dostêpu. Z pomoc± mo¿e przyj¶c zapis jak poni¿ej:

char TmpBufer[7]; memcpy_P(TmpBuffer, blabla);

Musisz ciag blabla najpierw rêcznie skopiowac do RAM, a dopiero potem cos z nim robiæ. Biblioteka avr-gcc zawiera ca³y zestaw funkcji i makr do operawania na wska¼nikach we flash (sprintf_P, strcpy_P, strchr_P, vsprintf_P i wiele innych - nie ma strstr_P nad czym ubolewam :)).

Pozdrawiam,

Krzysztof

U¿ytkownik "Krzysztof Skoroniak" snipped-for-privacy@NospaM.polsl.gliwice.pl> napisa³ w wiadomo¶ci news:cedkr7$lgp$ snipped-for-privacy@nemesis.news.tpi.pl...

Jezeli zmienne inicjowane s± w programie jawnie zerami, wówczas rozbiegówka nie wykonuje tego tak, jak napisa³e¶. Inicjalizacjê wykonuje tak samo, jak np w przypadku dowolnych innych warto¶ci. Automatycznie zerowane s± obszary WY£¡CZNIE zmiennych nie inicjalizowanych, czyli:

unsigned char aqq;

zapewni ¿e aqq == 0;

Krzysztof

Akurat zmienna blabla bedzie w ram. Gdzie w ROM (flash) bedzie napis, akurat tak jest ze wszystkimi stalymi napisowaymi (literalami) np te od printf:

printf("Wartosc zmiennej x = %d\n", x);

Krzysiek Rudnik

Tu nie jestem taki pewny - w sumie wynik ten sam, a umieszczenie zmiennej w .data powoduje powiekszenie binarki ladowanej do rom. Wydaje mi sie ze np. gcc 2.95 zmienne jawnie inicjowane zerami wrzucal do .bss. Musze sprawdzic.

Krzysiek Rudnik

tak oczywiscie, w przypadku AVR bedzie w RAM, o czym zreszta napisalem, ale chyba nie doczytales. Bedzie we flash, w przypadku procesora, ktory ma jednolita przestrzen adresowa dla RAM i dla flasj, np w msp430.

Stringi takie sa ladowane przez kod startowy do ram. Funkcja printf pobieta je z ram, chyba ze:

const char *aqq PROGMEM = "Wartosc zmiennej x = %d\n"; printf_P(aqq, x);

wtedy string jest pobierany bezposrednio z flash.

Ok i daj znac jak jest. Mozliwe ze jednak masz racje. Wszystko zalezy od linkera.

Akurat w AVR i 51 RAM i ROM sa rozdzielone. Inaczej trzeba je odczytywac, wiec printf czyta z RAM. A napis sie przepisuje z ROM do RAM na poczatku.

Do ROM jest inny printf.

J.

dzieki wszystkim za wyczerpujace odpowiedzi

pozdr

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required