Forum: Mikrocontroller und Digitale Elektronik Erkennen ob man in einer Interrupt Routine ist beim 8051


von Guest (Gast)


Lesenswert?

Hallo,

der 8051 hat zwei Interrupt Prioritäten, low and high.
Damit könnte es eine L1 Interrupt Rotuine mit low prio und eine zweite 
L2 Interrupt Routine mit high prio geben. Die L2 Interrupt Routine kann 
die L1 Interrupt Routine unterbrechen.

Gibt es beim 8051 die Möglichkeit zu erkennen ob man jetzt in der L1 
oder L2 Interrupt Routine gerade ist? Bei allen anderen CPUs war das bis 
jetzt kein Problem, entweder man konnte es im Program Status Word oder 
in irgendeinem Interrupt Register erkennen aber beim 8051 finde ich 
keine Lösung.

von Oliver S. (oliverso)


Lesenswert?

Setz die halt selber ein Flag.

Oliver

von TomA (Gast)


Lesenswert?

Hallo Guest,

die Anforderungsbit des UART bleiben bei Eintritt in die ISR (Interrupt 
Service Routine) erhalten, sie müssen immer per Software gelöscht 
werden.

Für die restlichen Interrupts ist der Vorschlag von Oliver doch 
geeignet!

Gruß. Tom

von Guest (Gast)


Lesenswert?

Danke, aber ein Flag setzen hilft nicht, da nicht sichergestellt ist das 
nicht vor dem Setzen des Flags im L1 Interrupt dieser nicht schon durch 
den L2 Interrupt unterbrochen wurde.

Letztlich geht es darum das beide Interrupts die gleiche Funktion 
aufrufen und ich in dieser erkennen muss, ob der Aufruf aus dem L1 
Interrupt kam.

von Georg G. (df2au)


Lesenswert?

Dann nimm zwei Einsprungpunkte. Der eine setzt das Flag, der andere 
nicht. Danach sind beide gleich.

von TomA (Gast)


Lesenswert?

Dann bleibt noch die benötigten Interrupts zu sperren und per Software 
zu pollen. Dabei bleiben die Anforderungsflags erhalten.

Oder setz beide Int's auf gleiche Priorität und gib den 2. innerhalb der 
1. Routine frei - nach setzen eines Flag?

von Guest (Gast)


Lesenswert?

Danke für die Ideen, aber leider alles so nicht umsetzbar.
Letzlich geht es um ein RTOS bei dem nur aus dem L1 Interrupt ein 
Taskwechsel ausgeführt werden darf. Ich habe keinen Einfluß darauf was 
der Anwender in seiner Interrupt Routine macht.

von Peter D. (peda)


Lesenswert?

Bis auf wenige Ausnahmen (Maxim) sind diese Flags beim 8051 nicht 
zugreifbar.
Einige 8051 (Atmel) haben auch 4 Prioritäten.

Ich wüßte jetzt nicht, warum man in Interrupts hoher Priorität das RTOS 
aufrufen sollte.
Die Interrupts sollten ja so kurz wie möglich sein. Funktionsaufrufe, 
die nicht inline sind, bewirken aber erstmal eine riesige 
Push/Pop-Orgie.

von Bastler (Gast)


Lesenswert?

Doch, Du schreibst ihm einfach ins Handbuch, was er zu machen hat. 
Andere OSe schreiben auch vor, wie eine ISR vorzugehen hat.

von Guest (Gast)


Lesenswert?

Bastler schrieb:
> Doch, Du schreibst ihm einfach ins Handbuch, was er zu machen hat.
> Andere OSe schreiben auch vor, wie eine ISR vorzugehen hat.

Das hilft leider nicht.
Stell die vor du rufst in beiden ISR eine Funktion StartInt() auf, die 
letztlich einen Zähler inkrementiert. Anhand dieses Zählers könntest du 
erkennen ob du im L1 oder L2 Interrupt bist...wenn nicht das Problem 
wäre das der L2 Interrupt schon ausgeführt werden könnte bevor der erste 
Befehl im L1 Interrupt ausgeführt wurde. Hilft also nicht.



