Forum: Mikrocontroller und Digitale Elektronik Crash @ TIM2-Überlauf statt TIM2_IRQHandler (STM32G031J6)


von Master-Jimmy (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich möchte PA11 eines STM32G031J6M6 mit 50 kHz blinken lassen, bzw. ein 
entsprechendes Rechtecksignal am Pin 5 generieren. Dafür habe ich TIM2 
so konfiguriert, dass er alle 10 us überläuft, was eine ISR 
("TIM2_IRQHandler") aufruft, welche den Zustand von PA11 umkehrt.

Der angehängte Code funktioniert soweit. Das heisst, der Timer tut, was 
er soll und das Toggeln funktioniert ebenfalls. Nur crasht das Program 
leider bei einem Überlauf von TIM2, statt meine ISR aufzurufen.

Vielen Dank schon einmal.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

In der IRQ am Ende fehlt noch ein NVIC_ClearPendingIRQ(nbr).
Sonst gibts Dauerfeuer vom NVIC.

von Master-Jimmy (Gast)


Lesenswert?

Der Status wird automatisch von "pending" auf "active" gesetzt, sobald 
die ISR aufgerufen wird. Es ist also nicht nötig, den Status per 
Software zu "clearen".
Trotzdem habe ich's mal eingefügt und ausprobiert: Macht keinen 
Unterschied.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Stand hier mal irgendwo im Forum - erst den Timer IRQ löschen, dann an 
den Ports rumfummeln.

von Master-Jimmy (Gast)


Lesenswert?

Könnte man so machen, muss man aber - jedenfalls in diesem Falle - nicht 
so machen.
Trotzdem habe ich auch das ausprobiert: Macht keinen Unterschied.

von M. Н. (Gast)


Lesenswert?

Keine Ahnung, ob folgendes Schuld ist. (Ich habe ehrlich gesagt deine 
Frag enicht verstanden. Du schreibst, dass die LED toggelt, aber die ISR 
nicht aufgerufen wird... Dabei wird doch in der ISR getoggelt)... Egal:

Mach mal aus
1
void TIM2_IRQHandler(void) {
2
3
  //Toggle PA11 (pin 5).
4
5
  GPIOA->ODR ^= (0x1u << 11);
6
7
  //Clear TIM2 update interrupt flag.
8
9
  TIM2->SR &= ~TIM_SR_UIF;
10
11
}

folgenden Code:
1
void TIM2_IRQHandler(void) {
2
3
  TIM2->SR &= ~TIM_SR_UIF;
4
  __DSB(); // sollte in der cmsis header Datei definiert sein...
5
6
  //Toggle PA11 (pin 5).
7
8
  GPIOA->ODR ^= (0x1u << 11);
9
}

Manchmal gibt es das Phänomen, dass man das Flag löscht und die CPU aus 
der ISR springt, aber der "Löschvorgang" des Interrupt Flags im 
Peripheral noch nicht durch den Bus durch ist. Dann wird gleich nochmal 
ausgelöst.

Das DSB (Assemblerbefehl für eine "Data synchronization barrier") Sollte 
das verhindern.

Passt aber eigentlich nicht ganz zu deinem Fehlerbild (, das ich 
zugegebenermaßen nicht genau verstanden habe).

von Master-Jimmy (Gast)


Lesenswert?

@bambel2 & mschoeldgen: Dieses Fehlerbild tritt bei Cortex-M0+ wohl 
prinzipiell nicht auf: 
https://developer.arm.com/documentation/ka003795/latest

Jedenfalls kämpfe ich nicht mit diesem Problem. Du hast in der Tat mein 
Fehlerbild nicht ganz verstanden:
Die LED toggelt mit dem im Ursprungs-Post angefügten Code nie und die 
ISR wird nie aufgerufen - wohl funktioniert der Timer aber einwandfrei.
Ich habe das Toggeln, bzw. die Funktion der ISR aber noch separat 
getestet: Ich habe im selben Code Interrupts global nicht "geenabled" 
(__disable_irq()) und dann in der while-Schlaufe in main() das 
Überlaufflag des TIM2 gepolt. Wenn ich da bei jedem Flag die ISR 
aufrufe, bekomme ich die 50 kHz an Pin 5.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Master-Jimmy schrieb:
> Du hast in der Tat mein
> Fehlerbild nicht ganz verstanden:
> Die LED toggelt mit dem im Ursprungs-Post angefügten Code nie

Sagen wir mal lieber, du hast es nicht verstanden, die 
Fehlerbeschreibung richtig zu machen. Denn du schreibst ja im ersten 
Posting:

Master-Jimmy schrieb:
> Das heisst, der Timer tut, was
> er soll und das Toggeln funktioniert ebenfalls.

Also was denn nun? Schau auch bitte mal, ob bei der G-Serie Clocks für 
NVIC aktiviert werden müssen und ob der NVIC ohne Konfiguration 
glücklich ist.

von Master-Jimmy (Gast)


Lesenswert?

Matthias S. schrieb:
> Also was denn nun? Schau auch bitte mal, ob bei der G-Serie Clocks für
> NVIC aktiviert werden müssen und ob der NVIC ohne Konfiguration
> glücklich ist.
Clocks müssen da keine aktiviert werden und konfiguriert werden muss per 
se eigentlich auch nichts - es gibt Default-Prioritäten:

-> Reference Manual: 
https://www.st.com/resource/en/reference_manual/rm0444-stm32g0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf#page=314&zoom=100,89,116

-> Programming Manual: 
https://www.st.com/resource/en/programming_manual/pm0223-cortexm0-programming-manual-for-stm32l0-stm32g0-stm32wl-and-stm32wb-series-stmicroelectronics.pdf#page=82&zoom=100,89,117

Allerdings lässt sich mein Problem tatsächlich erst einmal lösen, wenn 
ich "meinem" Interrupt die Priorität 0 zuweise. "Mein" Interrupt, 
welcher per default die Prio. 22 haben müsste, wird also offenbar von 
irgend einem anderen Interrupt verdeckt. Jetzt muss ich einfach noch 
herausfinden, was da dazwischen feuert.

VIELEND DANK MSCHOELDGEN. DAS BEANTWORTET FÜR MICH DIE FRAGE 
HINREICHEND.

von Master-Jimmy (Gast)


Angehängte Dateien:

Lesenswert?

Die Zeile die den Unterschied macht, ist Zeile 38.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Master-Jimmy schrieb:
> die Priorität 0 zuweise.

Wenn du das schrittweise höher drehst, kannst du den Störer 
herausfinden. Aber eigentlich gibt es nur SysTick, wenn man nichts 
weiter aktiviert.

von Johannes S. (Gast)


Lesenswert?

Jetzt ist es ein .cpp, ist der TIM2_Handler als extern "C" deklariert? 
Stimmt der Name mit der Definition in der Vektortabelle überein?

von Master-Jimmy (Gast)


Lesenswert?

Johannes S. schrieb:
> Jetzt ist es ein .cpp, ist der TIM2_Handler als extern "C"
> deklariert?
> Stimmt der Name mit der Definition in der Vektortabelle überein?

Ich habe da offensichtlich beim Posten verschiedene Versionen 
durcheinander gebracht. Auf meiner Seite hatte ich aber diese 
"Problematik" stets im Griff.
Danke trotzdem für den Hinweis.

Matthias S. schrieb:
> Master-Jimmy schrieb:
>> die Priorität 0 zuweise.
>
> Wenn du das schrittweise höher drehst, kannst du den Störer
> herausfinden. Aber eigentlich gibt es nur SysTick, wenn man nichts
> weiter aktiviert.

Du hast eigentlich recht. Allerdings kann ich nun den Fehler gar nicht 
mehr reproduzieren. Wenn ich nun also die Zeile, wo die Priorität für 
TIM2_IRQn gesetzt wird, wieder auskommentiere funktioniert der Code 
trotzdem.

Wie auch immer... Ich werde in Zukunft wohl einfach stets explizit 
Prioritäten setzen, selbst wenn dies nicht nötig sein sollte.

von Johannes S. (Gast)


Lesenswert?

in meinem Timer Code habe ich noch ein Interrupt Flag löschen vor dem 
Enable IRQ drin, könnte auch nötig sein.

von Master-Jimmy (Gast)


Lesenswert?

Johannes S. schrieb:
> in meinem Timer Code habe ich noch ein Interrupt Flag löschen vor
> dem
> Enable IRQ drin, könnte auch nötig sein.

Das sollte nicht nötig sein - von wo sollte das Pending Flag den 
kommen?? Hatte ich aber die letzten Tag auch bereits ausprobiert. Hatte 
nichts gebracht.

von Master-Jimmy (Gast)


Lesenswert?

Es könnte im Prinzip an der HW liegen/gelegen haben... Die 
entsprechenden Interrupts hätten ja ebenfalls höhere Prioritäten.
Ich habe ausserdem das ursprüngliche Board (STM32G0316-DISCO) 
geschrottet. Mit dem Ersatzteil hatte ich das Problem noch gar nicht 
versucht zu reproduzieren. Ich war bisher auch nie auf die Idee 
gekommen, dass die HW die Problemquelle sein könnte. Ist ja auch ein 
gekauftes und getestetes (nehme ich an) Teil...

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.