Forum: Mikrocontroller und Digitale Elektronik STM32F4 WWDG


von Dunky (Gast)


Lesenswert?

Hi,

Den iwdg habe ich am laufen und er funktioniert auch.
Am Window watchdog verzweifel ich aber ein wenig und bin mir noch nicht 
ganz im klaren wie da die Anwendung funktionieren soll oder ich da etwas 
einfach nicht verstehe.

Meine Mainloop hat je nach aktuellem Zustand eine recht unterschiedliche 
Laufzeit. Sagen wir normal sind 100us für einen Durchlauf, so kann ein 
Durchlauf nach Pagewechsel im virtuellen eeprom auch mal 200ms dauern.

Kann ich solche unterschiedlichen Laufzeiten damit überhaupt erschlagen? 
Wenn ich den prescaler auf 8 setze bekomme ich so ein großes Window doch 
schon nicht abgebildet da das Fenster zu kurz ist.

Wenn ich den prescaler klein mache, dann kann ich den Fall der 100us 
Mainloop abdecken, aber bei langer Laufzeit würde der watchdog 
zuschlagen.

Ich bin der Meinung gesehen zu haben, daß es Beispiele gab, bei denen 
der watchdog in dem pre-reset IRQ gefüttert wurde, aber das hebelt doch 
den Sinn des watchdogs aus, da der dann ja nie anschlagen dürfte?

