STM32F4: EXTI-Interrupt-Flag löschen

(Firma: Reusch Elektronik) #4008490
Lesenswert?

Hallo STM32F4-Spezialisten!
Ich beschreibe hier ein kleines Problem mit dem STM32F407, das sich zwar 
umgehen lässt, aber trotzdem hätte ich gerne gewusst, warum es so ist.

Gegeben ist die folgende Interrupt-Routine. Durch ein externes Signal 
wird die EXTI-Routine regelmäßig aufgerufen. Mit Timer2 wird der 
zeitliche Abstand zwischen zwei Interrupts ermittelt (Aufwärtszähler). 
(die ausgelesenen Timer-Werte werden in der Hauptschleife über die 
serielle Schnittstelle ausgegeben)
1
void EXTI0_IRQHandler(void)
2
{
3
  //TP2_H;      // Makro für Testpin auf high (für Messung mit Oszi)
4
  Tim2Cnt = TIM2->CNT;  // zeitl. Abstand messen
5
  TIM2->CNT = 0;
6
//  EXTI->PR = EXTI_Line0;  // EXTI_ClearITPendingBit (wenn es hier steht, ist alles ok)
7
  Externe_Routine();  // Berechnungen, dauern ca. 2µs (ist unkritisch)
8
  EXTI->PR = EXTI_Line0;  // EXTI_ClearITPendingBit (wenn es hier steht, treten Fehler auf)
9
  //TP2_L;      // Makro für Testpin auf low (für Messung mit Oszi)
10
}
Die Interrupt-Routine arbeitet, so wie sie oben aufgeführt ist, meistens 
korrekt, d.h. es wird ein Timer-Wert von ca. 37000 ermittelt. Relativ 
häufig tritt jedoch ein Timer-Wert von etwa 100 auf, d.h. die 
Interrupt-Routine wird zweimal hintereinander aufgerufen!

Um das messtechnisch nach zu weisen, ändere ich den Zustand eines 
Test-Pins. Sobald ich jedoch die "TP_"-Zeilen entkommentiere, tritt der 
Fehler nicht mehr auf!

Der Fehler verschwindet auch dann, wenn ich das Interrupt-Flag nicht am 
Ende sondern ganz am Anfang oder aber weiter vorne (wie im Listing 
angedeutet) lösche.

Meine Fragen:
Warum tritt der Interrupt manchmal zweimal auf, wenn das Interrupt-Flag 
am Ende gelöscht wird?
Warum sollte es am Anfang gelöscht werden?

Wenn ich es richtig verstehe, müsste ein gesetztes Interrupt-Flag doch 
verhindern, dass der Interrupt erneut aufgerufen wird. Und um zu 
verhindern, dass ein Aufruf erfolgt während die Interrupt-Behandlung 
noch läuft, ist ein Löschen des Flags am Ende doch eher sinnvoll. Aber 
das ist ja problematisch, wie das Beispiel zeigt.
(Firma: Reusch Elektronik) #4008680
Lesenswert?

Vielen Dank für die Antworten! Das leuchtet ein, insbesondere mit dem 
Hinweis auf 168MHz Core-Takt und 42/84MHz Peripherie-Takt. Ich meine, 
auch schon mal irgendwo (vermutlich hier im Forum) gelesen zu haben, das 
Flag müsse am Anfang gelöscht werden. Mit diesen einleuchtenden 
Erklärungen müsste es allerdings heißen: "nicht ganz am Ende löschen".
Gast #4008725
Lesenswert?

Hallo,

das Problem ist hier ja schon aufgezeigt. Wollte nur ergänzen, dass man 
mit den Assembler Befehlen DSB und DMB (Data Synchronisation Barrier) 
die CPU anhalten kann bis der Zugriff abgeschlossen ist.

Es sollten C Makros in der CMSIS Header-Datei für den Cortex M4 
definiert sein. Hab den Namen der H-Datei vergessen. Iwie core_cm4.h 
oder so.

Da sind _DMB(); und _DSB(); definiert. Einfach eins von beiden (welches 
ist recht egal) ans Ende der Routine und der Core wartet, bis alle 
Speicherzugriffe durch sind.

also:
1
Handler()
2
{
3
//Code
4
//Flag löschen
5
_DSB();
6
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren