Abend, sitze jetzt schon Tage an dem Bootloader aber leider will das alles nicht so wie ich will ;). Egal was ich auch tue ich hab das gefühl der Bootloader wird nicht nach dem Reset gestartet und die Interrupts funktionieren auch nicht wie sie sollen. Fuses: BootSZ auf 4096Words gestellt laut Datenblatt beginnt mein Bootloader damit bei 0x7000h. BootRST ist ein Haken drinne damit er auch mit dem Bootloader startet. Compiler: Optimization auf (-O0) gestellet also keine Optimierung damit hier nix scheif läuft Linker: Folgende zusatz Argumente für den Linker -Wl,--section-start=.text=0x7000 Hex File danach überprüft sieht gut aus. Auch ein Auslesen des Controllers zeigt das alles richtig geflasht wurde. Code: #include <avr/io.h> #include <stdbool.h> #include <util/delay.h> #include <avr/interrupt.h> //#include "bootloader.h" //#include "uart.h" #ifdef atmega644p #endif uint8_t wait; uint8_t temp; int main() { wait = 0; /* Interrupt Vektoren verbiegen */ char sregtemp = SREG; cli(); temp = MCUCR; MCUCR = temp | (1<<IVCE); MCUCR = temp | (1<<IVSEL); SREG = sregtemp; DDRB = 255; PORTB = 255; _delay_ms(1000); PORTB = ~(1); _delay_ms(1000); TCCR0B |= (1<<CS00) | (1<<CS02); TIMSK0 |= (1<<TOIE0); sei(); _delay_ms(1000); PORTB = ~(2); while(1) { } } ISR(TIMER0_OVF_vect) { wait++; PORTB = ~wait; } Kurzes Programm das einfach nur über ein Timer Interrupt ein paar Leds blicken lassen soll. Problem: 1)Die erste LED geht an sobald der Global Interrupt aktiviert wird und der erste Interrupt kommt fängt das Programm von vorne an. 2)Flashe ich eine andere Aplikation auf Adresse 0 startet das Programm immer von dieser. Egal was ich auch bei dem Fuse BOOTRST einstelle. (Hab natürlich drauf geachtet das ich nicht den Flash lösche wenn ich dsa 2 Programm rein flashe. Beim Auslesen aus dem Controller sieht man auch schön beide Programme) Anmerkung: Flashe ich das ganze an Adresse 0 ohne die Interrupt Vektoren zu verändern läuft alles wie es soll (war ja klar). Jemand eine Idee? Gruß Daniel
Daniel H. schrieb: > Folgende zusatz Argumente für den Linker > -Wl,--section-start=.text=0x7000 Falsche Adresse. Hier ist die Byte-Adresse nötig.
Hi Stefan, äähhhmmm irgendwie steh ich gerade auf dem Schlauch. Wie meinst du das mit Byte-Adresse? 0x7000 gibt doch ein Hex wert an oder? Gruß Daniel
Der Programmspeicher des AVR ist in Words organisiert, daher sind die Adressen im Datenblatt Word-Adressen. Die GCC-Tools sind alle Byte orientiert und erwarten daher eine Byte-Adresse. Falls der Groschen dann immer noch nicht gefallen ist: Rechne mal 0x7000 um in Dezimal und vergleiche das mit der Gesamtgröße des Flash (in Bytes).
Hi Stefan, Ok hab es soweit verstanden also Word-Adress 0x7000 * 2 (2 Byte = 1 Word) komme ich auf Adresse 0xE000 das in Dezimal umgerechnet = 57344. Das macht Sinn. Danke schon mal für den Hinweis. Leider ändert sich an dem verhalten des Prgramm nichts. Es ist jetzt an der richtigen stelle im Flash jedoch brennt immer noch nur 1 LED und das Programm startet von vorne. Gruß Daniel
> Optimization auf (-O0) gestellet also keine Optimierung
Damit wird bei dem hier
1 | MCUCR = temp | (1<<IVCE); |
2 | MCUCR = temp | (1<<IVSEL); |
ganz sicher nicht das erforderliche Timing erreicht. Also sind die Vektoren nicht in den Bootloaderbereich verschoben, und beim ersten Interrupt gibt es einen Crash.
Hi Stefan, das ok das hab ich auch noch geändert und siehe da es geht :). Vielen Dank für die hilfe und ein schönes Wochenende Gruß Daniel PS: hab die Optimierung auf (-O2) jetzt gestellt und es geht.
Inwiefern lohnen sich Interrupts im Bootloader ?
Milli Oschi schrieb: > Inwiefern lohnen sich Interrupts im Bootloader ? Macht die Programmierung komfortabler und ermöglicht es, im Bootloader Strom zu sparen, da nur agiert werden muss, wenn draußen einer klopft ;-). Es gibt noch mehr Gründe Interrupte dem Polling vorzuziehen.
Daniel H. schrieb: > PS: hab die Optimierung auf (-O2) jetzt gestellt und es geht. Die delay routinen und viele libs sind auf -Os optimiert. -O0 verursacht bei mir oft Probleme, mit -O2 wäre ich auch vorsichtig.
Knut Ballhause schrieb: > im Bootloader Strom zu sparen, da nur agiert werden muss Wie funktioniert das? mfg.
Knut schrieb: > Müsste wait nich auch noch volatile sein? Nicht bei dem gezeigten Code. Beim eigentlichen, kompletten Code ... wer weiß, dem Namen nach durchaus möglich.
Thomas Eckmann schrieb: >> im Bootloader Strom zu sparen, da nur agiert werden muss > Wie funktioniert das? Na, der Controller geht in den Sleep, wenn er nichts machen muss. Bei einem aktuellen Projekt braucht mein Bootloader gerade mal 1mA auf einem Mega168 und kann mit 57kBaud Daten über das UART verarbeiten. Der Mega läuft mit 8Mhz intern im Idle und ist blitzschnell aktiv, wenn er muss...
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.