Forum: Mikrocontroller und Digitale Elektronik Init1 - Section Bootloader: Abstürze


von Manuel H. (manu77)


Lesenswert?

Nach stundenlanger Suche bin ich einem sporadischem Problem auf die 
schliche gekommen, welches ich mir nicht richtig erklären kann.

Im Bootloader eines mega328p benutze ich einen Watchdog-Reset in der 
Init1 Section:
1
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init1")));
2
3
void wdt_init(void)
4
{
5
  MCUSR = 0;
6
  wdt_disable();
7
  
8
  return;
9
}

Dieser Code führt allerdings dazu, dass wenn ich die Spannung lange 
abgetrennt lasse (Vollentladung) das Hauptprogramm (Start nach 
Bootloader) nach ein paar Sekunden abstürzt.
Auch der Bootloader kann bei längerem Betrieb abstürzen.

Das Problem tritt nicht immer auf. Bei schnellen, mehrmaligen Resets oft 
nicht. Nehme ich den Code raus, ist das Problem weg.

Wieso kommt es zu derartigem Fehler?

von Johannes O. (jojo_2)


Lesenswert?

Im init1 hast du noch keinen Stack und auch das r0 Register ist noch auf 
einem zufälligen Wert, meist ungleich 0.

http://www.nongnu.org/avr-libc/user-manual/mem_sections.html


Beim wdt_disable() Aufruf (der eigentlich nur ein define ist), benötigst 
du aber afaik schon das r0 Register.

Bei kurzem Spannungsausfall ist das Register höchstwahrscheinlich noch 
auf 0. Wenn du die Spannung wegnimmst kippen bald schon viele Bits im 
Stack und in den Registern selbst um => Du bekommst Probleme.

Warum schaltest du überhaupt deinen Watchdog so früh aus? Solche .init1 
Spielereien sollte man nur tun, wenn es UNBEDINGT notwendig ist und man 
weiß was die Einschränkungen sind -- was in den meisten Anwendungen 
nicht der Fall ist.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

.init1 ist zu früh; an der Stelle geht nur Assembler. zero_reg wird z.B. 
erst in .init2 besetzt.  Guckst 
http://svn.savannah.nongnu.org/viewvc/trunk/avr-libc/crt1/gcrt1.S?revision=2459&root=avr-libc&view=markup

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Johannes O. schrieb:
> r0 Register ist noch auf einem zufälligen Wert

zero_reg ist R1 bzw. R17

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

...und in eine naked-Funktion gehört NIEMALS ein return!

von Manuel H. (manu77)


Lesenswert?

Johannes O. schrieb:
> Warum schaltest du überhaupt deinen Watchdog so früh aus?

Ich habe den Code aus einem meiner damaligen Projekte entnommen.
Der Snippet stammt aus irgend einem Forum (so recht ich mich erinnere) 
^^.
Damals ist mir der Fehler nicht aufgefallen.

Ich schalte den Watchdog jetzt in der Main direkt ab.
Danke für eure Erklärungen!

von Johannes O. (jojo_2)


Lesenswert?

Johann L. schrieb:
> Johannes O. schrieb:
>> r0 Register ist noch auf einem zufälligen Wert
>
> zero_reg ist R1 bzw. R17

danke für die Info, das ist natürlich korrekt. r1 ist das zero_reg. War 
grad noch gedanklich bei ner anderen Architektur...

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.