Forum: Mikrocontroller und Digitale Elektronik Cortex M3: Software-Interrupt gezielt auslösen?


von wibo (Gast)


Lesenswert?

Hallo,

gibt es eine Möglichkeit, einen (dafür vorgesehenen) Interrupt per 
Software auszulösen, also so etwas wie
1
triggerIRQ(IRQn)

Das Ziel ist nicht der Debugger, sondern ein bestimmter Programmfluss.

von N. G. (newgeneration) Benutzerseite


Lesenswert?

Hallo,

ja, das geht und ist ein Feature vom NVIC. Siehe das User Manual für den 
Cortex-M3 für Details.

Die CMSIS bietet hiefür auch direkt eine Funktion:
1
void NVIC_SetPendingIRQ(IRQn_Type IRQn);
Dokumentation findet man unter anderem hier:
https://www.keil.com/pack/doc/CMSIS/Core/html/group__NVIC__gr.html#ga3b885147ef9965ecede49614de8df9d2

Mit freundlichen Grüßen,
N.G.

von pegel (Gast)


Lesenswert?


von Mampf F. (mampf) Benutzerseite


Lesenswert?

wibo schrieb:
> Hallo,
>
> gibt es eine Möglichkeit, einen (dafür vorgesehenen) Interrupt per
> Software auszulösen, also so etwas wie
> triggerIRQ(IRQn)
>
> Das Ziel ist nicht der Debugger, sondern ein bestimmter Programmfluss.

Kann man die ISR-Funktion nicht einfach aufrufen?

von Jim M. (turboj)


Lesenswert?

Jein. NVIC_SetPendingIRQ() oder NVIC->STIR können einen Interrupt 
triggern - aber die erste Amtshandlung eines Handlers ist normalerweise 
nachzuschauen welches Bit im Peripherial den Interrupt konkret ausgelöst 
hat.

Ein Interrupt Trigger im Peripherial ist aber spezifisch vom konkreten 
Mikrocontroller - es könnte u.U. sogar sein dass man bestimmte Bits nur 
die Hardware selbst setzen kann. Da kocht jeder Hersteller sein eigenes 
Süppchen.

von Jim M. (turboj)


Lesenswert?

wibo schrieb:
> Das Ziel ist nicht der Debugger, sondern ein bestimmter Programmfluss.

Schau dir mal den PendSV an, den kann man über das PENDSVSET Bit im 
SCB->ICSR  triggern:
1
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;

Den nehme ich gerne für low-priority Nacharbeiten aus eine High-Priority 
Interrupt Handler.

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

Mampf F. schrieb:
> wibo schrieb:
>> Hallo,
>>
>> gibt es eine Möglichkeit, einen (dafür vorgesehenen) Interrupt per
>> Software auszulösen, also so etwas wie
>> triggerIRQ(IRQn)
>>
>> Das Ziel ist nicht der Debugger, sondern ein bestimmter Programmfluss.
>
> Kann man die ISR-Funktion nicht einfach aufrufen?

Könnte man (der Cortex hat ja keine speziellen Interruptframes, also 
können ISR Funktionen jederzeit ohne __interrupt() o.ä. aufgerufen 
werden), aber dann bräuchte man ja keinen Interrupt, sondern einfach nur 
eine Subroutine... ;-)

Wie Du sicherlich weisst, ist der Mechanismus mit dem Trigger/Invoke 
Interrupt genau dazu da, den Code in die Prioritätenhierarchie 
einzubetten, d.h. der SW ISR wird eben gerade nicht zu dem Zeitpunkt 
aufgerufen, wo er getriggert wird, sondern erst dann, wenn alles höher 
priorisierte fertig ist. Deswegen wird er gerne zum Context Switchen 
benutzt - man kann den Context Switch sowohl von einem beliebigen ISR 
als auch aus jeder Task anstossen, aber der ISR (in dieser Konfiguration 
immer lowest Pri) wird erst dann aufgerufen, wenn wir sicher wissen, 
dass wir in einem Task Context sind (den wir als Betriebssystem geordnet 
wegspeichern können).

Wenn wir das nicht bräuchten, wäre ein Unterfunktionsaufruf tatsächlich 
die naheliegende Lösung...

von wibo (Gast)


Lesenswert?

Herzlichen Dank an alle, das hilft mir sehr weiter.

Zum PendSV noch zwei Nachfragen: Ich nehme an, der hat keine wichtige 
Aufgabe im System, wenn man den verwenden kann? Gibt es unter den 
Interrupts 16-240 auch welche, die nicht belegt aber verwendbar sind?

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

wibo schrieb:
> Herzlichen Dank an alle, das hilft mir sehr weiter.
>
> Zum PendSV noch zwei Nachfragen: Ich nehme an, der hat keine wichtige
> Aufgabe im System, wenn man den verwenden kann? Gibt es unter den
> Interrupts 16-240 auch welche, die nicht belegt aber verwendbar sind?

