Variable in .noinit scheint Initialisiert zu werden

OP Persönliche Seite #368187
Lesenswert?

Hallo,
Ich möchte dass eine Variable während eines Watchdog Resets (ATMega8)
erhalten bleibt und habe daher die Variable in die Sektion .noinit
getan:
1
u08 volatile baudval __attribute__((section(".noinit")));
Die Variable wird also nur initialisiert wenn der Reset nicht durch den
Watchdog erfolgt:
1
if (MCUCSR != (1<<WDRF)) {  //Wenn kein Watchdog reset
2
  baudval = baud9600val;
3
}
Direkt nach dem Code gebe ich die Variable aus. Nach einem Power-On
steht in der Variable der gewünscht Wert, nach einem Watchdog Reset
jedoch immer 0. Testeshalber habe ich direkt vor der Watchdog
Aktivierung die Variable mal auf einen Wert gesetzt und bin dann in
eine Endlosschleife gegangen:
1
baudval = 42;
2
wdt_enable(WDTO_15MS);
3
_delay_ms(200.0);
Die Variable ist jedoch nach dem Reset weiterhin Null.

Kann mir jemand sagen wo die Ursache dafür liegt?
Moderator Persönliche Seite #368188
Lesenswert?

Dein Test ist flasch.  Die Flags in MCU[C]SR akkumulieren, d. h.
wenn du das PORF nicht löschst, ist es zusammen mit dem WDRF nach
dem nächsten watchdog reset gemeinsam dort vorhanden.  Damit
schlägt dein purer Test auf Ungleichheit aber fehl, und du
initialisierst deine Variable trotzdem.

Bei Prozessoren mit dem neuen AVR-Watchdog musst du sowieso
vorsichtig sein: dort kann man den Watchdog, wenn er einmal
zugeschlagen hat, nicht so einfach wieder loswerden, der triggert
sonst immer wieder neu.  Daher empfiehlt es sich, den Wachhund
möglichst frühzeitig (am besten in .init3) außer Betrieb zu nehmen
und dort den Reset-Status zu retten.  Das habe ich in der avr-libc-
Doku beispielhaft beschrieben (im Kapitel zu <avr/wdt.h>).
OP Persönliche Seite #368189
Lesenswert?

Ok, ich hätte wohl einen etwas größeren Auschnitt aus meinem Quellcode
posten sollen:
1
if (MCUCSR != (1<<WDRF)) {  //Wenn kein Watchdog reset
2
  baudval = baud9600val;
3
}
4
MCUCSR = 0;
5
[0]
6
und
7
[c]
8
#define F_CPU 11059200
9
#define baud9600val (F_CPU/(9600*16l)-1)
Der Test funktioniert auch, nach dem power-on ist der Wert wie erwartet
71. Nach dem Watchdog-Reset ist der Wert 0, müsste aber 42 sein.

Dass der Watchdog nach einem Reset bei den neueren Modellen nicht
automatisch deativiert wird, ist gut zu wissen. Scheint aber bei dem
ATMEGA8 nicht der Fall zu sein.
Moderator Persönliche Seite #368190
Lesenswert?

Simulierst du, oder hast du richtiges Silizium?

Ich frage nur, weil ich gerade eine ähnliche Anfrage in
avrfreaks.net gelesen habe, und diese sich auf den Simulator
von AVR Studio bezog...  Manche Details bekommt er wohl nicht
so recht hin.

Mein persönliches Testprogramm für die avr-libc, das ich nach
der Portierung auf jeden neuen AVR loslasse, testet jedenfalls
das WDRF, und das hat bislang immer funktioniert.  Auch die
.noinit-Variablen funktionieren sehr wohl (ist auch recht gut
durchschaubar, wenn man das Prinzip verstanden hat).
Gast #368193
Lesenswert?

Dazu hätt ich auch eine kleine Frage:

Mein Bootloader verwendet nur .noinit-Variablen und keine Interrupts.
Gibt's irgendeinen trick wie ich dem gcc sagen kann das er sich die
vector tabelle und die .data/.bss intialisierung schenken kann? Das
sind zusammen immerhin 100 Bytes...
Moderator Persönliche Seite #368195
Lesenswert?

> Zur Vektortabelle gibts ne Compiler Option:

Nö, leider nicht.  -mno-interrupts bewirkt nur, dass bei
Manipulieren des Stackpointers die Interrupts nicht gesperrt
werden.  Die Vektortabelle selbst stammt aus dem gcrt1.S und
ist derzeit nicht optional.  Wenn man sie weglassen will, müsste
man eine eigene modifizierte Kopie dieser Datei für den
Bootloader nehmen.

Theoretisch sollte das Initialisieren von .data und .bss ja mal
optional sein können, aber derzeit fehlt der Code für die
entsprechende Analyse im GCC, daher generiert er immer Referenzen
zu den Symbolen für diese Routinen.  Kann man sich im generierten
Assemblercode (nicht im Disassembler!) gut ansehen und könnte
man genau dort auch manipulieren: wenn man die dort rausstreicht,
hat der Linker keinen Grund mehr, die entsprechenden Funktionen
aus der Bibliothek dazuzulinken.

Allerdings haben solche Verrenkungen natürlich nur Sinn, wenn man
dadurch auch auf die nächstkleinere bootloader section gehen
kann.  Ansonsten bekommt man für nicht genutzten Flash kein Geld
zurück. ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren