Hallo, ich bin gerade über einen Bootloader für einen Mega16. Soweit funktioniert alles. Der Bootloader (primitiv, ohne Interrupts) funktioniert und startet auch die normale Applikation. Jetzt will ich aber im Bootloader Interrupts verwenden (Timer, Usart). Die Interrupt-Vektortabelle hab ich in den Bootloader Bereich verschoben, kann ich auch aus dem Map-File lesen. Ohne die globale Interruptfreigabe läuft der Bootloader ganz normal. Das kan nich an einer blinkenden LED erkennen. Wenn ich aber die Interrupts freigebe, scheint es, als ob er beim ersten Timer-Interrupt ins Nirvana läuft (LED-blinkt nicht mehr). Ich habe mich schon durch verschieden Threads hier gelesen, doch leider bekomme ich es dadurch auch nicht zum Laufen. #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #include "main.h" #define FCPU 14745600 #define TIMER_LOAD ((unsigned char) (256 - ((FCPU / 64) * 0.001))) // 1ms-Timer void main(void) { static volatile unsigned int i, j, k; cli(); // Interrupts sperren GICR = 0x01; // Interrupt Vektoren in den Bootloader bereich verschieben GICR = 0x02; TIMSK = (1<<TOIE0); //Timer 0 Overflow Interrupt aktivieren TCNT0 = TIMER_LOAD; //Timer 0 Startwert setzen TCCR0 = 3; //Timer 0 Prescaler = 64 -> Timer Taktfrequenz = FCPU / 64 DDRB = 0x07; PORTB |= 0x07; // sei(); // Interrupts freigeben PORTB &= ~0x02; // LED 2 einschalten while(1) { for(j=0; j<10; j++) // 10 Mal { k = 0; // warten for(i=0; i<50000; i++) k++; if(PORTB & 0x01) // LED 1 toggeln PORTB &= ~0x01; else PORTB |= 0x01; } PORTB |= 0x02; // LED 2 ausschalten k = 0; // warten for(i=0; i<65000; i++) k++; StartApp(); // Applikation starten } } void StartApp(void) { GICR = 0x01; // Interrupt Vektoren ins Flash verschieben GICR = 0x00; asm volatile ("push r1" "\n\t" "push r1" "\n\t" "ret" "\n\t" ::); } SIGNAL(SIG_OVERFLOW0) { PORTB &= ~0x04; // LED 3 einschalten } Kann mir irgendwer Tipps geben? Gruß Manuel
"Problem hat sich erledigt" Diese Antworten liebe ich :-( Wäre es nicht besser, sich nicht als Egoist zu outen ? Wenn Du willst, daß alle sich mit Deinem Problem beschäftigen, dann sollte man doch auch die gefundenen Lösungen öffentlich machen. Peter
Ich hatte im Makefile den Bootloader an eine andere Stelle verschoben als in den Fuses angegeben. So wurde das Programm zwar ausgeführt, als aber dann ein Interrupt ausgelöst wurde landete der Sprung im Nirvana und der Bootloader wurde von vorne ausgeführt. Dadurch war auch kein Blinken der LED mehr zu erkennen. Also: Achtung beim verschieben des Bootloaders im Makefile. Im Makefile werden Byte-Adressen verwendet und bei den Fuses Word-Adressen. Beim mega16 und 1024 Word Bootloader entspricht die Startadresse 0x1C00 (Word) bzw. 0x3800 (Byte). Bei 512 Word Bootloader entspricht die Startadresse 0x1E00 (Word) bzw. 0x3C00 (Byte). Ich hatte die Einstellungen versehentlich vermischt. In den Fuses auf 0x1C00 (Word) und im Makefile auf 0x3C00 (Byte). Gruß mrMR
Hallo! Ich sitze gerade an einem ganz ähnlichen Problem. Und zwar möchte ich auch einen Bootloader im mega16 zu implementieren. Funktioniert soweit ganz gut. Hänge jetzt aber auch an den Interrupts. Ist ja im Prinzip kein großes Problem aber wie sag ich nun dem avr-gcc das er die Interrupt-Sprungtabelle an den Anfang des Bootloaderbereiches schreiben soll? mfg ape
mhmm also hab nochmal ein wenig gesucht und ein beispiel gefunden wo im makefile schon die .text section in den bootloader bereich geschoben wird dann stehen auch interruptvektoren im bootloader bereich aber irgendwie müsste man doch auch 2 tabellen anlegen können eine im application bereich und eine im bootloader...
Erstmal ein wenig "Eigenwerbung": http://www.siwawi.arubi.uni-kl.de/avr_projects/#avrprog_boot Dort findet sich ein Bootloader in avr-gcc fuer den ATmega16. Code und Makefile sind so gestaltet, dass auch fuer den Bootloader eine "Interrupttabelle" erzeugt wird, obwohl dieser Bootloader selbst keine Interrupts nutzt (wuesst auch nicht wirklich warum - aber einerlei). Ist in meinem Code eher eine "parnoia"-Einstellung um sicherzustellen, das nicht irgendein Seiteneffekt aus der Applikation auftritt. Wichtig ist, dem uC mitzuteilen welcher Interruptvektor zu verwenden ist. Nehme an, das ist das Problem. Dazu setzt man IVCE im MCUCR des Mega16. Hierbei ist eine bestimmte "timed sequence" inzuhalten. Erlaeuterungen im Datenblatt, Beispiel im og. Bootloader. HTH, Martin
Hallo, leider läßt sich das Bootprogramm von Martin nicht mit dem AVR-Studio4 debuggen, obwohl Fuse-bit Boot Reset enabled ist. Gruß Ralf
Wenn recht erinnert, gibt es zu "Bootloader simulieren" im Studio4 einige Threads in den avrfreaks.net Foren. Funktioniert wohl nicht so einfach, aber mglw. gibts auch neuere Information in diesen Threads. BTW: warum noch debuggen, bzw. was fehlt dem Bootloader? Martin
Hallo Martin, weil ich ein anderes Bootprogramm benötige, welches in einem Bussystem einzelne Stationen updaten kann. Gruß Ralf
Ah ok, sowas hab' ich auch in Planung, verteiltes "Flash Update ueber RS485". Ist aber noch in den "Kinderschuhen". Viel Erfolg bei dem Projekt. Martin
Hallo, ich bin auch grad auf der Suche nach Informationen betreffend "Flash Update ueber RS485", finde aber keine Möglichkeit a) den Atmega vom Programm aus zu resetten b) vom Programm aus den Bootloader zu starten Könnt ihr mir da helfen?
> ...finde aber keine Möglichkeit > a) den Atmega vom Programm aus zu resetten Einen wirklichen Reset kannst du nur über ein mit /RESET verbundenes Port-Pin oder über den Watchdog erreichen. Falls es dir auf den Zustand der Hardware (IO-Register) nicht ankommt, kannst du natürlich auch einen Sprung zur Adresse 0 ausführen. > b) vom Programm aus den Bootloader zu starten Ein ganz normaler Sprungbefehl, oder was meinst du?
a) Ist klar.. b) Ok, habs grad eben in der AN von Atmel gelesen wie's geht. Dankeschön!
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.