Hallo,
ich habe ein paar Fragen grundsätzlich zu Bootloader. eigentlih ist der
Bootlaoder ja ein eigenständiges Programm. Bzw. man muss mit WInAVR ein
eigenes Bootloader Programm schreiben indem man im Makefile die .text
section an die Adresse des Bootloaders verschiebt.
Ich möchte aber gerne in einem Projekt das Hauptprogramm schreiben und
das boot programm. Geht das?
Folgendes habe ich im Makefile hinzugefügt.
LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS)
In meinem Hauptprogramm folgendes
_attribute_ ((section (".bootloader")))
void boot(void) _attribute_ ((section (".bootloader")));
void boot()
{
}
Die Funktion boot soll angesprungen werden um im Bootflash liegen.
Leider bekomme ich beim Linken folgednde Fehlermeldung:
Linking: main.elf
avr-gcc -mmcu=at90can128 -I. -gdwarf-2 -DF_CPU=16000000UL -O0
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wundef -Wa,-adhlns=../ControllerObj/main.o -I../lib
-std=gnu99 -Wundef -MD -MP -MF .dep/main.elf.d ../ControllerObj/main.o
../ControllerObj/comhandler.o ../ControllerObj/adctask.o
../ControllerObj/control.o ../ControllerObj/../lib/uart.o
../ControllerObj/../lib/adc.o ../ControllerObj/../lib/timer.o
../ControllerObj/../lib/can.o ../ControllerObj/../lib/spi.o
../ControllerObj/../lib/bq.o ../ControllerObj/../lib/iic.o --output
main.elf -Wl,-Map=main.map,--cref -Wl,-u,vfprintf -lprintf_flt -lm
-Wl,--section-start=.text=0x1E000
c:/winavr-20080610/bin/../lib/gcc/avr/4.3.0/../../../../avr/bin/ld.exe:
address 0x239c6 of main.elf section .text is not within region text
c:/winavr-20080610/bin/../lib/gcc/avr/4.3.0/../../../../avr/bin/ld.exe:
address 0x239c6 of main.elf section .text is not within region text
make.exe: *** [main.elf] Error 1
micro1 schrieb:
> Die Funktion boot soll angesprungen werden um im Bootflash liegen.
Irgendwie geht das ein wenig am Zweck eines Bootloaders vorbei.
Um den Bootloader zu aktivieren sollte es doch eigentlich reichen, wenn
du einen Reset des Prozessors auslöst. Watchdog auslaufen lassen fällt
mir da als Erstes ein.
Wird der Bootloader aufgerufen, kann man sich sowieso auf nichts mehr
verlassen. Es macht daher auch nicht wirklich Sinn den wie eine Funktion
aufzurufen. Die Funktion kann sowieso nicht vernünftig zurückkehren,
weil sich in der Zwischenzeit das komplette Programm geändert haben
kann.
Doch macht sinn. Ich möchte im laufenden Betreib on einem PC meine AVR
updaten. Danach wird komplett der Strom weggenommen und der Prozessor
startet neu direkt mit dem neuen Programm.
micro1 schrieb:
> Doch macht sinn. Ich möchte im laufenden Betreib on einem PC meine AVR> updaten. Danach wird komplett der Strom weggenommen und der Prozessor> startet neu direkt mit dem neuen Programm.
Das ist die übliche Weise, wie 99% der Bootloader funktionieren.
Dazu wird der alten Applikation ein Kommando geschickt, worauf sie den
Watchdog einschaltet und ne Endlosschleife ausführt.
Der Watchdog startet dann den Bootloader und der startet zum Schluß die
neue Applikation.
Der Bootloader ist also immer ein eigenständiges Programm.
Peter
Ok drücken ih es mal anders aus. Ih möhte im laufenden Programm an die
Bootloader stelle springen da ich ein neues Pogramm auf Flash speiher
will.
Das geht ja nur wenn ich an die Bootloader Adresse springe.
Die Daten Empfange ich über den CAN Bus. Jedoch wird auch über den CAN
gesagt wann neue Programmdaten kommen, also muss ih aus dem laufenden
Programm an die Bootadresse springen damit ih mein Flash ändern kann.
Nun möchte ich aber "normales" Programm und Bootloader Programm in
einem WinAVR Projekt schreiben. Wie sind die Linker einstellungen ?
Habe jetzt
LDFLAGS += -Wl,--section-start=.bootloader=0x1E000
eingetragen. Dies scheint zu funktionieren.
Jetzt werden alle Funktionen die mit
void boot(void) _attribute_ ((section (".bootloader")));
gekennzeichnet sind an diese Adresse gelinkt.
Mal schauen ob dass geht.
micro1 schrieb:
> Ok drücken ih es mal anders aus. Ih möhte im laufenden Programm an die> Bootloader stelle springen da ich ein neues Pogramm auf Flash speiher> will.
Ein Bootloader muss aktiv werden können, sobald der Prozessor einen
Reset durchmacht. Mit allem anderen läufst du Gefahr, dass du dich aus
dem Prozessor aussperrst und erst recht wieder vor Ort gehen/fahren
musst.
Was ist wenn der Prozessor hängt oder du einen Programmfehler hast, so
dass der µC das 'Jump to Bootloader' nicht mehr ausführen kann.
Im schlimmsten Fall muss das hier funktionieren:
Strom weg, Strom an und der Bootloader ist aktiv und wartet eine gewisse
Zeit auf ein neues Programm.
Das du den Bootloader per Programm auslösen kannst ist dann nur noch
eine nette Zugabe. Im einfachsten Fall realisiert man das dadurch, dass
das Programm den Prozessor resettet. zb mit dem Watchdog.
Aber abgesehen davon, weißt du ja wo im Flash der Bootloader sitzt und
kannst dir einen Pointer zurechtcasten über den du die Funktion aufrufen
kannst.
Das ändert aber nichts daran, dass es nicht besonders sinnvoll ist, den
Bootloader als Bestandteil deines Programms aufzufassen. Vor allem auch
deswegen, weil du beim Übertragen eines neues Programms ja nicht den
Bottloader mit übertragen wirst :-)
Was ih dann aber nicht erstehe. Wie flahse ih den AVR das erste mal?
Kann ich erst mit dem AVR Isp mk2 den Bootloader aufspuielen und dann
mit
dem AVR Isp mk2 auch mein Hauptprogramm. Oder Lösche ih dann wieder denn
Bootloader?
micro1 schrieb:
> Was ih dann aber nicht erstehe. Wie flahse ih den AVR das erste mal?> Kann ich erst mit dem AVR Isp mk2 den Bootloader aufspuielen und dann> mit> dem AVR Isp mk2 auch mein Hauptprogramm. Oder Lösche ih dann wieder denn> Bootloader?
Wie das beim AVR Isp mk2 geschieht weiß ich nicht, ich hab diesen
Brenner nicht.
Aber das Prinzip wird genau das Gleiche sein:
* Bootloader in den AVR brennen
* Fuses umstellen, so dass der AVR bei einem Reset als erstes in den
Bootloader verzweigt
* Größe des Bootloaders per Fuse einstellen
* Fuses umstellen, so dass die Bootloader Sektion vor Überschreiben
geschützt wird.
Ab da kannst du dann dein Programm per Brenner einspielen oder aber
gleich den Bootloader benutzen um dein eigentliches Programm
einzuspielen.
micro1 schrieb:
> Was ih dann aber nicht erstehe. Wie flahse ih den AVR das erste mal?> Kann ich erst mit dem AVR Isp mk2 den Bootloader aufspuielen und dann> mit> dem AVR Isp mk2 auch mein Hauptprogramm.
Nein, Du brennst nur den Bootloader.
Und dann die Applikation über den Bootloader, wie ein Update. Damit hast
Du quasi gleich eine Funktionskontrolle des Bootloaders.
Ohne Applikation rauscht der AVR durch die 0xFFFF durch, wieder bis zum
Bootloader. Du bleibst quasi permanent im Bootloader.
Peter
Karl-Heinz und Peter beschreiben das ganz richtig, wie mit dem
Bootloader umgegangen werden sollte. Ich möchte noch eine Anregung
anhängen:
Durch Reset wird der Bootloader angesprungen. Er prüft, ob ein gültiges
Applikationsprogramm vorhanden ist; das geht am sichersten, wenn das
App-Programm eine Prüfsumme enthält, die der Bootloader überprüfen kann;
findet er die Prüfsumme okay, startet er das Programm; andernfalls
wartet er, bis er ein App-Programm zugeführt bekommt, das er flashen
kann. Nach dem Flashen kann er dann ggf. gleich wieder die Prüfsumme
prüfen, das App-Programm starten oder - falls ein Fehler entstand -
erneut das Flashen anfordern.
Günter
Und noch ein Nachtrag: wenn man den Bootloader so ausstattet, daß er
verschiedene Eintrittspunkte hat, kann das App-Programm durchaus zum
Bootloader verzweigen und ihn dazu bewegen, ein App-Programm zum Flashen
anzufordern, obwohl derzeit ein integeres App-Programm geflasht ist
("Flash on Demand"). Das geht m.E. gar nicht anders, wenn der Bootloader
sofort zum Applikationsprogramm verzweigt, wenn eines vorhanden ist und
seine Prüfsumme okay ist (falls man mit dieser Methodik arbeiten
möchte).
Günter