mikrocontroller.net

Forum: Compiler & IDEs Variable in .noinit scheint Initialisiert zu werden


Autor: Malte __ (malte) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
u08 volatile baudval __attribute__((section(".noinit")));
Die Variable wird also nur initialisiert wenn der Reset nicht durch den
Watchdog erfolgt:
if (MCUCSR != (1<<WDRF)) {  //Wenn kein Watchdog reset
  baudval = baud9600val;
}
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:
baudval = 42;
wdt_enable(WDTO_15MS);
_delay_ms(200.0);
Die Variable ist jedoch nach dem Reset weiterhin Null.

Kann mir jemand sagen wo die Ursache dafür liegt?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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>).

Autor: Malte __ (malte) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ich hätte wohl einen etwas größeren Auschnitt aus meinem Quellcode
posten sollen:
if (MCUCSR != (1<<WDRF)) {  //Wenn kein Watchdog reset
  baudval = baud9600val;
}
MCUCSR = 0;
[0]
und
[c]
#define F_CPU 11059200
#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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Malte __ (malte) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richtiges Silizium :-) Das AvrStudio4 geht nicht mit WINE.
Aber da ist mir gerade was aufgefallen... ich hab ja nen Bootloader (
http://www.mikrocontroller.net/forum/read-4-53146.html ) mit auf dem
Chip und bei einem Reset geht der ja erstmal los... ich vermute der
setzt die 0 in die Speicherzelle.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am besten im Bootloader nur .noinit-Variablen benutzen oder
einen separat zugewiesenen Teil des RAMs.  Dann kann der
natürlich auch das MCU[C]SR auslesen und an eine vereinbarte
Stelle speichern.

Autor: m4444x (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Malte __ (malte) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur Vektortabelle gibts ne Compiler Option:
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/AVR-Op...

Bei dem Rest kenn ich mich nicht aus. Das schreiben eines eigenen
Bootloaders steht noch an.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.