>Ich wüßte jetzt nicht, warum man in Interrupts hoher Priorität das RTOS
>aufrufen sollte.
>Die Interrupts sollten ja so kurz wie möglich sein. Funktionsaufrufe,
>die nicht inline sind, bewirken aber erstmal eine riesige
>Push/Pop-Orgie.
Das die Performance beim 8051 bescheiden ist steht außer Frage.
Aber stell dir z.B. vor der Systick Timer läuft mit low prio und der 
Uart Interrupt läuft mit high prio. Aus beiden Interrupts muss ein 
preemptiver Taskwechsel möglich sein.

von (prx) A. K. (prx)


Lesenswert?

Wenn du ein RTOS baust, bei dem Interrupts niedriger Priorität RTOS APIs 
aufrufen dürfen, Interrupts hoher Priorität aber nicht, dann ist es 
letztendlich Sache des Anwenders des RTOS, sich daran zu halten. In 
solchen Systemen gibts kein Vollkasko.

von Martin L. (maveric00)


Lesenswert?

Hallo,

Wenn Du keinen Zähler verwendest, sondern tatsächlich zwei Flags setzt, 
stellt die Interrupt-Priorität und das direkte unterbrechen kein Problem 
dar (außer eventuell wenn die Routine nicht nur den aktuellen Level, 
sondern auch den letzten Level wissen muss - da fällt mir aber kein 
Grund zu ein).

Beispiel:

Normaler Programmablauf -> L1 interrupt -> L1 Flag setzen -> Irgendetwas 
-> Funktion aufrufen, die stellt fest, dass nur L1 Flag gesetzt ist, 
also L1 aktiv -> Irgendwas -> L1 Flag löschen -> Interrupt Ende -> 
Normaler Programmablauf

Normaler Programmablauf -> L1 interrupt -> L1 Flag setzen -> Irgendwas 
-> L2 Interrupt -> L2 Flag setzen -> Irgendetwas -> Funktion aufrufen, 
die stellt fest, dass L1 & L2 Flag gesetzt ist, also L2 aktiv -> 
Irgendwas -> L2 Flag löschen -> Interrupt beenden -> Irgendwas -> 
Funktion aufrufen, die stellt fest L1 ist gesetzt, also in in L1 -> 
Irgendwas -> L1 Flag löschen -> Interrupt Ende -> Normaler 
Programmablauf

Normaler Programmablauf -> L1 interrupt -> L2 Interrupt -> L2 Flag 
setzen -> Irgendetwas -> Funktion aufrufen, die stellt fest, dass nur L2 
Flag gesetzt ist, also L2 aktiv -> Irgendwas -> L2 Flag löschen -> 
Interrupt beenden -> L1 Flag setzen -> Irgendwas -> Funktion aufrufen, 
die stellt fest nur L1 ist gesetzt, also L1 aktiv -> Irgendwas -> L1 
Flag löschen -> Interrupt Ende -> Normaler Programmablauf

Du siehst, auch eine Unterbrechung des L1 bevor das Flag gesetzt ist, 
stellt kein Problem dar, wenn die L1 und L2-Flags in der Routine 
entsprechend priorisiert werden.

Schöne Grüße,
Martin

von Peter D. (peda)


Lesenswert?

Die Idee mit dem Flag ist gut.
Jeder Interrupt muß beim Eintritt eine Variable incrementieren und vor 
dem RETI decrementieren. Damit weißt Du immer, wieviel Level gerade 
laufen.
Ein high Level Interrupt vor dem INC bzw. nach dem DEC ist kein Problem, 
es ist ja noch nichts passiert bzw. alles abgeschlossen.

von Georg G. (df2au)


Lesenswert?

