Forum: Mikrocontroller und Digitale Elektronik critical regions vom XC164CM


von Owen S. (senmeis)


Lesenswert?

Servus,

ich habe folgende Beschreibung über Interrupts vom XC164CM gelesen:

Unlike the classic C167, C166S V2 pipeline enhancements mean that 
clearing the global interrupt enable flag
(PSW.IEN = 0) will immediately disable all interrupts. This removes the 
need to insert NOP instructions after
clearing the flag. However this instant disabling does not apply to 
individual interrupt sources i.e. the Interrupt
Enable flags for the various peripherals.
Where it is critical that a particular interrupt is disabled before any 
other operation can begin (i.e. there is a critical
region), special steps are required that do not use the ATOMIC sequence 
instruction. Therefore to clear, for
example, the GPT12E_T3IC_IE flag or GPT12E_T3IC_IR flag, the following C 
macro is recommended by
Infineon:
1
#define Disable_One_Interrupt(IE_bit) \\
2
{if(IEN) {IEN=0; IE_bit=0; while (IE_bit); IEN=1;} else {IE_bit=0; while IE_bit);}}
Usage Example:
1
Disable_One_Interrupt(GPT12E_T3IC_IE) ; // T3 interrupt enable flag

Ich verstehe dies nicht ganz. Was wird geschafft mit
1
IE_bit=0; while (IE_bit);
?

Gruss
Senmeis

von TManiac (Gast)


Lesenswert?

Hi Senmeis,

der Gedanke hinter dem Macro ist (wie es der Text weiteroben 
beschreibt), dass das Löschen des IEN, des globalen InterruptEnableBits, 
eine ATOMIC sequence instruction ist. Das Löschen der einzelnen 
EnableBits aber nicht.

Der Befehl IE_bit=0; muss also erst durch die Pipeline.
Das heißt also, wenn zum Beispiel du am Anfang einer Interrupt-Routine 
den Interrupt vorübergehend sperren willst (zum Beispiel zum Entprellen) 
solltest du darauf achten das inzwischen kein weiterer Interrupt 
aufgetreten ist.

Folgendes Beispiel:
Du hast einen extrem prellenden Taster und willst seine Änderung mit 
einem Interrupt auswerten.
Interrupts sind aktiv
Es wird der Taster gedrückt.
-> Interrupt löst aus.
-> der Controller springt zum ersten Befehl der ISR und löscht 
automatisch das Interrupt-Flag.
Der erste Befehl in der ISR ist "disable Interrupt der ISR" damit das 
Prellen des Testers die ISR nicht gleich noch einmal auslöst. Nun gehst 
man davon aus, dass der Interrupt gesperrt ist. Dem ist aber nicht so, 
dass dauert noch drei Zyklen (wenn ich mich jetzt nicht täusche) bis der 
Befehl durch die Pipeline im Core angekommen ist.
das Makro sorgt nun dafür, dass nichst anderes gemacht wird bis das 
lokale IEN gelöscht ist. Es sorgt sogar dafür, dass auch keine weiteren 
Interrupts gemeldet werden können bis das lokale Flag gelöscht ist.

Das Makro ist also nur erforderlich, wenn man schnell auf einander 
folgende Events ausblenden will, um parallele Interrupts (man kann ja 
auch eine andere ISR deaktivieren) oder aber um aus dem Hauptprogramm 
heraus ohne Pipelining-Effekte, definiert einen Interrupt zu 
deaktivieren.

Gruß,
TManiac

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.