Kann man dem avr-gcc irgendwie z.B. per Parameter beibringen, anstatt des Aufrufs von "bad interrupt" einfach "reti" in die Interrupt Table reinzuschreiben? Standardmäßig wird ja ein Sprung nach 0 gemacht, was einem Reset gleichkommt. Der Hintergrund ist der, dass ich einen Bootloader schreibe. Kommt es nun zu einem Reset und es sind noch Interrupts aktiv (andere als im Bootloader), werden diese natürlich nicht korrekt behandelt und der Bootloader bleibt hängen. Leider habe ich zu wenig Platz, daher wäre es praktisch, einfach diese (je) zwei Bytes für reti direkt in der Interrupt Table zu haben.
Ein Reset löscht alle anstehenden Interrupts. Da kann also nichts mehr kommen.
Ein Sprung nach 0 ist aber kein richtiger Reset. Dann bleibt z.B. auch ADCSRA auf dem alten Wert. Wenn der ADC-Interrupt an ist und auslöst, hat man den Salat.
Ohne Rücksetzen der Interrupt Bedingung wird oft erneut ein Interrupt ausgelöst, Du hast jetzt also eine Endlosschleife (Deadlock) statt einem Reset. Ich würde lieber die Quellen ausschalten, das sind bei AVR normalerweise nicht soo viele.
Herbert schrieb: > Der Hintergrund ist der, dass ich einen Bootloader schreibe. Kommt es > nun zu einem Reset und es sind noch Interrupts aktiv Herbert schrieb: > Ein Sprung nach 0 ist aber kein richtiger Reset. Oben schreibst du reset, hier ist es ein Sprung nach 0. Warum springst du denn nach 0, statt einen richtigen Reset zu machen?
Danke, ich verstehe nicht so ganz, was du damit sagen willst. Momentan ist es so:
1 | ISR(__vector_default, ISR_NAKED) { |
2 | asm volatile ("reti"); |
3 | }
|
Leider verursacht das 2 unnötige Jumps.
Herbert schrieb: > Leider verursacht das 2 unnötige Jumps. Ach Gottchen, fehlen wirklich die 2 Byte Flash?
1 | EMPTY_INTERRUPT(BADISR_vect); |
Herbert schrieb: > Der Sprung nach 0 ist der Default bei nicht definierter ISR. Jetzt versteh ich's dann nicht mehr. Warum aktiviert dein Programm denn Interrupts, für die keine ISRs definiert sind? Du schreibst doch: Herbert schrieb: > Der Hintergrund ist der, dass ich einen Bootloader schreibe. Kommt es > nun zu einem Reset und es sind noch Interrupts aktiv [...] Und nun frage ich mich, was für einen "Reset" du hier meinst. Kommt es zu einem echten Reset, sind danach keine Interrupts mehr aktiv, und das Problem existiert nicht. Wird stattdessen, wie du hier nun sagst, durch eine nicht definierte ISR ein Sprung nach 0 gemacht, dann ergibt sich die Frage, warum dein Programm den entsprechenden Interrupt überhaupt einschaltet.
Viele Interrupts löschen ihr Flag nicht beim Einsprung. Dann läuft mit RETI das Main in Zeitlupe (je 10 Zyklen Interrupt + 1 Zyklus Main).
Sinnvoller wäre es unter diesen Umständen, im Bootloader einfach komplett auf Interrupts zu verzichten und sie per cli abzuschalten. Die Applikation sollte man dann wohl per Watchdog-Reset anspringen, damit sichergestellt ist, dass sie nicht mit Altlasten der vorherigen Applikation kämpfen muss. Ansonsten: mit dem in der Bibliothek mitglieferten crt0.o kannst du es nicht erreichen, die RETIs direkt in die Vektortabelle zu bekommen, aber wenn du das partout willst, hindert dich natürlich niemand daran, dein eigenes Startup-File zu schreiben und linken zu lassen.
Kenne das auch mit Watchdog aktivieren und ner folgenden Endlosschleife ohne Watchdog Reset, schon hast du einen richtigen Reset.
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.