Peter Dannegger schrieb:
> high Level Interrupt vor dem INC

Abgesehen davon, dass grundsätzlich mindestens 1 Befehl ausgeführt wird, 
ehe der nächste Sprung erfolgt. Ein "INC #xxx" zerstört keine Register 
und darf daher problemlos als erste Befehl in der Routine stehen.

von GB (Gast)


Lesenswert?

Jeder Funktionsaufruf rettet vor dem Sprung zur Funktion die 
Rücksprungadresse auf den Stack.
Schau' Dir an, wo die hingelegt wird und werte Sie in der nachfolgenden 
Funktion aus.
Du brauchst dazu nur den aktuellen Stackpointer + den Offset für die 
abgelegte Rücksprungadresse.
Damit weißt Du sicher, woher der Funktionsaufruf kam.

von Guest (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Die Idee mit dem Flag ist gut.
> Jeder Interrupt muß beim Eintritt eine Variable incrementieren und vor
> dem RETI decrementieren. Damit weißt Du immer, wieviel Level gerade
> laufen.

Ne, das funktioniert halt nicht, wie ich oben schon beschrieben habe. 
Nämlich für den Fall das vor dem Inkrementieren im L1 Interrupt dieser 
schon durch den L2 Interrupt unterbrochen wurde...

Mit den Flags geht leider auch nicht, denn beide Interrupt Routinen 
rufen die gleiche!! API Funktion auf. Woher soll diese denn wissen, 
welches Flag sie setzen soll? Wenn ich weiß welches Flag ich setzen 
muss, dann weiß ich auch in welcher Interrupt Routine ich bin und das 
ich aus einem L2 Interrupt keinen Taskwechsel machen darf...dann brauche 
ich aber auch die Flags nicht.


>Abgesehen davon, dass grundsätzlich mindestens 1 Befehl ausgeführt wird,
>ehe der nächste Sprung erfolgt
Ist das so beim 8051?
Wenn dem so ist, dann wäre die Lösung als ersten Befehl die Interrupts 
zu sperren. Anschließend kann man ganz einfach mit einem Zähler 
arbeiten.
Ich bin bis jetzt davon ausgegangen, das dies beim 8051 nicht sicher so 
ist.

von Guest (Gast)


Lesenswert?

GB schrieb:
> Jeder Funktionsaufruf rettet vor dem Sprung zur Funktion die
> Rücksprungadresse auf den Stack.
> Schau' Dir an, wo die hingelegt wird und werte Sie in der nachfolgenden
> Funktion aus.
> Du brauchst dazu nur den aktuellen Stackpointer + den Offset für die
> abgelegte Rücksprungadresse.
> Damit weißt Du sicher, woher der Funktionsaufruf kam.

Sowas würde funktionieren, wenn z.B. das PSW mit auf dem Stack gerettet 
wird und dieses z.B. die Information enthält, ob man gerade einen 
Interrupt ausführt oder nicht. Bei anderen CPUs mache ich das genau so. 
Damit kann ich dann erkennen, das vorher kein Interrupt ausgeführt wurde 
und das dann der L1 Interrupt sein muss.

Aber nur über Rücksprungadresse wird es schwer. Woher soll ich in meinem 
OS wissen wo der Anwender seine Funktionen im Code hat? Es geht ja hier 
nicht um eine statische Anwendung sondern mein OS ist nur Teil einer 
Applikation.

von GB (Gast)


Lesenswert?

Das ist richtig, aber für die Interrupts gibt es Interrupt-Vektoren, 
diese liegen an einer festen Position. In diesem wird normalerweise der 
Sprung zur Interrupt-Service-Routine gemacht.
Also nachschauen, wohin er von den Interruptvektoren aus springt und mit 
aktueller Rücksprungadresse vergleichen.

von Guest (Gast)


Lesenswert?

GB schrieb:
> Das ist richtig, aber für die Interrupts gibt es
> Interrupt-Vektoren,
> diese liegen an einer festen Position. In diesem wird normalerweise der
> Sprung zur Interrupt-Service-Routine gemacht.
> Also nachschauen, wohin er von den Interruptvektoren aus springt und mit
> aktueller Rücksprungadresse vergleichen.

Die Idee ist so pervers, das sie schon wieder gut ist ;-).
Danke, ich werde darüber nachdenken.

