Datum:
Hallo! System: ATmega48, 8 MHz interner Takt Ich: Anfänger Ich möchte das MCUSR Register auslesen und entspreched des entstandenen Resetursprungs die .noinit Variablen initialisieren. Ich habe für Testzwecke ein kleines Prg. geschrieben das anzeigen soll, welcher Reset aufgetreten ist. Ich habe folgendes Problem: Eigentlich sollte das Programm meines erachtens im Betrieb alle 2 s 4 mal blinken, da ja der WD einen reset ausführt. Die Realität ist jedoch, dass es immer nur einmal blinkt. Wo liegt da der Fehler?
uint8_t mcusr_mirror __attribute__ ((section (".noinit"))); //Anm. 1 void get_mcusr(void) \ //Anm. 2 __attribute__((naked)) \ __attribute__((section(".init3"))); void get_mcusr(void) { mcusr_mirror = MCUSR; MCUSR = 0; wdt_disable(); } //Blinken mit der LED void blinken(uint8_t anz) { for( ;anz > 0; anz--) { wdt_reset(); LED(1); _delay_ms(70); _delay_ms(70); LED(0); _delay_ms(70); _delay_ms(70); } } int main( void ) { port_init(); get_mcusr(); wdt_enable(WDTO_2S); // Watchdog akivieren if (mcusr_mirror & (1<<BORF)) { blinken(2); } else if (mcusr_mirror & (1<<PORF)) { blinken(3); } else if (mcusr_mirror & (1<<WDRF)) { blinken(4); } else { blinken(1); } set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Sleep Modus festlegen sleep_mode(); // Sleep Modus aktivieren } |
zu Anm. 1) Achtung wenn mann den Code aus der avr-libc Hilfe unter "<avr/wdt.h>: Watchdog timer handling" nimmt, steht statt "__attribute__" nur "_attribute_". Hat sich aber nicht übersetzen lassen, deshalb denke ich das dass nicht der Fehler ist. zu Anm. 2) Was genau bewirken diese Zeilen? Danke Norton
Datum:
Norbert S. wrote: > zu Anm. 1) Achtung wenn mann den Code aus der avr-libc Hilfe unter > "<avr/wdt.h>: Watchdog timer handling" nimmt, steht statt > "__attribute__" nur "_attribute_". Hat sich aber nicht übersetzen > lassen, deshalb denke ich das dass nicht der Fehler ist. Das ist ein Bug in der Doku. Bitte schreib einen Bugreport unter https://savannah.nongnu.org/bugs/?group=avr-libc > zu Anm. 2) Was genau bewirken diese Zeilen? > void get_mcusr(void) \ //Anm. 2 > __attribute__((naked)) \ > __attribute__((section(".init3"))); "naked" bewirkt, dass get_mcusr() nur noch syntaktisch eine Funktion ist (weil C nur innnerhalb von Funktionen Code besitzen kann), semantisch ist es aber aneindander gefädelter Maschinencode. section(".init3") schiebt den Code dann ganz vorn in die Initialisierungssequenz des Laufzeitsystems, damit er bereits weit vor dem Erreichen von main() abgearbeitet wird. http://www.nongnu.org/avr-libc/user-manual/mem_sections.html > int main( void ) > { > port_init(); > get_mcusr(); Ich vermute, genau darin liegt dein Problem: du versuchst, diese Funktion ,,aufzurufen'', aber das kann man gar nicht. Das resultierende Verhalten würde ich als `undefined' bezeichnen.
Datum:
Danke für die Antwort und die Erklärungen. Ich habe einfach die Zeile get_mcusr(); in der main weggegeben und das Programm verhält sich so wie ich es erwartet habe. Bug werde ich melden.
Datum:
wenn man sich den Code anguckt dann ist der call get_mcusr() aber in Ordnung, er wird wie ein inline ohne Prolog eingefügt. Der Fehler ist aber das get_mcusr() zweimal ausgeführt wird, einmal automatisch als init Code, dann wird die Watchdog Source auf 0 gesetzt und dann am Anfang von main beim zweiten Aufruf wird immer diese 0 wieder geladen.