servus! die prioritaeten im atmel sind ja ueber die adresse des jeweiligen interruptvektornamen definiert. kann man diese prioritaeten irgendwie veraendern? des weiteren wird im avr-gcc-tutorial und auch im avr-libc-user-manual davon abgeraten interrupt-nesting zu benutzen, dass ich also weitere interrupts aufrufen kann, waehrend ich gerade in einer ISR bin. wie ist das? benutzt man das wirklich nicht? problematischerweise wird ja beim eintritt in einen interrpt das globale IR-flag zurueckgesetzt. das muss ich nun in der ISR wieder setzen, um nesting zu aktivieren. dabei kann mir aber der eine oder andere hoeherpriorisierte interrupt rausgehen, wenn dieser direkt zwischen ruecksetzen und setzen des globalen bits aufgerufen wird. wie wird das also beim atmel gehandhabt? Esco
Interrupt-Prioritäten gibt es bei den AVRs nicht wirklich. Die Priorität gilt nur für gleichzeitig auftretende Interrupts. Während der Abarbeitung der ISR ist das I-Flag deaktiviert, damit kein anderer Interrupt dazwischen funkt. Setzt man das I-Flag von Hand, dann muss man sicherstellen, dass keine Konflikte entstehen. Dies wird schwierig, wenn mehr als zwei Interrupts genutzt werden. Deshalb sollte man lieber die ISRs so kurz wie möglich halten und auf die Interrupt-Freigabe im Interrupt verzichten. ...
aha. ja wie macht man das normalerweise? also ich moechte gerne alles in ISRs abarbeiten. dabei moechte ich mich auf sehr kurze ISRs beschraenken und die eigentliche arbeit dann in 3 timerinterrupts machen lassen. ich habe dann 3 timer (eigentlich 4, aber einer faellt wegen der vorgegebenen priorisierung leider weg...) die alles abarbeiten: 120 µs, 1ms und 500ms. der 120 µs-task hat dann die hoechste prioritaet und interruptet immer die beiden anderen. wobei der 1ms-task dann noch den 500ms-task interrupten kann (sonst wuerden die ja nie aufgerufen werden). oder wie handhabt ihr das, dass dann auch alles zum richtigen zeitpunkt abgearbeitet wird und das dann noch mit unterschiedlichen aufruffrequenzen? ich moechte das ganze gerne ohne "real-time"-os machen. Esco
Also ich kann nur für ASM sprechen. Ich richte mir meist ein Register mit Boolschen Variablen (Flags) ein, setze in der ISR das entsprechende "Jobflag" und frage in der Mainloop die Jobflags der Reihe nach ab. Ist eins gesetzt, wird die entsprechende Routine ausgeführt und das Jobflag gelöscht. Die Timer-ISR mit der schnellsten Aufrufzeit kann ihre Arbeit dann selbst machen, somit schafft sie ihre Arbeit auch bei längeren Mainloop-Jobs. Einige Beispiele in ASM mit kleineren AVRs (der 128er kann ich nicht löten) findest du auf www.hanneslux.de/avr/ , wobei da auch nicht alles optimal ist. Ein Beispiel mit Int-Freigabe im Int ist auch dabei, und zwar der Tiny15-Fahrtregler im Modellbaubereich. ...
>sonst wuerden die ja nie aufgerufen werden Grundsätzlich gilt bei den AVRs: Wenn eine ISR aufgerufen wird, wird das I-Flag gelöscht. Dann wird die ISR abgearbeitet und beim Rücksprung ins Hauptprogramm wird automatisch das I-Flag wieder gesetzt. Wenn in der Zwischenzeit (also während der Abarbeitung der ISR) ein Interrupt-Ereignis von einer anderen Quelle auftritt, wird das dazugehörige Interrupt-Flag gesetzt. Nach dem Rücksprung aus der o.g. ISR wird zunächst mindestens ein Befehl im Hauptprogramm ausgeführt und dann die zu dem zwischenzeitlich aufgetretenen Interrupt gehörende ISR aufgerufen. Dann gilt das selbe wie oben. Es geht normalerweise kein Interrupt verloren, es sei denn, eine ISR dauert zu lange und während diese abgearbeitet wird treten mehrere Interrupts von der anderen Quelle auf. Dann wird nach dem Rücksprung nur einmal die entsprechende ISR aufgerufen, alle anderen Ereignisse gehen verloren. Nested Interrupts sind gerade dann gefährlich, wenn Interrupts in sehr kleinen Abständen kommen, da es dann zu einem Stack Overflow kommen kann. Deshalb sollte man sie vermeiden, wo es nur geht. Die Methode, die Hannes anführt (mit Jobflags und Bearbeitung von Aktionen, die nicht zu zeitkritisch sind, im Hauptprogramm) ist sicherlich für die meisten Anwendungen die beste. Ich selbst habe damit bisher nie Probleme gehabt. Bei Deiner 120µs-Interrupt-Geschichte musst Du natürlich darauf achten, dass die dazugehörende ISR wesentlich weniger als 120µs in Anspruch nimmt, sonst geht wirklich was verloren. Gruß Johnny
Mach nur ein Interrupt mit dem größten gemeinsamen Teiler (oder wie nennt man das Ding doch gleich?); hier 40 µs. Der prüft zunächst, ob die 120 µs-Routine fällig ist, anschließend, ob die 1 ms dran ist und zum Schluß der 500 ms-Job.
ja, dann ist aber das problem, dass man keine langen jobs mehr durchfuehren kann. desweiteren hab ich dann keine echtzeit mehr fuer die ganzen tasks. bei der 4-timer-loesung hast du ja zumindest echtzeitgarantie fuer alle aufrufe. der niederste job wird dann garantiert in echtzeit abgearbeitet. und man kann dann ohne grossen aufwand ausrechnen, wie lange welcher job braucht und weiss ganz genau, wann welcher job aufgerufen wird, und wann er beendet ist. Esco
"der niederste job wird dann garantiert in echtzeit abgearbeitet." OhGottogottogottogott ! Nochmal gaaanz laaangsam zum Mitschreiben, der AVR hat keine Prioritäten ! Wenn der langsamste Interrupt 121µs dauert, dann kannst Du Dir den 120µs Timerinterrupt sonstwohin stecken, der geht definitiv ab und zu verloren. Peter
@all da versteht Mann gar nicht warum alle Atmel HURA schreien !!!! Kopfschüttel.....
Wo ist eigentlich das Problem? Jedes Teil hat seine Grenzen. Bei halbwegs vernünftigem Programmierstil leisten die AVRs schon allerhand. ...
Hi, beim AVR bleibt nur eine Implementierung per Software mit einigen kompromissen. Hannes > Ich richte mir meist ein Register mit Boolschen Variablen (Flags) > ein,setze in der ISR das entsprechende "Jobflag" und frage in der > Mainloop die Jobflags der Reihe nach ab. Ist eins gesetzt, wird die > entsprechende Routine ausgeführt und das Jobflag gelöscht. > Die Timer-ISR mit der schnellsten Aufrufzeit kann ihre Arbeit dann > selbst machen, somit schafft sie ihre Arbeit auch bei längeren > Mainloop-Jobs. Ich mache es genauso. Ich deklariere mich eine Variable (uchar,uint) und setze in der ISR entsprechende Flag's fuer eine state maschine. Leider klappt es nicht mit zeitkritischen Sachen wie Software PWM oder hat jemand nen Tipp? Sollte ich die Zeitkritischen Sachen mit in die ISR nehmen und in der ISR die State Maschine mit Informationen versorgen? stephan >da versteht Mann gar nicht warum alle Atmel HURA schreien !!!! >Kopfschüttel..... Es zwingt niemanden die AVR's zunutzen. Bei entsprechenden Anforderungen sollte man sich den passenden µC aussuchen. Ein Mikrocontroller mit NMI waere hier wohl recht hilfreich. Gruß, Dirk
> Leider klappt es nicht mit zeitkritischen Sachen wie Software PWM > oder hat jemand nen Tipp? Software-PWM frisst wirklich Ressourcen, da kommt es auf jeden Takt in der ISR an. Soft-PWM hatte ich dann voll in die Timer-ISR gelegt. Dazu gab's exklusiv-Register für die ISR, um die Registersicherei einzusparen. Bei der Bezeichnung "State-Machine" oder "Zustandsautomat" halte ich mich zurück. Ich vermute zwar, das mein Programmierstil etwas in diese Richtung geht, kenne (verstehe) aber die genaue Definition nicht. Das, was ich dieser Tage über Zustandsautomaten gelesen habe, passt irgendwie noch nicht so richtig in meinen Kopf. Die Theorie ist mir da etwas zu abstrakt. ...
Hi, Hannes: >Software-PWM frisst wirklich Ressourcen, da kommt es auf jeden Takt >in der ISR an. Soft-PWM hatte ich dann voll in die Timer-ISR gelegt. >Dazu gab's exklusiv-Register für die ISR, um die Registersicherei >einzusparen. Ok, das mit den exklusiv Register wusste ich bis jetzt nicht und ehrlich gesagt dauert das push / pop laenger als die isr. >Bei der Bezeichnung "State-Machine" oder "Zustandsautomat" halte >ich mich zurück. Ich vermute zwar, das mein Programmierstil etwas in >diese Richtung geht, kenne (verstehe) aber die genaue Definition >nicht. Da schliesse ich mich an ;) Gruß, Dirk
Hi, Hannes: Hattest du ein kleines Beispiel mit den exklusiv Registern ? Ich werde ehrlich gesagt nicht wirklich schlau aus der AVR LIBC in diesem Bereich. Gruß, Dirk
> Hattest du ein kleines Beispiel mit den exklusiv Registern ? > > Ich werde ehrlich gesagt nicht wirklich schlau aus der AVR LIBC in > diesem Bereich. Ich auch nicht, denn ich versuche es gar nicht erst, da ich in Assembler programmiere. Und wenn ich da Register ausschließlich für die ISR reserviere (und in der Mainloop nicht anrühre), dann nenne ich das exklusive Nutzung der Register. Die Reservierung erfolgt dann aber in meinem Kopf und nicht in irgendwelchen Compiler-Anweisungen. So kann man aneinander vorbei reden... ;-) ...
@Dirk, aha kommt vom Z80. Na NMI hilft auch nicht immer. Heist ja nur das der Int kommt und die Quelle erst ermittelt werden muß. Deswegen ja NMI ( Nicht Maskiert I..) Was fehlt ist eine Funktion zum sortieren der "Anforderungen". Geht ja um Prioritäten. Da helfen wirklich nur Hilfsflags um die Interruptpriotitätenlogik anderer MCU´s zu Fuß nachzuerfinden. Leider !!! Wobei ich persönlich glaube das sich die meisten Sachen warscheinlich auch ohne eine "Single Cycle" MCU bewerkstelligen lassen würden. Und dann hat man diesbezüglich weniger den Kopf voll. Ist aber meine ganz pers. Meinung.
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.