Das Problem ist aber das in der IVT nur Einsprungsadressen stehen aber 
keine Information darüber wie groß die Interrupt Routinen sind. Der L2 
Interrupt muss ja den L1 Interrupt nicht unbedingt beim ersten Befehl 
unterbrechen.

von Peter D. (peda)


Lesenswert?

Guest schrieb:
> Wenn dem so ist, dann wäre die Lösung als ersten Befehl die Interrupts
> zu sperren.

Das sollte klappen. Das "CLR EA" muß dann der 1. Befehl in der 
Vektortabelle sein. Da je Vektor 8 Byte Platz sind, kein Problem.

von GB (Gast)


Lesenswert?

Guest schrieb:
> Das Problem ist aber das in der IVT nur Einsprungsadressen stehen aber
> keine Information darüber wie groß die Interrupt Routinen sind. Der L2
> Interrupt muss ja den L1 Interrupt nicht unbedingt beim ersten Befehl
> unterbrechen.

IVT:

L1: Sprung nach 0x01000

L2: Sprung nach 0x02000

Rücksprungadresse größer gleich 0x01000 und kleiner 0x02000 => L1
Rücksprungadresse größer gleich 0x02000 => L2

von TomA (Gast)


Lesenswert?

Hier eine kleine Beschreibung des Ablaufs beim Auftreten eines 
Interrupt.

Zitat:
Zwischen Auftreten eines Interrupt-Signals und Beginn der 
Interrupt-Service-Routine vergeht einige Zeit

    1 Befehlszyklus für das speichern der Anforderung
    1 Befehlszyklus für das Polling der Anforderung
    2 Befehlszyklen für den Aufruf (LCALL..) der ISR

Die Verzögerung zwischen Auftreten einer Interrupt-Anforderung und der 
Interrupt-Ausführung kann allerdings noch wesentlich länger dauern.

    1. Wenn gerade ein Interrupt abgearbeitet wird.
    2. Wenn der Befehlszyklus, in dem das Polling durchgeführt wird,
       nicht der letzte Zyklus des auszuführenden Befehls ist.
    3. Wenn gerade ein RETI-Befehl oder ein Zugriff auf eines der
       SFRegister IE oder IP durchgeführt wird.

Im ersten Fall ist die Verzögerung abhängig von der Länge der noch 
auszuführenden ISR. Nach dem RETI-Befehl wird noch ein Befehl im zuvor 
unterbrochenen Programm ausgeführt, erst dann wird der neue Interrupt 
Interrupt bearbeitet.

Im zweiten Fall wird der Befehl noch ganz abgearbeitet (max. 4 
Befehlszyklen bei MUL bzw. DIV), danach wird der Interrupt bearbeitet.

Im dritten Fall wird noch der daruffolgende Befehl abgearbeitet, da 
Befehle, welche die Interrupt-Logik (Hardware) beeinflussen keinen 
Interrupt zulassen.

Zitat Ende!

So wie ich das lese, wird da nicht zwingend ein Befehl in der ISR 
ausgeführt. Das müsste man evtl. mit einem guten Simulator überprüfen.

Um welchen Baustein der 51er-Familie handelt es sich den konkret? Da 
gibt es ja eine Vielzahl verschiedener Typen, mit Teilweise abweichenden 
Funktionen.

Gruß. Tom

von TomA (Gast)


Lesenswert?

Hallo Guest,

wenn ich ein wenig gründlicher über dein Problem nachdenke, fällt mir 
Folgendes ein.

