Forum: Compiler & IDEs Bekomme keine gültigen MCUSR Werte


von Norbert S. (norton)


Lesenswert?

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?
1
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));    //Anm. 1
2
3
void get_mcusr(void) \                      //Anm. 2
4
  __attribute__((naked)) \
5
  __attribute__((section(".init3")));
6
void get_mcusr(void)
7
{
8
  mcusr_mirror = MCUSR;
9
  MCUSR = 0;
10
  wdt_disable();
11
}
12
13
//Blinken mit der LED
14
void blinken(uint8_t anz)
15
{
16
  for( ;anz > 0; anz--)
17
  {
18
    wdt_reset();
19
    LED(1);
20
    _delay_ms(70);
21
    _delay_ms(70);
22
    LED(0);
23
    _delay_ms(70);
24
    _delay_ms(70);
25
  }
26
}
27
28
int main( void )
29
{
30
  port_init();
31
  get_mcusr();
32
  wdt_enable(WDTO_2S);                    // Watchdog akivieren
33
  if (mcusr_mirror & (1<<BORF))
34
  {
35
    blinken(2);
36
  }
37
  else if (mcusr_mirror & (1<<PORF))
38
  {
39
    blinken(3);
40
  }
41
  else if (mcusr_mirror & (1<<WDRF))
42
  {
43
    blinken(4);
44
  }
45
  else
46
  {
47
    blinken(1);
48
  }
49
50
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);            // Sleep Modus festlegen
51
  
52
  sleep_mode();                        // Sleep Modus aktivieren
53
}

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Norbert S. (norton)


Lesenswert?

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.

von Jojo S. (Gast)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.