Sollte das nicht in die Abteilung für C?
Sollte das nicht in die Abteilung für C?
Grüße
Thomas
Geändert von ePyx (15.02.2012 um 05:56 Uhr)
Grüße,
Daniel
Es ist zwar richtig, dass der TO die ISR vergessen hat, aber so wie Du das beschreibst funktioniert das in der Regel nicht.
Das Verhalten des Programms würde zufällig werden, wenn ein nicht definierter Interrupt wild im Speicher läuft, deshalb werden alle Interrupts ohne ISR auf einen Fehlervektor umgeleitet, welcher dann selbst wieder auf den Resetvektor umleitet. Der µC bekommt also 'nen SW-reset und das ist der Grund, warum die Init's erneut ausgeführt werden.
Findest Du hier unter default Interrupt:
http://www.rn-wissen.de/index.php/Av...ault_Interrupt
Bei anderen C-Compilern dürfte das nicht viel anders sein.
Kann nur aus meiner Erfahrung heraus antworten und diese lautet, ISR vergessen -> Dauerreset. Was auch recht lustig ist, wenn man durch die uneinheitlichen Bezeichnungen den falschen Interruptvektor nimmt, da man das Programm von einem µC auf einen anderen portiert hat.
Das mit dem reti beruhte auf Halbwissen und habe ich mir aus der Vorstellung eines ASM-Listing zusammengereimt. Was ohne den __default_interrupt__ auch stimmt.
Grüße,
Daniel
Nein, ohne Einbinden eines eigenen Default-Vektors sieht's aus wie unten dargestellt.
Die undefinierten Interruptvektoren gehen standardmäßig auf einen Punkt zusammen, an diesem Punkt würde bei selbst definiertem Bad-Interrupthandler der Weitersprung darauf erfolgen, ansonsten geht's (wie im Listing) auf den Resetvektor. Mit RETI hat das nix zu tun.
Code:L0000: jmp __start ; L002A jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 jmp L0047 ; L002A: ; ... startup code call L0049 jmp L03C5 L0047: jmp L0000 ; main L0049: ; ... L03C5: cli L03C6: rjmp L03C6
Hab nichts anderes geschrieben.
Durch das Einfügen einer rjmp Marke, wird der unter der Marke Code für die ISR abgearbeitet. Zum Schluss wird mit reti doch, zurück an die Stelle PCs die vor dem IRQ bearbeitet wurde, gesprungen. Letztendlich muss der C-Compiler doch Ähnliches erzeugen, denn es muss bzgl. der Funktionalität das Gleiche herauskommen.
Sprich, für mich definiert der ISR-Block den Interrupt-Einsprung und folglich auch den Rücksprung.
Grüße,
Daniel
Konnte (kann) ich so nicht verstehen.
Nein, er muss nichts funktional Ähnliches erzeugen, denn bei einem Fehlen der ISR muss er nicht mehr unbedingt in den unterbrochenen Code zurückkehren. Dann kann direkt (die Bad-Vektor Marke mal ausgeklammert) vom jeweilig Interruptvektor auf den Reset-Vektor gesprungen werden. Das normalerweise ausgeführte RETI der ISR poppt die Rücksprungadresse in den Programmzähler und würde damit den Stack wieder in Ordnung bringen. Wenn's aber per JMP oder RJMP auf den Resetvektor geht, dann wird der Stack in Folge sowieso neu initialisiert und damit muss man darauf nicht mehr darauf achten.Letztendlich muss der C-Compiler doch Ähnliches erzeugen, denn es muss bzgl. der Funktionalität das Gleiche herauskommen.
Weis jetzt nicht, ob wir da aneinander vorbeireden...
Bezeichnest Du mit ISR-Block die Interruptvektortabelle oder die ISR selbst ?Sprich, für mich definiert der ISR-Block den Interrupt-Einsprung und folglich auch den Rücksprung.
Ein Interrupt geht von der Interruptvektortabelle aus, aber er kehrt dorthin nicht mehr zurück, das ist der Unterschied zwischen einem Interruptaufruf und einem CALL/RCALL, bei dem der Rücksprung unmittelbar nach die Caller-Adresse erfolgt.
Lesezeichen