Im laufenden Proramm haben alle INT's die gleiche Priorität. Beim 
auftreten eines INT, setzt du deine benötigteen Flags und teilst dann 
den benötigten INT's die höhere Priorität zu. Ab da sind sie in der Lage 
deine ISR zu unterbrechen und trotzdem hast du den Überblick!

Gruß. Tom

von Guest (Gast)


Lesenswert?

TomA schrieb:
> Um welchen Baustein der 51er-Familie handelt es sich den konkret? Da
> gibt es ja eine Vielzahl verschiedener Typen, mit Teilweise abweichenden
> Funktionen.

Das OS muss auf jedem 8051 funktionieren, daher kann ich leider nicht 
von einem speziellen Device ausgehen. Ich stimme dir auch zu das nicht 
sicher gestellt ist, das der erste Befehl ausgeführt wird, den zitieren 
Absatz habe ich auch schon in der Doku gelesen.

TomA schrieb:
> Im laufenden Proramm haben alle INT's die gleiche Priorität. Beim
> auftreten eines INT, setzt du deine benötigteen Flags und teilst dann
> den benötigten INT's die höhere Priorität zu. Ab da sind sie in der Lage
> deine ISR zu unterbrechen und trotzdem hast du den Überblick!

Auch sehr nette Idee. Hieße aber das ich mir für jeden Interrupt merken 
muss, ob auf welcher Prio er laufen soll.

Wahscheinlich wird es erstmal darauf hinauslaufen, das OS API Aufrufe 
aus high prio Interrupt Routinen nicht zulässig sind.

Btw. Danke an alle Beteiligten für dieses konstruktive Brainstorming!!

von Georg G. (df2au)


Lesenswert?

Guest schrieb:
> Ist das so beim 8051?
Ich muss mich korrigieren. Das mit der Ausführung mindestens eines 
Befehls gilt nicht generell für alle Befehle. In der Hardware 
Beschreibung des 8051 steht sogar etwas versteckt drin, dass der höher 
priorisierte Interrupt in den ersten 2 Befehlszyklen nach Erkennung des 
niedrig priorisierten Interrupts noch gewinnen kann. Nur nach einem RETI 
wird mindestens ein Befehl ausgeführt, ehe der nächste Interrupt eine 
Chance hat.

Zu der Erkennung des "Woher" über den Stack: Was passiert, wenn der böse 
User in seiner Routine einen PUSH einschiebt? Wie unterscheidet man 
Daten vom PC, wenn man auf den Stack schaut?

: Bearbeitet durch User
von Martin L. (maveric00)


Lesenswert?

Hallo,

sind meine folgenden Annahmen korrekt?

- Du möchtest also ein RTOS mit API-Funktionen haben, die von 
verschiedenen Interrupts aufgerufen werden kann.
- Du möchtest, dass der Anwender die Adresse der API-Funktionen direkt 
in den Interrupt-Vektor eintragen kann; abhängig vom Vektor muss diese 
Funktion dann aber unterschiedlich reagieren.

Wenn das der Fall ist, würde ich den ersten Satz des zweiten Punktes 
noch einmal überdenken; normalerweise würde so etwas durch Callbacks 
(oder Hooks oder wie Du es nennen möchtest) mit entsprechenden Wrappern 
und Registrierungsfunktionen gelöst. Dabei implementiert das RTOS für 
jeden Interrupt-Vektor eine kleine Routine (die dann z.B. auch die Flags 
setzen kann), welche nach einer möglichen Verwaltungsarbeit eine oder 
mehrere Funktionen aufruft, die vorher von dem Anwendungsprogramm 
während der Initialisierung für diesen Vektor registriert worden sind. 
Bei der Registrierung kann ggf. noch zusätzlich die Prio gesetzt werden.

Kostet nur ein paar Takte mehr pro Interrupt, dafür hast Du die 
gewünschte Funktionalität.

Schöne Grüße,
Martin

von Guest (Gast)


Lesenswert?

