Forum: Mikrocontroller und Digitale Elektronik unterbrechbarer Int.


von AVR-freak (Gast)


Lesenswert?

Hi ich arbeite gerade mit einem atmega8 und muss dabei mit den INTs 
spielen und brauiche dafür unterbrechbare ISR.
Meine Frage:

Wisst ihr wieviel ISR sprünge (also wieviel ISR Verschachtelungen 
ineinander ) ein atmega8 mitmacht?
BSP Alle ISR sind unterbrechbar....


INT1 kommt
ISR1 wird anfangen
.
INT2 kommt
.
ISR2 wird angefangen
.
.
.
INTN kommt

ISRN wird angefangen
ISRN wird beendet
.
ISR2 wird beendet

ISR1 wird beendet

Im datenblatt habe ich dazu leider nichts gefunden... Mir ist klar dass 
es nicht von Vorteil ist N ISR zu Verschachteln, da sonst ISR1 an 
starvation leidet.Es sollte nur ein Bsp sein um klarzumachen was ich 
meine / will.

Habt ihr ne Idee?

von Peter II (Gast)


Lesenswert?

AVR-freak schrieb im Beitrag #2590500:
> Hi ich arbeite gerade mit einem atmega8 und muss dabei mit den INTs
> spielen und brauiche dafür unterbrechbare ISR.

begründe das bitte, warum du das brauchst?

Im normalfall werden sie gar nicht unterbrochen, weist du das?

Wenn du es so hingebogen hast, das es doch geht. Dann ist es abhängig 
davon wie viele werte du (oder der compieler) auf den Stack legst.

von Falk B. (falk)


Lesenswert?

@  AVR-freak (Gast)

>Wisst ihr wieviel ISR sprünge (also wieviel ISR Verschachtelungen
>ineinander ) ein atmega8 mitmacht?

Bis der Stack überläuft. Der liegt im SRAM. Den Rest sollte ein 
AVR-freak selber zusammenreimen können.

MfG
Falk

von Jonathan S. (joni-st) Benutzerseite


Lesenswert?

Das kommt darauf, wie viel Stack Du pro Aufruf brauchst. Also 3 Byte 
(Rücksprungadresse plus SREG) plus die Anzahl der Register, die Du 
sichern musst. Sagen wir einfach mal, Du sicherst alle Register. Das 
heißt, Du brauchst pro Aufruf 35 Byte Stack. Der ATMega8 hat 1KB RAM. 
Macht also 29 verschachtelte Interrupts maximal, wenn Du alle Register 
sicherst.


Gruß
Jonathan

von AVR-freak (Gast)


Lesenswert?

Danke für die schnelle gute Antwort! :-)

cool dass man hier doch noch schnelle gute Hilfe bekommen kann! habe das 
schon anders erlebt.

ich dachte das sei per hardware begrentzt. dabei meine ich nicht durch 
den speicher sondern dass  pauschal gesagt wird um starvation zu 
vermeiden wird bei x sprüngen abgeriegelt.

von Michael (Gast)


Lesenswert?

Ich würde behaupten, du willst hier nicht unterbrechen. Klingt nach 
falschem Programmdesign. Interruptroutinen sollten immer so kurz wie 
möglich sein. Wie wäre es mit "lienar" abarbeiten in der Reihenfolge 
ihres Auftretens?
Welche Anwendung gibt es, wo man definitiv schachteln müsste?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

AVR-freak schrieb im Beitrag #2590500:
> Hi ich arbeite gerade mit einem atmega8 und muss dabei mit den INTs
> spielen und brauiche dafür unterbrechbare ISR.
Ja, hört sich nach Murks an.
Stell dir mal die Frage: warum brauchen Andere das nicht?

Du könntest natürlich auch einfach mal konkretere Angaben machen. 
Ansonsten sieh einfach mal nach, was der reti Befehl mit den 
Interrupt-Flags macht. Das mußt du auch machen...

von AVR-freak (Gast)


Lesenswert?

naja liniear abarbeiten nach der reihenfolge vom auftreten finde ich 
scheisse.....was ist wenn ich eine ISR habe dann einen "unwichtigen bzw 
nicht so wichtiten INT " bekomme und danach einen "mega wichtigen INT" 
dann wird nbei der liniearen abarbeitung zuerst der "unwichtige" INT 
abgearbeitet und danach der wichtige deswesgen ziehe ich immer eine 
Prioritäten Abarbeoitung vor.

