Hallo, Ich möchte Code absichern, so daß er nicht gleichzeitig vom Hauptprogramm und von Interrupt-Routinen betreten werden kann. Einfach Interrupts disablen und danach wieder einschalten wird nicht funzen, weil dir Funktionen selbst aus einer ISR aufgerufen werden könnten. Reicht es, wenn ich das CPSR zwischenspeichere und danach wieder restauriere?
Interrupts abschalten. Ob alle, oder bloss den betreffenden, kannst du dir aussuchen. Eine Mutex ist ein RTOS-Konstrukt und hindert Zugriff durch konkurrierende Prozesse indem ggf. der eine auf den anderen wartet. Bei Interrupts lässt sich das schlecht machen.
> Interrupts abschalten. Ob alle, oder bloss den betreffenden, kannst du > dir aussuchen. Naja, aber was passiert wenn ich in einer ISR die Interrupts ab- und danach wieder einschalte. Das funktioniert doch nicht, oder. Beispiel:
1 | // Diese Funktion darf nicht gleichzeitig betreten werden
|
2 | void LockedFunction (void) |
3 | {
|
4 | __disable_interrupt(); |
5 | // ...
|
6 | // Weiterer Code
|
7 | // ...
|
8 | __enable_interrupt(); |
9 | }
|
10 | |
11 | // Hauptprogramm
|
12 | void main () |
13 | {
|
14 | for (;;) |
15 | {
|
16 | // ...
|
17 | LockedFunction(); // Wäre ja kein Problem |
18 | // ...
|
19 | }
|
20 | }
|
21 | |
22 | // Interrupt Routine
|
23 | void ISR (void) |
24 | {
|
25 | // ...
|
26 | LockedFunction(); // Aber wie mache ich das? |
27 | // ...
|
28 | }
|
Nö, das funktioniert nicht. Drum sieht das auch eher so aus:
1 | void LockedFunction (void) |
2 | {
|
3 | unsigned savedCPSR = __disable_interrupt(); |
4 | // ...
|
5 | // Weiterer Code
|
6 | // ...
|
7 | __restore_interrupt(savedCPSR); |
8 | }
|
Alternativ kann man nur der betreffende Interrupt abschalten. In der ISR ist es meist egal ob man den auch dort zeitweilig mal aus- und einschaltet. Hier am Beispiel LPC2000:
1 | void LockedFunction (void) |
2 | {
|
3 | VICIntEnClr = 1<<UARTInterrupt; |
4 | // ...
|
5 | // Weiterer Code
|
6 | // ...
|
7 | VICIntEnable = 1<<UARTInterrupt; |
8 | }
|
Wobei man dabei die Verzögerung der Interrupt-Pipeline und des Speicherbefehls beachten sollte, weshalb es nach VICIntEnClr einige wenige Takte dauern kann, bis das wirklich greift.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.