Martin L. schrieb:
> - Du möchtest, dass der Anwender die Adresse der API-Funktionen direkt
> in den Interrupt-Vektor eintragen kann; abhängig vom Vektor muss diese
> Funktion dann aber unterschiedlich reagieren.
>
> Wenn das der Fall ist, würde ich den ersten Satz des zweiten Punktes
> noch einmal überdenken;

Nicht ganz. Ich habe natürlich für jeden Interrupt einen eigenen 
Interrupt Handler. Der Anwender muss aber am Anfang und Ende der 
Interrupt Routine eine API Funktion aufrufen. Das Eintragen in die IVT 
macht in dem Fall schon der IAR für mich. Die API Funktion am Ende der 
Interrupt Routine muss jetzt entscheiden können ob sie aus dem L1 
Interrupt aufgerufen wurde und darf nur dann einen Taskwechsel falls 
nötig ausführen.

Martin L. schrieb:
> Dabei implementiert das RTOS für
> jeden Interrupt-Vektor eine kleine Routine (die dann z.B. auch die Flags
> setzen kann), welche nach einer möglichen Verwaltungsarbeit eine oder
> mehrere Funktionen aufruft,

Hilft nicht, man hat immer noch das prinzipelle Problem wie oben 
beschrieben.
Wenn du das Flag setzt weißt du nicht, ob du im L1 oder L2 Interrupt 
bist.
Deine Idee funktionert nur wenn Interrupts nicht nestable on entry sind. 
Sind sie aber beim 8051.

von Peter D. (peda)


Lesenswert?

Guest schrieb:
> Ich habe natürlich für jeden Interrupt einen eigenen
> Interrupt Handler. Der Anwender muss aber am Anfang und Ende der
> Interrupt Routine eine API Funktion aufrufen.

Warum muß er das?

Wenn ich höher priorisierte Interrupts benutze, dann weil sie sauschnell 
sein müssen. Dann möchte ich nicht durch Unterfunktionsaufrufe mit 
Push/Pop Orgien die Geschwindigkeit wieder zunichte machen.

Ist der Interrupt aber nicht zeitkritisch, dann brauche ich die hohe 
Priorität ja nicht.

von Martin L. (maveric00)


Lesenswert?

Hallo,

ich glaube, wir reden etwas aneinander vorbei. Wenn ich Dich richtig 
verstehe, dann sieht das bei Dir etwa wie folgt aus (Pseudo-Code)

Anwenderprogramm:
1
UASRT_INTERRUPT Handler () //prio L
2
{
3
 CALL_API_ENTRY () ;
4
5
 Tu_Was();
6
7
 CALL_API_EXIT () ;
8
}
9
10
TIMER_INTERRUPT Handler2 () //prio H
11
{
12
 CALL_API_ENTRY () ;
13
14
 Tu_Was () ;
15
 
16
 CALL_API_EXIT() ;
17
}
18
19
main ()
20
{
21
  Init ()
22
  EnableInterrupts() ;
23
  while (1) ;
24
}

Die Handler wird von dem Linker in die Vektortabelle eingetragen. In 
diesem Fall hast Du tatsächlich das Problem, dass Nested-Interrupts 
nicht sauber erkannt werden können bzw. die Priorisierung ohne das der 
Anwender etwas macht nicht sauber bestimmbar ist.

Mein Vorschlag sieht allerdings so aus:

