Forum: Mikrocontroller und Digitale Elektronik Fieser Softwarebug! [Watchdog] Vieleicht hat jemand einen Tipp!


von C. H. (hedie)


Lesenswert?

Guten Abend zusammen

Ich habe folgendes Problem:

Bei meinem Atmega324 habe ich den Watchdog aktiviert.
Dieser Soll in meiner Hauptschleife regelmässig resetiert werden.

Seit einigen wochen klappten dies auch wunderbar. Doch seit ich einige 
Änderungen vorgenommen habe, tut es nicht mehr so wie ich möchte.

Mein gesamter Code ist ziemlich umfangreich. Deshalb verzichte ich hier 
auf ein Posten des gesamten Codes. Durchlesen würde Ihn sowieso niemand 
:)

Hie mal meine derzeitige Main:
1
int main(void)
2
{
3
4
  init_ports();
5
6
  LED_1;
7
  _delay_ms(200);
8
  LED_0;
9
10
11
  GPS_CS_0;    //GPS Deaktivieren
12
  GPS_ON_0;    //GPS Deaktivieren
13
  //_delay_ms(100);
14
15
  toggle_on_off();  //GPS Einschalten
16
  init_soft_uart();
17
18
  wdt_enable(WDTO_2S); //2Sekunden Watchdog!
19
  sei();     //Interrupts aktivieren
20
21
  GSM_RST_1;  //GSM Reset aufheben
22
23
24
  while(1)
25
  {
26
27
28
29
    ///// Wadtchdog Reset
30
31
    if(ucReset != 1) wdt_reset();
32
    else
33
    {
34
      LED_1;
35
      _delay_ms(10000);
36
    }
37
    ///////////
38
39
    //Wenn wir einen \n Terminierten String vom PC erhalten haben, parsen wir. Maximal 32Bytes!
40
    if(ucRX1NewData) parse_rx1buff();
41
  }
42
}

Heruntergeladen wird das ganze durch den Bootloader von Peter Dannegger.

Nach dem ersten Download, klappt es und das Programm läuft normal.
Damit meine ich, zu beginn blitzt die LED kurz auf und danach ist sie 
Dunkel und bleibt es auch.

Wenn ich nun jedoch einen Reset (Hardware oder mit Software) durchführe, 
dann wird der Watchdog nicht mehr resetiert.

Ich verstehe nicht, was nach einem Reset anderst sein soll.

Die Led blitzt nach einem Reset im 2 Sekunden Takt (Watchdog-Zeit).

Hatt jemand schonmal ähnliche erfahrungen im Zusammenhang mit dem 
Watchdog oder dem Bootloader gemacht?

Ich weiss nicht wie ich herausfinden kann, ob das Programm hängt und 
wenn ja wo.

While Schleifen habe ich stets unterlassen.

In den Unterfunktionen initports und toggle_on_of sowie init soft uart 
gibt es keine schleifen!

Danke schonmal

von g457 (Gast)


Lesenswert?

> wdt_enable(WDTO_2S); //2Sekunden Watchdog!
[..]
> _delay_ms(10000);

∗hüstel∗

von C. H. (hedie)


Lesenswert?

g457 schrieb:
>> wdt_enable(WDTO_2S); //2Sekunden Watchdog!
> [..]
>> _delay_ms(10000);
>
> ∗hüstel∗

Haha... Ja das ist noch so eine sache.

Die _delay_ms(10000) entsprechen einer Sekunde.
Dies obwohl die 10 000 000 Hz dem Compiler korrekt übergeben werden.

Irgendwo steckt da der Hund begraben...


Aber so oder so. Diese 10000ms bzw. 1s treten sowieso nur in dem Falle 
ein, in dem der Reset per Software (über UART vom PC) ausgelöst wurde.

Dies ist jedoch nicht der Fall.

Soll heissen, der uC resettet sich nicht, weil die Variable ucReset > 0 
ist.
Sondern weil ziemlich sicher wdt_reset(); nicht mehr aufgerufen wird.

Ich weiss ich weiss, eure Glaskugeln haben nicht genug performance...

Aber ist es nicht etwas merkwürdig, wenn das Programm direkt nach dem 
Schreiben ins Flash durch den Bootloader läuft, hingegen nach einem 
Reset nicht mehr?

Ich habe gehofft, jemand hätte eine Idee worauf dies hindeuten könnte.