1. Der PendSV wird mit fast 100%iger Sicherheit verwendet (und zwar 
systemkritisch), wenn Du ein RTOS verwendest (siehe mein Post zur 
Erklärung weiter oben).

2. Die ISRs 0-15 sind bei allen Cortex PODs gleich belegt, die darüber 
sind POD spezifisch. Deine Frage lässt sich also nicht beantworten, ohne 
zu wissen, über welches POD wir reden.

3. Du kannst nicht jeden ISR "frei verwenden" (also kontrolliert 
triggern) wie den PendSV. Normalerweise werden die ISRs von der Hardware 
angestossen. Manche PODs können durchaus eine weitere Menge von SW 
triggerbaren ISRs implementieren (soweit ich mich erinnere, gibt es u.A. 
ein paar von NXP). Mglw. kannst Du manche nicht dafür gedachte ISRs  in 
manchen PODs durch tricks wie faken von Hardwareevents zu einem 
vergleichbaren Verhalten wie den PendSV bringen, aber das sind eher 
halbseidene Angelegenheiten, und Du kannst Dich nicht unbedingt darauf 
verlassen, das solche Spielchen mit späteren Hardwarerevisionen oder 
Anderen PODs desselben Herstellers auch so funktionieren.

Zeit, dass Du mal erklärst, was Du eigentlich vor hast damit zu machen, 
wenn Du mehr Infos haben willst...

: Bearbeitet durch User
von Lothar (Gast)


Lesenswert?

wibo schrieb:
> einen (dafür vorgesehenen) Interrupt per Software auszulösen

Wie wäre es denn mit dem Software-Interrupt SWI/SVC ?

von Jim M. (turboj)


Lesenswert?

Lothar schrieb:
>> einen (dafür vorgesehenen) Interrupt per Software auszulösen
>
> Wie wäre es denn mit dem Software-Interrupt SWI/SVC ?

Da muss der SVC Interrupt aber eine höhere Priorität als der Auslöser 
haben, sonst gibts (Hard-) Fault.

PendSV macht grade die andere Richtung - aber keine Ahnung was der OP 
wirklich braucht.

Man kann übrigens jeden unbenutzen Interrupt dafür missbrauchen. Die 
meisten Cortex-M3 haben jede Menge Peripherials - unwahrscheinlich das 
man alle in einem Programm verwendet.

von Steffen R. (steffen_rose)


Lesenswert?

Mampf F. schrieb:
> Kann man die ISR-Funktion nicht einfach aufrufen?

Das Verhalten ist dann typischerweise ein anderes. U.a. muss die 
Funktion dann reentrant sein oder man muss sicherstellen, dass der 
Interrupt nicht genau zur gleichen Zeit auch noch zuschlägt.

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

Steffen R. schrieb:
> Mampf F. schrieb:
>> Kann man die ISR-Funktion nicht einfach aufrufen?
>
> Das Verhalten ist dann typischerweise ein anderes. U.a. muss die
> Funktion dann reentrant sein oder man muss sicherstellen, dass der
> Interrupt nicht genau zur gleichen Zeit auch noch zuschlägt.

Ausserdem wird der Cortex automatisch in den Handler Mode versetzt, wenn 
er eine ISR ausführt. Wenn der ISR code per Aufruf direkt aus einer task 
ausgeführt wird, bleibt der POD im Thread mode. Je nachdem was in dem 
ISR passiert, kann das Verhalten in beiden Fällen unterschiedlich sein 
(der SP kann z.B. auf unterschiedliche stacks verweisen).

von wibo (Gast)


Lesenswert?

Jim M. schrieb:
> Lothar schrieb:
>> Wie wäre es denn mit dem Software-Interrupt SWI/SVC ?
>
> Da muss der SVC Interrupt aber eine höhere Priorität als der Auslöser
> haben, sonst gibts (Hard-) Fault.
>
> PendSV macht grade die andere Richtung - aber keine Ahnung was der OP
> wirklich braucht.

Ja, genau das meine ich, genauso wie Du es beschrieben hast. Und RTOS 
will ich gerade nicht verwenden, also benutze ich jetzt den PendSV.

> Man kann übrigens jeden unbenutzen Interrupt dafür missbrauchen. Die
> meisten Cortex-M3 haben jede Menge Peripherials - unwahrscheinlich das
> man alle in einem Programm verwendet.

Das meinte ich: ob man statt PendSV auch diese verwenden kann. Aber ein 
Interrupt reicht mir hier aus.

SWI hatte ich im Hinterkopf, aber mir war nicht klar, dass dort die 
Priorität gerade andersrum ist. Herzlichen Dank für den Hinweis also!

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.