von Peter II (Gast)


Lesenswert?

AVR-freak schrieb im Beitrag #2590592:
> ziehe ich immer eine
> Prioritäten Abarbeoitung vor.

dann mache die unwichtigen sachen im main, getriggert vom der ISR.

von Thomas E. (thomase)


Lesenswert?

AVR-freak schrieb im Beitrag #2590592:
> was ist wenn ich eine ISR habe dann einen "unwichtigen bzw
> nicht so wichtiten INT " bekomme und danach einen "mega wichtigen INT"
> dann wird nbei der liniearen abarbeitung zuerst der "unwichtige" INT
Und genau das passiert nicht.
Die werden nicht in eine Warteschlange gestellt, sondern wenn der gerade 
in der Abarbeitung befindliche Interrupt fertig ist, wird der Interrupt 
mit der höchsten Priorität als nächstes abgearbeitet. Unabhängig vom 
Zeitpunkt des Auftretens.

mfg.

von Karl H. (kbuchegg)


Lesenswert?

AVR-freak schrieb im Beitrag #2590592:

> nicht so wichtiten INT " bekomme und danach einen "mega wichtigen INT"
> dann wird nbei der liniearen abarbeitung zuerst der "unwichtige" INT
> abgearbeitet und danach der wichtige deswesgen ziehe ich immer eine
> Prioritäten Abarbeoitung vor.

Dann hast du den Fehler gemacht, dass du zu viel Funktionalität in die 
Interrupt Routinen gesteckt hast.