RTOS:
1
void (*Callbacks)() [NUM_INTS] ;
2
void IntPrio [NUM_INTS] ;
3
4
int LoPrio ;
5
int HiPrio ;
6
7
#define USART 0
8
#define TIMER 1
9
10
UASRT_INTERRUPT Handler () 
11
{
12
 // Flags setzen
13
 if (IntPrio[USART]==0) {
14
   LoPrio=1 ; 
15
 } ;
16
17
 if (IntPrio[USART]==1) {
18
   HighPrio=1 ; 
19
 } ;
20
21
 // Funktion aufrufen
22
 (*Callbacks)[USART] ();
23
24
 // Flag loeschen
25
 if (IntPrio[USART]==0) {
26
   LoPrio=0 ; 
27
 } ;
28
29
 if (IntPrio[USART]==1) {
30
   HighPrio=0 ; 
31
 } ; 
32
}
33
34
TIMER_INTERRUPT Handler2 () 
35
{
36
 // Flags setzen
37
 if (IntPrio[TIMER]==0) {
38
   LoPrio=1 ; 
39
 } ;
40
41
 if (IntPrio[TIMER]==1) {
42
   HighPrio=1 ; 
43
 } ;
44
45
 // Funktion aufrufen
46
 (*Callbacks)[TIMER] ();
47
48
 // Flag loeschen
49
 if (IntPrio[TIMER]==0) {
50
   LoPrio=0 ; 
51
 } ;
52
53
 if (IntPrio[TIMER]==1) {
54
   HighPrio=0 ; 
55
 } ; 
56
}
57
58
void CALL_API_EXIT ()
59
{
60
 if (HighPrio==1) {
61
   // Sind in einem hoch-Prioren Interrupt
62
   Tu_Was () ;
63
 } else if (LoPrio==1) {
64
   // Sind in einem niedrig-Prioren Interrupt
65
   Tu_Was_Anderes () ;
66
 } else {
67
   // Sind in keinem Interrupt
68
   Bekomm_Panik () ;
69
 } ;
70
}
71
72
73
void RegisterInterrupt (void (*Func)(),int Vector, int Prio)
74
{
75
 Callback[Vector] = Func ;
76
 IntPrio[Vector] = Prio ;
77
78
 SetInterruptPrio (Vector,Prio) ; // Setzt die Priorität in der Hardware
79
 EnableInterrupt (Vector) ; // Schaltet den Interrupt in der Hardware ein
80
}

Der User-Teil sieht dann so aus:
1
void USART_Hander ()
2
{
3
 CALL_API_ENTRY () ;
4
5
 Tu_Was () ;
6
7
 CALL_API_EXIT () ;
8
} 
9
10
void TIMER_Hander ()
11
{
12
 CALL_API_ENTRY () ;
13
14
 Tu_Was_Anderes () ;
15
16
 CALL_API_EXIT () ;
17
} 
18
19
main ()
20
{
21
 Init () ;
22
23
 RegisterInterrupt (USART_Handler,USART,1) ;
24
 RegisterInterrupt (TIMER_Handler,TIMER,0) ;
25
26
 while(1) ;
27
}

Die User-Handler werden also nicht von dem Linker eingebunden. 
Stattdessen werden RTOS-Handler eingebunden, die die User-Handler 
aufrufen. Dies sollte wie gewünscht funktionieren, wenn der 
Low-Prio-Interrupt nur vom High-Prio-Interrupt unterbrochen werden kann 
und der High-Prio-Interrupt nicht unterbrechbar ist (eingeschränkte 
Interrupt-Verschachtelung). Wenn man die Flags zu Countern ausbaut, 
gehen auch vollständig verschachtelbare Interrupt-Strukturen; ebenso 
kann man natürlich auch die Anzahl der Flags erhöhen, wenn mehr 
Prioritätsstufen hinzukommen.

Oder sieht jemand einen Fehler?

Schöne Grüße,
Martin

von Guest (Gast)


Lesenswert?

Hallo Martin,

Martin L. schrieb:
> Bekomm_Panik () ;

rofl...sehr geil ;-).


Ja, du hast mich richtig verstanden, genauso sieht es aus.
Dein Vorschlag macht auf jeden Fall Sinn.
Allerdings muss ich mich an eine bestehende API halten, bin mir nicht 
ganz sicher ob ich das so umsetzen kann.

Ich werde mir aber nochmal Gedanken dazu machen.

Danke!!

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.