Hallo zusammen, ich möchte in meinem Programm für einen Timer (overflow) zwei verschiedene Interruptroutinen durchlaufen. Die Anwahl soll programmgesteuert erfolgen. Aus Gründen der Performance möchte ich die Auswertung / Unterscheidung des Programmteils nicht in der Interruptroutine selbst vornehmen. Ist sowas irgendwie möglich, es gibt ja nur ein "ISR(SIG_OVERFLOW2)" ? Was ich baruche ist "ISR(SIG_OVERFLOW2_A)" und "ISR(SIG_OVERFLOW2_B)" Grüße kritter
Konrad Ritter schrieb: > Hallo zusammen, > > ich möchte in meinem Programm für einen Timer (overflow) zwei > verschiedene Interruptroutinen durchlaufen. Die Anwahl soll > programmgesteuert erfolgen. > > Aus Gründen der Performance möchte ich die Auswertung / Unterscheidung > des Programmteils nicht in der Interruptroutine selbst vornehmen. > > Ist sowas irgendwie möglich, es gibt ja nur ein "ISR(SIG_OVERFLOW2)" ? > > Was ich baruche ist "ISR(SIG_OVERFLOW2_A)" und "ISR(SIG_OVERFLOW2_B)" > > > Grüße kritter Nö.
Switch Case Abfrage gleich zu Beginn. Wie kommst du darauf, dass man einen Interruptvektor doppelt belegen kann?
Doch, das geht. Der Cortex-M3 kann die Adresse seiner Vektortabelle im Programm ändern. Es wäre sicherlich sinnvoll gewesen, anzugeben, dass es sich bei der Frage um eine Frage für den AVR handelt. Dann könnte man höchstens vorschlagen, dass der AVR sich selbst umprogrammiert... Gruß Lasse
Ich dachte mir eigentlich das ich die Vektoren umschalten kann und eventuell einen Vektor benutzen den ich nicht brauche. d.h. bei Interruptereignis wird einmal die normal zuständige ISR für Overflow aufgerufen und ein anderes mal (nach MAnipulation der Vektoren) die ISR für Compare.... Grüße Kritter
Hi >Aus Gründen der Performance möchte ich die Auswertung / Unterscheidung >des Programmteils nicht in der Interruptroutine selbst vornehmen. Welche Performanceeinbuße würdest du denn erwarten? MfG Spess
Kurz gesagt: unmöglich. Auch umprogrammieren im Betrieb geht nicht, da man den Flash nur 10.000 mal umprogrammieren kann. Aber was spricht denn eigentlich gegen 2 zusätzliche Assemblerbefehle in der ISR, mit denen Du die passende Routine anspringst?
Jonathan Strobl schrieb: > Kurz gesagt: unmöglich. Kurz gesagt: falsch. Auch ohne den Flash neu zu beschreiben lassen sich bei den AVRs die Vectoren verlegen. Ist eigentlich für andere Dinge gedacht (speziell Bootloader) aber unmöglich ist das definitiv nicht. Nur ist der Gewinn so minimal, du handelst dir Nebeneffekte und einen relativ großen Implementierungsaufwand ein.
Man könnte auch einen pointer auf eine Funktion nehmen und diesen dann mit der entsprechenden Funktion zuweisen. Da der Compiler aller Register sichern muss, sobald du aus einer ISR eine andere Funktion aufrufst, wird das Ergebnis nicht soviel effizienter sein, als wenn due ein if then else machst. Gruss, Adib.
max schrieb: > Auch ohne den Flash neu zu beschreiben lassen sich bei den AVRs die > Vectoren verlegen. Ist eigentlich für andere Dinge gedacht (speziell > Bootloader) aber unmöglich ist das definitiv nicht. Klingt interessant, wie macht man das? Wusste nicht, dass das geht. Zur Performance: der Gewinn ist wirklich minimal. Das Reinspringen in die ISR dauert sowieso 8 Zyklen, das Rausspringen nochmal 5, macht zusammen 13. Ein bedingter Sprung dauert inclusive Vergleich 3 Zyklen. Wenn du in deiner Anwendung das T-Flag nicht für andere Zwecke brauchen solltest, dann kannst du es für diese "Weichenstellung" verwenden und schaffst den Vergleich in einem Zyklus, wenn nicht gesprungen wird, und in zwei Zyklen, wenn gesprungen wird. Noch ein Tipp: Falls du die nächsthöheren Interruptvektoren nicht benötigst, kannst du den Vergleich an dieser Stelle im Programmcode implementieren und kriegst die Unterscheidung möglicherweise zum Nulltarif.
Markus W. schrieb: > Das Reinspringen in > die ISR dauert sowieso 8 Zyklen, das Rausspringen nochmal 5, macht > zusammen 13. Ich meine reinspringen dauert 4+2 für den Sprung und ein reti kostet auch nur 4 (=10). Ist der COMPA/B interrupt schon belegt? WEnn nicht kann dieser als Overflow genutzt werden.
Markus W. schrieb: > Klingt interessant, wie macht man das? Wusste nicht, dass das geht. Schau im jeweiligen Datenblatt nach IVSEL.
max schrieb: > Schau im jeweiligen Datenblatt nach IVSEL. Danke, wieder was gelernt. Praktisch, aber halt auch eine Fehlerquelle. Ich stimm dir zu, dass es zwar möglich ist, sich aber wohl nicht lohnt. Samuel K. schrieb: > Ich meine reinspringen dauert 4+2 für den Sprung und ein reti kostet > auch nur 4 (=10). OK, ein paar Zyklen hin oder her... :-) Ich hab mich am Datenblatt orientiert: "The interrupt execution response for all the enabled AVR interrupts is five clock cycles minimum. After five clock cycles the program vector address for the actual interrupt handling routine is executed. During these five clock cycle period, the Program Counter is pushed onto the Stack. The vector is normally a jump to the interrupt routine, and this jump takes three clock cycles." --> 5+3 "A return from an interrupt handling routine takes five clock cycles. During these five clock cycles, the Program Counter (three bytes) is popped back from the Stack, the Stack Pointer is incremented by three, and the I-bit in SREG is set." --> 5 Vielleicht bist du von den kleineren AVR-Architekturen ausgegangen. Da gehts etwas schneller, weil RJMP statt JMP benutzt wird.
Bisher hat der TO noch nicht beschrieben, warum eine simple Abfrage und Verzweigung so sehr seinen Zeitrahmen sprengt. Bei mangelnder Phantasie kommt man auch mit dem nächst- besseren Prozessor schnell an die Grenzen! Wahrscheinlich versteht er nur die Maxime "Interrupts sind so kurz wie möglich halten" falsch. Für Programm-Code in der Interrupt-Routine gibts keine engen Grenzen! Wichtig ist nur, dass die Programmierung mit möglichst wenigen Schritten zum Ende (reti) führt! @ max (Gast) Hast du ein Beispiel, wo das funktioniert? Ich kann mir noch nicht so richtig vorstellen, wie die Verlegung aller IRQ-Adressen sinnvoll (speziell bei dieser Frage) eingesetzt wird.
Markus W. schrieb: > Vielleicht bist du von den kleineren AVR-Architekturen ausgegangen. Da > gehts etwas schneller, weil RJMP statt JMP benutzt wird. Stimmt. Ich bin noch nicht auf die Idee gekommen einen >8KB Flash AVR nur in Assembler zu programmieren. Aber jmp kann man auch durch einen Schalter durch den Compiler ersetzen lassen.
Samuel K. schrieb: > Ich bin noch nicht auf die Idee gekommen einen >8KB Flash AVR > nur in Assembler zu programmieren. Stimmt, macht man normalerweise auch nicht. :-) Außer, es kommt wirklich auf jeden Clock Cycle an, dann ist eine Mischung aus C und Assembler gar nicht so verkehrt.
Worum geht es denn hier eigentlich? Mit unbedarfter C-Programmierung Echtzeit-Anwendungen auf den Taktzyklus genau zu programmieren? Gähn! "five clock cycles minimum" ist schon mal schwer zu beherrschen, da das Ereignis mal zu Beginn eines 3- oder 2-cycle-Befehls auftritt, mal in einem 1-cycle-Befehl. Nach dem Rücksprung wird auch erst mal der nächste 1-, 2-, 3-cykle-Befehl ausgeführt, bevor der nächste IRQ bearbeitet wird. Das lässt sich schon im Simulator beobachten ... Aber, träumt weiter!
"Else" ist doch ein ganz passables Mädel. ;-) Um den "Jitter" gering zu halten, kann man in ASM (!) auch noch Ausgleichs-NOPs in den Ablauf bringen, damit die entscheidende Reaktionszeit maximal um die beschriebenen 1 - 3 Clocks variiert.
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.