Forum: Mikrocontroller und Digitale Elektronik PIC32: ISR wird zweimal ausgeführt!


von Martin (Gast)


Lesenswert?

Hallo zusammen,

ich habe in meinem Programm was komisches festgestellt:
mehrere Interrupts können gleichzeitig auftreten, daher habe sie auch 
unterschiedliche Prioritäten.
Mit dem Oszilloskop und durch toggeln von verschiedenen Outputs, habe 
ich festgestellt das manche ISRs zweimal hintereinander ausgeführt 
werden, aber immer nur wenn zwei Interrupts gleichzeitig oder kurz 
nacheinander auftreten und immer nur die ISR der Interrupt mit der höhen 
Priorität wird zweimal ausgeführt:
Normalerweise soll der Ablauf so sein:
- Interrupt A (Prio=3) tritt auf
- ISR wird ausgeführt
- Out1 wird gesetzt
    - Interrupt B (Prio 7) tritt auf
    - ISR wird ausgeführt
    - Out2 wird gesetzt
    - ISR B Tut was
    - Out2 wird gelöscht
- ISR A tut was
- Out 1 wird gelöscht

Aber nach dem Oszi ist der Ablauf so:
- Interrupt A (Prio=3) tritt auf
- ISR wird ausgeführt
- Out1 wird gesetzt
    - Interrupt B (Prio 7) tritt auf
    - ISR wird ausgeführt
    - Out2 wird gesetzt
    - ISR B Tut was
    - Out2 wird gelöscht
    - Pause von etwa 3 us
    - Out2 wird gesetzt
    - ISR B Tut was
    - Out2 wird gelöscht
- ISR A tut was
- Out 1 wird gelöscht

Das gilt auch nicht nur für einen Interrupt (z.B. Timerx) sondern auch 
für ext Interrupt.

Hat jemand Ahnung an was das liegen kann?

von (prx) A. K. (prx)


Lesenswert?

In anderer Umgebung (ARM) kann das auftreten, wenn in der ISR das 
Interrupt-Flag erst ganz am Ende der ISR zurück gesetzt wird. Dann kommt 
es vor, dass der Prozessor schneller ist als die gesamte Laufzeitkette 
der Verarbeitung dieser Flag-Aktion und das Interrupt-Signal 
entsprechend verzögert zum Zeitpunkt der Entscheidung des Cores noch 
aktiv ist. Der dreht dann die Runde nochmal.

M.a.W: Zieh mal die Operation, mit der in der ISR das zugehörige 
Interrupt-Flag zurück gesetzt wird, nach vorne.

: Bearbeitet durch User
von Martin (Gast)


Lesenswert?

Ok, vielen Dank, werde ich testen.
Der Flag wird tatsächlich als letzter Schritt in der ISR gelöscht.

von Martin (Gast)


Lesenswert?

Hilft leider nicht. Der Fehler ist immer noch da.

von Martin (Gast)


Lesenswert?

Hat keiner hier für einen Vorschlag/Lösung?

von Peter D. (peda)


Lesenswert?

Martin schrieb:
> Normalerweise soll der Ablauf so sein:
> - Interrupt A (Prio=3) tritt auf
> ...

Ich liebe es, wenn Quellcode in Prosa umgewandelt wird.
Insbesondere die "Tut was" Instruktion ist auf jeder CPU atomar, also 
absolut fehlerfrei.
Eine Zeitangabe 3µs ist vollkommen sinnlos ohne die Angabe des 
CPU-Taktes.

von Martin (Gast)


Lesenswert?

Na ja, das ist ein riesiges Projekt, und verlange auch nicht das man die 
Fehler korrigiert oder sucht.
Aber vielleicht hat jemand so etwas gehabt oder hat Ahnung an was das 
sein kann, Tips/Tricks wie A. K. mit dem Löschen des FLags an der ersten 
Stelle.

von Peter D. (peda)


Lesenswert?

Martin schrieb:
> Na ja, das ist ein riesiges Projekt

Was hindert Dich daran, es nur auf die beiden Interupts zu reduzieren 
und alles zur Fehlersuche unnötige rauszuschmeißen.
Divide et impera.

von Martin (Gast)


Lesenswert?

Schon gemacht, aber das hat nicht nur mit einem Interrupt zu tun, 
sondern auch tritt auch bei den anderen.

Ich glaube (bin gerade noch beim Testen ob es wieder auftritt oder 
nicht) der Fehler ist das die Irq Flags direkt gelöscht werden:(z.B.) 
_T3IF = 0;
also nicht atomar, jetzt habe ich sie alle durch IFS0CLR = 0x0000..; 
ersetzt, was eine Atomare Operation sein soll.
Test läuft..

von Valeri K. (dl2vk)


Lesenswert?

ich habe so ein Problem gehabt. Microchip gibt ISR Beispiele nur mit 
einem Flag IF. Nachdem ich zusätzlich in ISR noch int_dis/en Bit 
eingefügt, ging alles ok. Also:

ISR
   int_disable
   .........
   .........
   int_flag löschen
   int_enable

Ich habe so verstanden: egal ob IF gesetzt ist, kann neu int ausgelöst 
werden. Dabei IF wird einfach nochmal gesetzt, obwohl er ist schon = 1. 
Int_disable verhindert während ISR einen neuen Int. Int_disable 
verhindert nur aktuelle Instanz nicht den ganzen µC.

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.