AT91SAM7S... CrossStudio i zmienne

Wiam wszystkich.

Może ktoś podpowie, w jaki sposób zadeklarować w środowisku j.w. zmienną globalną, która nie będzie inicjowana w momencie startu programu. Muszę wyeliminować jej zerowanie w przypadku zadziałania watchdog`a. Wiem, że "help" twoim przyjacielem, ale sprawa jest na "wczoraj". Proszę o wyrozumiałość i nie odsyłanie do "F1" :-)

Pozdrawiam

Reply to
ELP
Loading thread data ...

ELP napisał(a):

W prosty sposob nie da sie tego zrobic. Kazda zmienna globalne jest inicjowana - na 0 lub wartosc wpisana w programie. Jedyne co mi przychodzi do glowy, to zarezerwowanie np. czterech bajtow w pamieci poprzez skrypt linkera i odwolywanie sie do tego obszaru poprzez wskaznik na unsigned long. Ale jak to nie bedzie inicjowane, to wtedy po wlaczeniu zasilania moze byc dowolna wartosc. Dosc ryzykowny sposob na rozpoznanie resetu watchdoga. A swoja droga, w tym procesorze da sie odczytac powod resetu. Zobacz na strone 69 dokumentacji - rejestr RSTC_SR.

Ewentualnie mozna w startup-ie spawdzic powod resetu i jesli to watchdog, to pomijamy inicjalizacje tej zmiennej. W kazdym razie raczej nie da rady bez grzebania w plikach startowych.

Pozdr AK

Reply to
AK

ELP napisał(a):

A może wrzucić ją do innej sekcji niż .data przez np. __attribute__ coś tam, i tylko odpowiednio zmodyfikować plik linkera aby zamapował tą sekcję w pamięci ram.

Reply to
Artur P

ELP napisał(a):

Polecamy przejście na gcc (np. pakiet gnuarm). Wystarczy przenieść zmienną do niestandardowej sekcji (cała sekcja .bss jest zerowana przy starcie) i dodać taką sekcję w pliku linkera.

unsigned int mojaflaga __attribute__ ((section (".noinit"));

Ewentualnie możesz "na sztywno" wymyślić jakiś adres, np. pod koniec wewnętrznej pamięci RAM i z tamtej komórki korzystać. Pamiętaj wtedy o potrzebnym ograniczeniu zakresu działania malloc'a (dokładniej mówiąc sbrk) aby sterta nie zjadła twojej zmiennej.

unsigned int *mojaflaga = (unsigned int *) 0x12345678; // (wstaw adres)

*mojaflaga = 7;

Zrób bardziej skomplikowany system flag - bo oczywiście przy pierwszym włączeniu zasilania w RAMie będą krzaki i twoja flaga akurat może się okazać ustawiona we właściwy sposób. Skutecznym wyjściem jest opatrzenie zestawu danych niekasowanych jakimś nagłówkiem (np. słowem 0xabcd1234) i zakończenie sumą kontrolną CRC32 liczoną z całego zabezpieczanego bloku.

Najlepszym rozwiązaniem jest jednak odczytanie z rejestru powodu resetu procesora i na tej podstawie sprawdzenie, czy reset był w wyniku zadziałania wewnętrznego watchdoga. Oczywiście to odpada gdy masz watchdoga na zewnątrz i nie da się odróżnić resetu przyciskiem od resetu watchdogiem.

Reply to
Adam Dybkowski

Adam Dybkowski napisał(a):

CrossStudio korzysta właśnie z GCC.

pzdr

Reply to
Elektrolot

Jak kolega poniżej napisał, CrossStudio korzysta z GCC. Nie wiem jednak jak dodać taką sekcję do pliku linkera. Może jakiś przykład?

To faktycznie działa, ale ja tak na prawdę potrzebuję kilkadziesiąt takich zmiennych, no i w tym momencie robi się to troszeczkę upierdliwe (wyliczanie adresów - łatwo o pomyłkę).

Właśnie tak to ma być zrobione.

Pozdrawiam

Reply to
ELP

ELP napisał(a):

Zobacz, jak jest zrobiona obecnie np. sekcja .bss i wyrzuć z jej deklaracji wszystkie niepotrzebne definicje adresów (początek i koniec sekcji .bss - wykorzystywane do wyczyszczenia jej przy starcie). W pliku linkera (.ld) w bloku SECTIONS powinieneś dodać coś w tym rodzaju:

.noinit : { *(.noinit) } >ram

Oczywiście "ram" zastąp nazwą obszaru pamięci, który definiujesz na początku swojego pliku linkera (w bloku MEMORY).

Reply to
Adam Dybkowski

Dzięki za podpowiedź. Będę próbował tego sposobu. Troszkę poszukałem i znalazłem zadeklarowane sekcje, które nie są inicjowane przy starcie uC. Dla programu ładowanego do RAM jest to sekcja ".fast_load", a dla ładowanego do Flash ".fast_run". Malutkie makro uzależniające deklarację zmiennych w zależności od tego, gdzie jest program ładowany (Ram, Flash) i efekt jest 100%owy. Może to nie "po bożemu", ale diała :-)

Dzięki wzystkim za pomoc. Pozdrawiam.

Reply to
ELP

ELP napisał(a):

Bardzo dobry sposób. Jeżeli twój plik linkera już definiuje sekcje, które nie są zmieniane przy starcie programu - to najlepiej właśnie z nich skorzystać.

Reply to
Adam Dybkowski

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.