von AVR-freak (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> AVR-freak schrieb im Beitrag #2590592:
>> was ist wenn ich eine ISR habe dann einen "unwichtigen bzw
>> nicht so wichtiten INT " bekomme und danach einen "mega wichtigen INT"
>> dann wird nbei der liniearen abarbeitung zuerst der "unwichtige" INT
> Und genau das passiert nicht.
> Die werden nicht in eine Warteschlange gestellt, sondern wenn der gerade
> in der Abarbeitung befindliche Interrupt fertig ist, wird der Interrupt
> mit der höchsten Priorität als nächstes abgearbeitet. Unabhängig vom
> Zeitpunkt des Auftretens.
>
> mfg.

michael hatte aber explizit gesagt nach der reihenfolge ihres 
auftretens....

>Wie wäre es mit "lienar" abarbeiten in der Reihenfolge
>ihres Auftretens?

deswegen hab ich das mit den Prioritöäten gesagt....weiss garnicht ob 
eine lineare abarbeitung bei den atmegas möglich is

von AVR-freak (Gast)


Lesenswert?

Peter II schrieb:
> AVR-freak schrieb im Beitrag #2590592:
>> ziehe ich immer eine
>> Prioritäten Abarbeoitung vor.
>
> dann mache die unwichtigen sachen im main, getriggert vom der ISR.

naja aber wenn ich zb eine PWM habe und im hauptprogramm noch ordentlich 
zeugs kann ich die nicht in der main machen... was du mit einer 
getriggerten verarbeitung von der ISR versteh ich auf Anhieb nicht

von Peter II (Gast)


Lesenswert?

AVR-freak schrieb im Beitrag #2590643:
> naja aber wenn ich zb eine PWM habe

eine PWM muss ein ein paar takten erledigt sein, wenn nicht hast du was 
falsch gemacht.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mehrer ISR-Level bzw. Prioritäten zu haben kann durchaus sinnvoll sein.

Viele µC unterstürten zum Beispiel verschiedene IRQ-Prioritäten, und 
wenn mich nicht alles täuscht gehören auch AVRs (XMEGA) dazu.

Dogmen wie "ISRs niemals nicht unterbrechen" etc. sind eh hinfällig.

Das trifft zwar für viele Anwendungen zu, eber wie immer und überall 
gibt es auch Ausnahmen.

von Thomas E. (thomase)


Lesenswert?

AVR-freak schrieb im Beitrag #2590643:
> naja aber wenn ich zb eine PWM habe und im hauptprogramm noch ordentlich
> zeugs kann ich die nicht in der main machen
Eine PWM lässt man im Timer laufen. Dann ist es völlig egal, was der 
Rest des Controllers macht.

AVR-freak schrieb im Beitrag #2590643:
> naja aber wenn ich zb eine PWM habe und im hauptprogramm noch ordentlich
> zeugs kann ich die nicht in der main machen...
Aber schreib' erstmal dein Programm. Ich glaube eher du bist auf einem 
Level, in dem du noch ganz andere Sorgen hast.

mfg.

von Thomas E. (thomase)


Lesenswert?

Johann L. schrieb:
> Mehrer ISR-Level bzw. Prioritäten zu haben kann durchaus sinnvoll sein.
Das macht ja auch Sinn. Wenn sie denn einstellbar sind. Das ist beim 
Atmega/tiny aber nicht der Fall. Da ergeben sich die Prioritäten aus der 
Position in der Vektortabelle.

mfg.

von bitte löschen (Gast)


Lesenswert?

Ich bin ja recht neu im Thema, aber mir fällt da spontan eine Message 
Queue ein, um das Auftreten der Interupts mit der Abarbeitung im 
Hauptprogramm zu synchronisieren. Als ich mit Windows-Programmierung 
anfing, gab es noch kein C++ und man schrieb selbst eine WinMain(), die 
neben der Initialisierung nur aus einer Schleife bestand, die per 
GetMessage() Nachrichten von der GDI empfing, und letztendlich an die 
GDI-Funktion DispatchMessage() weiterleitete, die wiederum die Funktion 
WndProc() mit dieser Nachricht als Parameter aufrief.

So etwas ähnliches, nur viel einfacher, könnte man doch selbst 
implementieren. Etwa so:
1
volatile uint8_t nMsgAnzahl;
2
3
WarteNachricht()
4
{
5
 for (;!nMsgAnzahl;)
6
 {
7
   // nichts
8
 }
9
 cli();
10
 --nMsgAnzahl;
11
 // Nachricht aus Fifo holen:
12
 ...
13
 sei();
14
}
15
16
main()
17
{
18
 nMsgAnzahl= 0;
19
 for(;;)
20
 {
21
   int nNachricht = WarteNachricht();
22
   switch (nNachricht)
23
   {
24
     case Blah:
25
       ...
26
       break;
27
     case Hurz:
28
       ...
29
       break;
30
   }
31
 }
32
}
33
34
ISR(Blah)
35
{
36
  // Packe Nachricht Blah in Fifo
37
}
38
39
ISR(Hurz)
40
{
41
  // Packe Nachricht Hurz in Fifo
42
}

Die Interrupts würden in der Reihenfolge ihres Auftretens abgearbeitet 
und das halbwegs flott. Wenn der Fifo überläuft, reicht die Rechenzeit 
insgesamt nicht.

von Roland H. (batchman)


Lesenswert?

Johann L. schrieb:
> Viele µC unterstürten zum Beispiel verschiedene IRQ-Prioritäten, und
> wenn mich nicht alles täuscht gehören auch AVRs (XMEGA) dazu.

Der atxmega A PMIC (Programmable Multi-level Interrupt Controller) 
unterstützt in der Tat drei "Interrupt levels" (neben der Priorisierung 
durch die Adresse); höher priorisierte Interrupts unterbrechen niedriger 
priorisierte.

von Ingo (Gast)


Lesenswert?

Wenn es wirklich zeitkritisch ist, bleibt oft keine Zeit etwas in der 
Main durchgzuführen, dann muss man es in einer ISR durchführen, da diese 
durch einen Timer immer in ein festes Raster fällt. Aber das ist eher 
die Ausnahme. Regler und co müssen sogar immer im selben Zeitraster 
aufgerufen werden.

Ingo

von bitte löschen (Gast)


Lesenswert?

Philipp Klostermann schrieb:
> ISR(Blah)
> {
>   // Packe Nachricht Blah in Fifo
> }
>
> ISR(Hurz)
> {
>   // Packe Nachricht Hurz in Fifo
> }

Ich meinte natürlich:
ISR(Blah)
{
  // Packe Nachricht Blah in Fifo
  ++nMsgAnzahl;
}

ISR(Hurz)
{
  // Packe Nachricht Hurz in Fifo
  ++nMsgAnzahl;
}

von Ein (Gast)


Lesenswert?

Eine Interrupt zu umterbbrechen wird nicht funktionieren weil ...
1
;Nicht so wichtiger Interrupt 
2
   ...
3
   out      sreg,s                ;Statusbits zurücklesen
4
-->
5
   reti                           ;in der Main weitermachen

... was passiert wohl, wenn --> hier unterbrochen wird ?

von bitte löschen (Gast)


Lesenswert?

Ein schrieb:
> Eine Interrupt zu umterbbrechen wird nicht funktionieren weil ...
> ;Nicht so wichtiger Interrupt
>    ...
>    out      sreg,s                ;Statusbits zurücklesen
> -->
>    reti                           ;in der Main weitermachen
>
>
> ... was passiert wohl, wenn --> hier unterbrochen wird ?

Ich verstehe Deinen Einwand nicht.
Die aktuelle Adresse (die, wo das reti steht) wird auf den Stack 
geschmissen, das I-Flag wird gelöscht und der Programmzeiger wird auf 
die andere Interrupt-Routine gesetzt.
Dort wird SREG wieder eingelesen, am Ende rekonstruiert, die 
Rückkehradresse vom Stack geholt und dahin gesprungen. SREG hat sich 
also nicht verändert und das reti mit dem Pfeil davor wird korrekt 
ausgeführt.

von Ralph (Gast)


Lesenswert?

Das sieht wieder mal so aus wie so oft.

Man fängt einfach mal an, ohne ein Konzept zu machen.
Mittendrin merkt man dann das es so nicht geht.
Bastelt dann den Weile herum.

Und dann kommt der Hilferuf ins Forum.


Also :
1. µC zur Seite legen, der hat jetzt erst mal Pause.

2. Überlegen und AUFSCHREIBEN was man machen will.

3. Überlegen und AUFSCHREIBEN wie man es machen will.

4. Aus 2 und 3 ableiten was der µC und die restliche Schaltung können 
muss.

5. Jetzt Datenblätter wälzen und die passenden Bauteile aussuchen ( In 
diesem Fall einen µC der Nested IRQ unterstützt)

6. Gehe zurück zu Schritt 2 und prüfe ob alles noch passt

7. Na jetzt kann man dann so langsam mal den µC wieder in die Hand 
nehmen

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Thomas Eckmann schrieb:
> Johann L. schrieb:
>> Mehrer ISR-Level bzw. Prioritäten zu haben kann durchaus sinnvoll sein.
> Das macht ja auch Sinn. Wenn sie denn einstellbar sind. Das ist beim
> Atmega/tiny aber nicht der Fall. Da ergeben sich die Prioritäten aus der
> Position in der Vektortabelle.

Jein.

Mann kann die niedrigpriore IRQ durch ein __attribute__((interrupt)) 
bedienen lassen und die höherpriore durch ein __attribute__((signal)). 
Dadurch kann die höherpriore die niedrigpriore unterbrechen, aber nicht 
umgekehrt. Die verminder die IRQ-Latenz der höherprioren, was ja Ziel 
der Übung ist.

Und die AVR-Libc zum Beispiel bietet auch den notwendigen Syntax-Zucker 
dafür.

von AVR-freak (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> AVR-freak schrieb im Beitrag #2590643:
>> naja aber wenn ich zb eine PWM habe und im hauptprogramm noch ordentlich
>> zeugs kann ich die nicht in der main machen
> Eine PWM lässt man im Timer laufen. Dann ist es völlig egal, was der
> Rest des Controllers macht.

naja aber der timer (im PWM )erzeugt doch auch interrupts die du 
verarbeiten musst oder seh ich das falsch?^^....

ich sage nicht dass es definitiv so ist aber spontan würde ich 
"behaupten" dass es so wäre

von spess53 (Gast)


Lesenswert?

Hi

>naja aber der timer (im PWM )erzeugt doch auch interrupts die du
>verarbeiten musst oder seh ich das falsch?^^....

Wenn du es erlaubst ja. Aber zur Funktion ist es nicht notwendig.

MfG Spess

von Floh (Gast)


Lesenswert?

AVR-freak schrieb im Beitrag #2590500:
> Hi ich arbeite gerade mit einem atmega8 und muss dabei mit den INTs
>
> spielen und brauiche dafür unterbrechbare ISR.

Zeig doch mal deinen Code und beschreib, was der alles tun soll.

von Thomas E. (thomase)


Lesenswert?

Johann L. schrieb:
> Mann kann die niedrigpriore IRQ durch ein __attribute__((interrupt))
> bedienen lassen und die höherpriore durch ein __attribute__((signal)).
> Dadurch kann die höherpriore die niedrigpriore unterbrechen, aber nicht
> umgekehrt. Die verminder die IRQ-Latenz der höherprioren, was ja Ziel
> der Übung ist.
Wie soll das denn gehen? Das gibt doch die Hardware gar nicht her.

mfg.

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.