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 | 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.
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
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; }
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 ?
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.