Wenn ihr mir hingegen sagt, es liegt zu 100% an meinem Code (also z.B. 
eine Schleife oder sowas) und nicht daran, weil ich irgendwie vergessen 
habe ein Bit in irgendeinem Register zu setzen oder sowas (halt eben die 
Fiesen Tricks und kniffe) dann suche ich natürlich selbst nach dem 
Fehler.

von Thomas E. (thomase)


Lesenswert?

Claudio Hediger schrieb:
> Aber ist es nicht etwas merkwürdig, wenn das Programm direkt nach dem
> Schreiben ins Flash durch den Bootloader läuft, hingegen nach einem
> Reset nicht mehr?
Nur auf den ersten Blick.
Der Watchdog bleibt nach dem Aktivieren solange aktiv bis er entweder 
per Software deaktiviert oder ihm der Strom abgedreht wird.
Bei einem Reset (GND an Resetpin) wird nur der Watchdogprescaler auf 
default gesetzt, also auf 16ms. Und dann macht er da:   _delay_ms(200);
einen Reset.
Die Einstellung des Watchdogprescalers muss die erste Anweisung sein.

mfg.

von tommy (Gast)


Lesenswert?

Claudio Hediger schrieb:
> Die _delay_ms(10000) entsprechen einer Sekunde.

Hab jetzt extra meine Lesebrille geholt.
Ja, vier nullen, also 10.000
Macht dann 10 Sekunden.....

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

tommy schrieb:
> Claudio Hediger schrieb:
> Die _delay_ms(10000) entsprechen einer Sekunde.
>
> Hab jetzt extra meine Lesebrille geholt.
> Ja, vier nullen, also 10.000
> Macht dann 10 Sekunden.....

Glaub' ich eher nicht!
Doku zu den Delay-Funktionen gelesen?

von Peter II (Gast)


Lesenswert?

Patrick Dohmen schrieb:
> Glaub' ich eher nicht!
> Doku zu den Delay-Funktionen gelesen?

auf was willst du hinaus? Oder hast du noch die alte Doku im Kopf mit 
der Beschränkung?

von kukuk (Gast)


Lesenswert?

ext.WD wirkt Wunder.

von Peter II (Gast)


Lesenswert?

kukuk schrieb:
> ext.WD wirkt Wunder.

der interne geht auch wunderbar. Solange seine delays nicht stimmen 
braucht man überhaut nicht weiter zu suchen.

@Claudio Hediger

nimm mal ein leeres Programm und lass eine LED blinken

while(1) {
   _delay_ms(1000);
   //led blinken
}

uns stoppe mal die zeit. Wenn das nicht stimm dann zeig die Fuse und die 
Compiler Einstellungen.

von Rolf M. (rmagnus)


Lesenswert?

Claudio Hediger schrieb:
> Die _delay_ms(10000) entsprechen einer Sekunde.
> Dies obwohl die 10 000 000 Hz dem Compiler korrekt übergeben werden.

Offensichtlich werden sie das nicht, denn sonst würde es richtig 
funktionieren.

von Claudio H. (Gast)


Lesenswert?

Vielen Dank an euch alle!


Es war in der Tat folgendes Problem:

Thomas Eckmann schrieb:
> Claudio Hediger schrieb:
>> Aber ist es nicht etwas merkwürdig, wenn das Programm direkt nach dem
>> Schreiben ins Flash durch den Bootloader läuft, hingegen nach einem
>> Reset nicht mehr?
> Nur auf den ersten Blick.
> Der Watchdog bleibt nach dem Aktivieren solange aktiv bis er entweder
> per Software deaktiviert oder ihm der Strom abgedreht wird.
> Bei einem Reset (GND an Resetpin) wird nur der Watchdogprescaler auf
> default gesetzt, also auf 16ms. Und dann macht er da:   _delay_ms(200);
> einen Reset.
> Die Einstellung des Watchdogprescalers muss die erste Anweisung sein.
>
> mfg.

Danke vielmals!


Es funktioniert nun wieder einwandfrei :)

von Oliver (Gast)


Lesenswert?

Claudio H. schrieb:
> Es funktioniert nun wieder einwandfrei :)

Nun ja,"wieder" ist ja wohl etwas übertrieben, und die Begriffe 
"funktioniert" und "einwandfrei" treffen auf Software selten zu, vor 
allem im direkten Zusammenhang.

Der Rest des Satzes wird wohl zutreffen ;)

Oliver

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.