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?
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.
@ 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
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
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.
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?
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...
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.
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.
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.
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.
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
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
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.
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.
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.
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.
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
volatileuint8_tnMsgAnzahl;
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
intnNachricht=WarteNachricht();
22
switch(nNachricht)
23
{
24
caseBlah:
25
...
26
break;
27
caseHurz:
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.
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.
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
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.
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
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.
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
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
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.
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.