Forum: Compiler & IDEs Bootloader und app gleichzeitig in schreiben


von micro1 (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von micro1 (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von micro1 (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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 :-)

von micro1 (Gast)


Lesenswert?

Ach ja stimmt. Ich muss Bootloader und Programm
trennen hast ja recht.

von micro1 (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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.

von micro1 (Gast)


Lesenswert?

Ah. Jetzt wird einiges klar. Gibt es eigentlich irgendwo ein gutes 
Tutorial über Bootloader AVR?

von Peter D. (peda)


Lesenswert?

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

von Günter R. (galileo14)


Lesenswert?

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

von Günter R. (galileo14)


Lesenswert?

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

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
Noch kein Account? Hier anmelden.