Versteht jemand mein Problem und hat eine gute Erklärung oder ein 
Beispiel wie die Anwendung da gedacht ist? Ich habe nichts gefunden was 
meine Fragen beantwortet :(

von dunky (Gast)


Lesenswert?

Hier meine Einstellungen
1
void watchdog_window_setup(void){
2
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
3
  WWDG_SetPrescaler(WWDG_Prescaler_8);
4
  WWDG_SetWindowValue(127);
5
}
6
7
void watchdog_window_start(void){
8
  WWDG_Enable(127);
9
  // enable pre interrupt EWI interrupt 
10
  WWDG_EnableIT();
11
}
12
13
void watchdog_window_trigger(void){
14
  WWDG_SetCounter(127);
15
}
16
17
void WWDG_IRQHandler(void){
18
  WWDG_ClearFlag();
19
  watchdog_window_trigger(); // nur zu Testzwecken
20
}

hmm ich habe den Watchdog am laufen, zumindest insofern das ich in 
meiner Mainloop den Counter neu laden kann.

Was jedoch nicht funktioniert, ist der WWDG_IRQHandler()
Ich komme da nie rein, auch wenn ich das triggern des Watchdogs in 
meiner Mainloop herausnehme.
Im Debugger sehe ich noch den Neustart und dann ist auch WWDGRSTF 
gesetzt, aber meinen IRQ Handler erreiche ich nicht.

Hat jemand eine Idee was ich falsch machen?

von pegel (Gast)


Lesenswert?

In der Repository des F4 gibt es einige Beispiele für HAL und LL.
Ist da nichts dabei?

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

dunky schrieb:
>   // enable pre interrupt EWI interrupt
>   WWDG_EnableIT();

Was macht die Funktion?

>
> Was jedoch nicht funktioniert, ist der WWDG_IRQHandler()
> Ich komme da nie rein, auch wenn ich das triggern des Watchdogs in
> meiner Mainloop herausnehme.
> Im Debugger sehe ich noch den Neustart und dann ist auch WWDGRSTF
> gesetzt, aber meinen IRQ Handler erreiche ich nicht.
>
> Hat jemand eine Idee was ich falsch machen?

Ganz blöd gefragt: Sind Interrupts bei Dir überhaupt enabled? Wenn Du 
eine "barebone App" hast, die aus dem Resetvektor erst die 
Prozessorinitialisierung macht und dann sofort in die main loop 
übergeht, hast Du mglw. am System Entry ein

cpsid i

und müsstest dann vor dem entern der main loop ein

cpsie i

machen. Bekommst Du überhaupt irgendwelche interrupts?

von planlos (Gast)


Lesenswert?

pegel schrieb:
> In der Repository des F4 gibt es einige Beispiele für HAL und LL.
> Ist da nichts dabei?

wenn ich das richtig gesehen habe wird bei dem wwdg kein irq benutzt. 
aber werde nochmal schauen. evtl kann ich da etwas ableiten(muss 
aufgrund der veralteten Projektstruktur momentan noch die stdlib 
verwenden)

von planlos (Gast)


Lesenswert?

Ruediger A. schrieb:
> dunky schrieb:
>>   // enable pre interrupt EWI interrupt
>>   WWDG_EnableIT();
>

Ist eine Funktion aus der StdLib. Die macht aber eigentlich nur
1
WWDG->CFR |= WWDG_CFR_EWI;

> Ganz blöd gefragt: Sind Interrupts bei Dir überhaupt enabled? Wenn Du
> eine "barebone App" hast, die aus dem Resetvektor erst die
> Prozessorinitialisierung macht und dann sofort in die main loop
> übergeht, hast Du mglw. am System Entry ein
>
> cpsid i
>
> und müsstest dann vor dem entern der main loop ein
>
> cpsie i
>
> machen. Bekommst Du überhaupt irgendwelche interrupts?

Hmm ich denke das war der Hinweis in die richtige Richtung.
Für andere Timer/UARTS etc bekomme ich Interrupts.
Ich muss es morgen testen, aber ich habe vermutlich den NVIC nicht 
korrekt konfiguriert. Ich habe mich auf diese Funktion verlassen, aber 
am NVIC nix gemacht.

Jetzt habe ich auf die schnelle mal gesucht und mit den richtigen 
Stichworten purzeln auch x Codeschnippsel aus Google die darauf 
hindeuten, dass das der Fehler sein müsste.

Ich sag schonmal danke, da mir das sicherlich weiterhelfen dürfte

von dunky (Gast)


Lesenswert?

jaa, das scheint es gewesen zu sein.

Momentan stoppt mein Debugger nicht in dem IRQ Handler, aber wenn ich 
dort den Watchdog triggere, läuft der Controller weiter, nehme ich das 
heraus, resetet er so wie ich das erwarten würde.

Danke schonmal

von dunky (Gast)


Lesenswert?

1
void watchdog_window_setup(void){
2
  NVIC_InitTypeDef NVIC_InitStructure;
3
  
4
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
5
  WWDG_SetPrescaler(WWDG_Prescaler_8);
6
  WWDG_SetWindowValue(127);
7
  
8
  NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn;
9
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;
10
  NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;
11
  NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
12
  NVIC_Init(&NVIC_InitStructure);
13
}
14
15
void watchdog_window_start(void){
16
  WWDG_Enable(127);
17
  WWDG_ClearFlag();
18
  WWDG_EnableIT();
19
}
20
21
void watchdog_window_trigger(void){
22
  WWDG_SetCounter(127);
23
}
24
25
void watchdog_window_force_cpu_restart(void){
26
  watchdog_window_setup();
27
  watchdog_window_start();
28
  while(1){};
29
}
30
31
void WWDG_IRQHandler(void){
32
  WWDG_ClearFlag();
33
  watchdog_window_trigger();
34
}

Falls es jemandem hilft...damit geht es bei mir zumindest.

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

Hallo Dunky,

danke für die Rückmeldung und den Code. Es passiert leider nicht oft, 
dass die selbst gefundenen Lösungen mit Code veröffentlicht werden...

Nur als kleine Randbemerkung: Die Preemption Priorität deines WWDG ist 
2. WIr wissen natürlich nicht, welche Prios deine andere Interrupts 
haben (vielleicht ist 2 ja bei Dir die höchste), aber auf Grund der 
beabsichtigten Funktionsweise würde ich davon ausgehen, dass dein WWDG 
die höchste Interruptpriorität haben sollte - oder kannst Du in deiner 
Anwendung riskieren, dass der WWDG IRQ von anderen höher priorisierten 
IRQs unterbrochen wird?

von Bauform B. (bauformb)


Lesenswert?

dunky schrieb:
>
1
 void WWDG_IRQHandler(void){
2
   WWDG_ClearFlag();
3
   watchdog_window_trigger();
4
}
>
> Falls es jemandem hilft...damit geht es bei mir zumindest.

Was ist "es"? Weil, auf diese Art erzeugt der watchdog nur dann einen 
Reset, wenn du für lange Zeit die Interrupts ausschaltest. Und das macht 
man auf einem Cortex-M normalerweise nicht. Also war irgendwie alles 
vergebens? Was verstehe ich hier nicht?

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

Bauform B. schrieb:
> dunky schrieb:
>>
1
 void WWDG_IRQHandler(void){
2
>    WWDG_ClearFlag();
3
>    watchdog_window_trigger();
4
> }
5
>
>>
>> Falls es jemandem hilft...damit geht es bei mir zumindest.
>
> Was ist "es"? Weil, auf diese Art erzeugt der watchdog nur dann einen
> Reset, wenn du für lange Zeit die Interrupts ausschaltest. Und das macht
> man auf einem Cortex-M normalerweise nicht. Also war irgendwie alles
> vergebens? Was verstehe ich hier nicht?

So wie es der Dunky skizziert hat, macht der Code natürlich erstmal 
keinen Sinn, denn damit wird über die Hintertür der Watchdog ausser 
Kraft gesetzt. Das ist für mich jetzt erstmal nur Testcode, um 
nachzuweisen, dass der Interrupt kommt (vielleicht kann sein Debugger ja 
keinen BP auf den IRQ setzen, oder es hilft ihm nix, wenn direkt danach 
der Reset kommt).

Ich vermute aber mal, dass im "produktiven" Einsatz der IRQ etwas 
sinnvolles macht (so wie die Kondition zu analysieren und eine fool 
proof Diagnostik zu generieren und dann den Controllern in den Reset 
laufen zu lassen oder so).

von Dunky (Gast)


Lesenswert?

Ja, das war nur Testcode um zu sehen ob ich im IRQ Lande.

Der Debugger hält jetzt auch im IRQ

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.