-
        

Ergebnis 1 bis 10 von 10

Thema: Usart interrupt Atmega8 prioritat

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    61
    Beiträge
    531

    Usart interrupt Atmega8 prioritat

    Anzeige

    Hallo,

    Es handelt sich um Atmega8.

    innerhalb main() wird ein Warteschleife Funktion angerufen.

    Die Funktion ist etwas wie:

    for(i=0;i<1000;i++){
    for(j=0;j<1000;j++){
    }
    }

    Wenn wahrend die Warteschleife ein usart von aussen angesteurt wird, wird kein usart interrupt aktiviert. Wenn die Warteschleiffe beendet ist da erscheint in die usart-interrupt funktion ein usart overrun error.
    Die usart interrupt funktion funktioniert sonst normal.

    Ich dachte die usart wird auch ein Warteschleiff unterbrechen, oder irre ich mich hier?

    Gruss

    Henk

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Ja klaro. Einer IRQ ist es egal, wie dein Programm aussieht. IRQs müssen natürlich global aktiviert sein ein der betreffende IRQ muss zugelassen sein.
    Disclaimer: none. Sue me.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    61
    Beiträge
    531
    Jetzt hab ich die ursache gefunden.
    Die Warteschleiffe wird ausgefuhrt innerhalb eine interrupt function.
    Im Atmega pdf steht dass warend die ausfuhrung eines interrupt die globalen interrupt immer 'disabled' ist!

    Ich habe immer (offensichtlich fals) gedacht dass ein interrupt mit eine hoheren prioritat ein anderes interrupt mit niedrigen prioritat interuppieren konnte....

    Jetzt denke ich dass, wenn wahrend die ausfuhrung von interrupt A sich zwei andere interrupts B und C sich melden, nachdem interrupt A fertig ist die interrupt B oder C, derjenige der die hochste prioritat besitzt, zuerst ausgefuhrt wird.

    Hat mich schon wieder manche Stunde gekostet das heraus zu finden...

    Gruss

    Henk

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Jau, genauso ist das mit A, B, und C

    Falls eine ISR durch eine andere IRQ unterbrochen werden sollte, kann man einfach an den Anfang der ISR ein sei() schreiben.

    Noch einfacher deklariert man die ISR (avr-gcc 3.x) mit INTERRUPT() anstatt mit SIGNAL(), und avr-gcc mache den passenden Code. Ist auch in GCC erklärt.
    Disclaimer: none. Sue me.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    61
    Beiträge
    531
    Aha,

    also, jetzt ist mir ganz klar wie INTTERUPT() und SIGNAL() funktionieren und was die unterschied ist.

    Schon wieder etwas gelernt!

    Danke

    Gruss

    Henk

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    50
    Beiträge
    1.195
    Die Namen sind auch missverständlich.

    Bei SIGNAL sind die Interrupts während der Ausführung deaktiviert (Implizites cli() am Anfang der Interrupt Routine.

    Bei INTERRUPT bleiben die Interrupts aktiviert. Eine INTERRUPT-Routine kann also von weiteren Interrupts unterbrochen werden. Da das schnell zu einem Stacküberlauf führen kann, sollten INTERRUPTS wenn möglich vermieden und ansonsten sehr vorsichtig eingesetzt werden.

    BTW, in den neuen Versionen des avr-gcc ist die Benennung geändert worden. Aus SIGNAL wurde ISR (was IMHO dem Sinn viel näher kommt).

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    61
    Beiträge
    531
    Ich mochte noch dazu bemerken:

    SIGNAL:
    ist die normale weise wie die Atmega8 hardwaremassig funktioniert.
    INTERRUPT
    ist (fur Atmega) die weise da braucht die programmierer (oder compiler) die sei() instruction selber zu zu fugen innerhald eine ISR.

    Ich hatte ein grosseres project gemacht mit einen Philips microcontroller der hardwaremassig wie 'INTERUPT' functionierte und nicht wie 'SIGNAL'.

    Deswegen war ich mit dem Atmega auf dem falschen Spur gefahren.

    Gruss

    Henk

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    INTERRUPT ist vor allem dann zweckmässig, wenn manche ISRs eine kleine Interrupt-Respond-Time haben müssen und andere ISRs vergleichsweise komplex sind und lange dauern.

    Dann macht man die lange ISR unterbrechbar und die kurzen, schnell abzuarbeitenden als normale SIGNAL().

    Abstürzen tut da nix. Ein fehlerhaftes Programm nur mit SIGNAL() schmiert genauso ab

    In der 4er Version scheint es kein Analogon zu INTERRUPT zu geben, da muss man selber mit den Attributen rumhudeln.

    Übrigens ist
    SIGNAL (...)
    {
    sei();
    ...
    }

    NICHT gleichbedeitend mit

    INTERRUPT (...)
    {
    ...
    }

    Letzteres führt zu teilweise deutlich kleineren Response-Zeiten, weil das sei schon am Anfang des ISR-Prologs eingefügt wird!

    Ein cli() am Ende der ISR braucht man übrigens nicht. SREG steht ja aufm Stack.
    Disclaimer: none. Sue me.

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    50
    Beiträge
    1.195
    Abstürzen tut da nix. Ein fehlerhaftes Programm nur mit SIGNAL() schmiert genauso ab
    Deswegen steht da oben ja auch der Konjunktiv

    Lange ISRs sind ja sowieso Pfui (auch wenn sie sich manchmal vielleicht nicht vermeiden lassen) - und was lang ist, ist ja relativ.

    Ich finde die Änderung von SIGNAL nach ISR allerdings sehr sinnvoll. Viele Einsteiger haben SIGNAL und INTERRUPT genau anders herum verstanden.

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Ich find's eher nervig, wenn sich dauernd die API ändert: andere Makro-Namen, Dateinamen, Vektor-Namen...

    Wer die Doku zu SIGNAL() nicht gelesen hat, tut es wohl auch nicht, wenn das Ding plötzlich ISR() heisst und der Kaiser neue Kleider anhat.

    Lange ISR sollte man vermeiden -- vor allem dann, wenn darin nix weiter getan wird, als zu warten, also im Endeffekt NIX zu tun. Kategorisch oder dogmatisch braucht es aber nicht zu sein...

    Man kann sein Programm zB so auslegen, daß es 3 Prioritätsstufen hat:
    -- die unterste Ebene (normale Ausführungsebene)
    -- mittlere Ebene: In einem INTERRUPT, der auch recht ausgewachsen sein darf
    -- höchste Ebene: Typischerweise kurze Schnittstellen- und Interrupt-Bedienungen mit SIGNAL()

    Den Code aus der mittleren Ebene auf die untere zu ziehen, kann sehr umständlich sein und das Programm schnell undurchschaubar machen. Zudem kommen lästige Synchronisierungen hinzu. Ausserdem verliert man dadurch Echtzeitigkeit, weil sich Code auf Ebene 1 nicht selbst unterbrachen kann. Macht man auf unterer Ebene nen unwichtigen Job und ist zB ne Zeit um, an der man was komplexes zu machen hat, wird's schnell ätzend. Man müsste dan ständig nachschauen, ab's an der Zeit ist, den Cron-Job zu erledigen, ihn gegebenenfalls ausführen und danach die Arbeit wieder aufnehmen.

    Mit einer mittelprioren Zwischenschicht steht die Sache jedoch ganz gut da.
    Disclaimer: none. Sue me.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •