Forum: Mikrocontroller und Digitale Elektronik ARM/KEIL: Wie kann eine C-Funktion erkennen ob sie aus ISR heraus aufgerufen wurde?


von Alexander I. (daedalus)


Lesenswert?

Hallo,

ich muss eine kleine API schreiben, die unsere hausintere API an das 
RL-ARM Betriebssystem von KEIL anflanscht. Dabei ist es bei einigen 
API-Funktionen notwendig, dass diese erkennen können, ob sie von einer 
ISR heraus aufgerufen wurden oder nicht.

Beispiel:
Die nachfolgende Funktion löscht ein Event und darf nicht in einer ISR 
aufgerufen werden. Wenn doch, gibt sie OS_ERROR_ISRLEVEL zurück. Im 
OK-Fall ruft sie die os_evt_clr von RL-ARM auf.
1
Status ClearEvent(EvtMask mask)
2
{
3
 if(AusISRherausAufgerufen) // <-- gibt's da ein Makro / Intrinsic / ... ?
4
 {
5
  return OS_ERROR_ISRLEVEL;
6
 }
7
 else
8
 {
9
  os_evt_clr(event);
10
  return OS_OK;
11
 }
12
}

Da ich noch nicht so vertraut bin mit der KEIL-Umgebung meine Frage an 
euch, gibt's eine einfache Methode rauszufinden, ob die Funktion gerade 
in einer ISR läuft oder nicht? Könnte ich dazu z.B. VICVectAddr auf 0 
vergleichen?

Habe beim Debugging gesehen, dass der erkennt, ob ich im Mode "ISR" oder 
"User" bin. Scheint also irgendwie möglich zu sein. Ich hab aber keine 
Möglichkeit gefunden, an diese Aussage mit C-Code heranzukommen.

Vielen Dank vorab.

von (prx) A. K. (prx)


Lesenswert?

Klassische ARMs: Im Statusregister steht drin, in welchem 
Registerkontext er grad läuft (das wird das sein, was du im Debugger 
siehst). Das funktioniert aber nur, wenn man keine verschachtelten 
Interrupts zulässt, weil er sonst im Handler sofort vom 
Interrupt-Context wegschaltet. Ansonsten kann es sein, dass der 
Interrupt-Controller diese Information vermittelt, aber da gibt's mehr 
als einen Typ von.

Cortex-Cores: Aktuelle Priorität.

von Thomas K (Gast)


Lesenswert?

Hallo!

Das hört sich nach einer ARM-CPU. Eine genauere Angabe wäre hilfreich. 
Die ARMs haben ein Feld im PS-Register das den Modus bestimmt. Je nach 
ARM sieht es unterschiedlich aus.. Eines der Modi signalisiert die 
Ausführung eines Interrupts. Google mal nach ARM processor modes.. 
Ausserdem: das CPU Manual ist dein Freund! :)

Gruss
thomas

von (prx) A. K. (prx)


Lesenswert?

PS: Das sieht irgendwie nach RTOS aus. Ein RTOS, das verschachtelte 
Interrupts zulässt, benötigt auf klassischen ARMs üblicherweise einen 
Zähler für diese Verschachtelung. Der lässt sich auch dafür nutzen.

von Alexander I. (daedalus)


Lesenswert?

Hallo,

der Controller ist ein LPC2387 von NXP. Was ich bisher so gelesen hab, 
scheint man ja nur die unteren 5 Bits des CPSR-Registers via 
Inline-Assembler auslesen zu müssen?

von (prx) A. K. (prx)


Lesenswert?

Jein.

von Alexander I. (daedalus)


Lesenswert?

Es müsste doch folgendes klappen, oder?
1
int status;
2
__asm {mrs status, cpsr};
3
4
if(status & 0x12) 
5
{
6
 // IRQ
7
}
8
else
9
{
10
 if(status & 0x10)
11
 {
12
  // User
13
 }
14
 else
15
 {
16
  // Unzulässig!
17
 }
18
}

Ein erster Test hat jedenfalls funktioniert... warum "Jein."?

von Flag (Gast)


Lesenswert?

Setze einfach ein Flag.

Interrupt
 Flag=1;
 Aufruf Routine;
 Flag=0;



Routine:
  if (Flag) return;
  else ....

von (prx) A. K. (prx)


Lesenswert?

Alexander I. schrieb:

> Ein erster Test hat jedenfalls funktioniert... warum "Jein."?

Wdh: Das funktioniert nur, wenn man keine verschachtelten
Interrupts zulässt, weil sonst im Handler sofort vom
Interrupt-Kontext wegschaltet wird (meist in den System-Kontext. Ob 
deine Umgebung verschachtelte Interrupts zulässt weiss ich nicht, 
deshalb "jein".

von Alexander I. (daedalus)


Lesenswert?

Achso, alles klar. Ich verwende vorerst kein Interruptnesting.
Danke mal soweit!

von (prx) A. K. (prx)


Lesenswert?

Flag schrieb:

> Interrupt
>  Flag=1;
>  Aufruf Routine;
>  Flag=0;

Auch dies funktioniert nur, wenn Interrupts keine Interrupt-Handler 
unterbrechen können.

Besser:
  IrqLevel+=1;
  Aufruf Routine;
  IrqLevel-=1;

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.