Ist es beim AVR möglich aus der Applicationarea den Bootloader zu
überschreiben (entsprechende Lockbits vorausgesetzt)
Soweit ich das Datenblatt verstehe muss flashender Code immer in der
NRWW sektion sein und der Bootloader befindet sich auf jeden Fall in der
NRWW sektion.
Nicht in jedem Fall befindet sich der Bootloader in der NRWW Sektion,
das hängt von Dir ab. Es ist aber möglich, den Bootloader vom
Applikationsprogramm her zu überschreiben, deswegen sollten die Lockbits
auch so gesetzt sein, daß sie dies verbieten. Egal wohin Du nun
Bootloader oder Programm schreibst, mußt Du die Lockbits so setzen, daß
im Zweifelsfall wenigstens der Bootloader heile bleibt, sonst hast Du
ein Problem.
..wenigstens der Bootloader heile bleibt, sonst hast Du ein Problem.
Ich will gerade dieses Problem haben ;-)
was muss ich dafür tun, das mein applicationscode der den Bootloader
überschreiben soll in der NRWW Sektion ist und dies darf?
Ihn dort ´reinschreiben und keines der Lockbits setzen ?! Komisch, ich
dachte immer, daß der Bootloader der letzte Strohhalm bleiben sollte,
aber wenn Du ihn Dir absägen willst, warum nicht? Am Controller soll´s
nicht scheitern ;-)
Travel Rec. wrote:
> Es ist aber möglich, den Bootloader vom> Applikationsprogramm her zu überschreiben
Nein, das ist in der Regel nicht möglich. Die Programmierroutinen müssen
in der Bootsektion sein. Steht zumindest so im Datenblatt.
Um von der Applikation her den Flash zu ändern, muß man eine
API-Funktion im Bootbereich haben, die dann die Applikation aufruft und
im SRAM die zu schreibenden Daten übergibt.
Ausnahme sind nur die AVRs mit kleinem Flash, die keine getrennten
Sektionen haben, z.B. der ATmega48 ist so einer.
Peter
Stand jemand schon einmal vor dem Problem, einen Bootloader per RS232
updaten zu müssen und hat dafür einen gangbaren Weg gefunden?
Wir müssen ein Update für eine Firmware durchführen, die jetzt einen
Watchdog verwendet, der bislang verwendete Bootloader ist aber nicht
"watchdog-sensitiv", was zu Problemen führt, da der Watchdog nach dem
Auslösen ja aktiv bleibt. Eine kleine Änderung im Bootloader behebt das
Problem, aber alle bereits ausgelieferten Geräte per ISP upzudaten ist
nicht machbar.
Nach viel Rumsuchen habe ich mir folgendes überlegt:
-Mit dem Bootloader einfach einen anderen Bootloader aufspielen, geht
sicher schief, da sich ja die Schreibroutine irgendwann selbst
überspielt.
-Mit dem Bootloader den gleichen Bootloader einfach noch mal
aufzuspielen, sollte ja eigentlich funktionieren, da der Bootloader
während des Schreibvorgangs in einem konsistenten Zustand bleibt.
-Falls man nun den Bootloader ansonsten unverändert lässt und nur die
erste Instruktion durch einen Jump hinter das Ende des bisherigen Codes
ersetzt, dort den Watchdog deaktiviert, die durch den Jump
überschriebene Instruktion ausführt und zurückspringt, sollte die
Konsistenz erhalten bleiben und ein "Update" durchführbar sein.
Übersehe ich dabei etwas Entscheidendes?
Oder besteht doch eine Möglichkeit, dem Watchdog beizubringen, nach
Auslösen des Resets nicht mehr aktiv zu sein, die mir entgangen ist?
Viele Grüße
Johannes
Johannes schrieb:> -Mit dem Bootloader den gleichen Bootloader einfach noch mal> aufzuspielen, sollte ja eigentlich funktionieren, da der Bootloader> während des Schreibvorgangs in einem konsistenten Zustand bleibt.
Nein, bleibt er nicht.
Vor dem Programmieren mußt Du eine Page löschen, d.h. Du wirst
irgendwann die Page löschen, in der die Programmierbefehle stehen und
das wars dann.
Bei älteren DOS war es möglich "format C:" von C zu starten. Und danach
guckt die Command.com verdutzt auf die blanke Platte und kann sich nicht
mehr nachladen.
Willst Du solche Spielchen machen, mußt Du Dir das vorher überlegen.
Der Bootloader muß dann aus 3 Teilen bestehen. Einem Masterloader, der
überprüft, ob ein Slaveloader eine gültige Signatur und CRC hat und
diesen dann ausführt. Und mindestens 2 Adreßbereiche für 2 Slaveloader,
die sich dann gegenseitig überschreiben dürfen.
Peter
moment, moment, das ginge schon ...
Ihr schreibt einen bootloader, der hinter dem vorhandenen im Flash
liegt,
schriebt eine Aplikation, die diesen beim Start anspringt, mit dem
Zweitloader ladet Ihr eine komplette Firmware inklusive des neuen
Erst-Bootloader ...
Ist etwas durchs Knie ins Auge, aber geht.
Der Knackpunkt ist der vorhandene Bootloader, das ganze geht nur, wenn
Ihr nicht nur die Inhalte, sondern auch die Adresse mit übertragt und
auch benutzt fürs SPM ...
Fhutdhb Ufzjjuz schrieb:> Ihr schreibt einen bootloader, der hinter dem vorhandenen im Flash> liegt,
Schreiben kannst Du sowas, bloß wie kriegst Du es programmiert?
Ein Bootloader, der nicht dafür vorbereitet ist, wird ein Schreiben in
die Bootsektion abweisen. Und außerdem muß hinter ihm noch Platz sein
(mindestens ein Page).
Und außerdem dürfen die Bootloaderlockbits nicht gesetzt sein.
Und wie Du schon sagst, er muß ein Schreiben mit Lücken zulassen, um
sich selbst zu überspringen.
Peter
>Wir müssen ein Update für eine Firmware durchführen, die jetzt einen>Watchdog verwendet, der bislang verwendete Bootloader ist aber nicht>"watchdog-sensitiv", was zu Problemen führt, da der Watchdog nach dem>Auslösen ja aktiv bleibt.
Ihr habt bis jetzt keinen Watchdog benutzt und habt den Bootloader
anders getriggert als durch einen Wadtchdog Reset ?
Wenn ja dann könnt ihr doch einfach den Watchdog vor dem Triggern (oder
nach dem Triggern )abschalten. Natürlich mit einen Frimwareupdate und
nicht des Bootloaders.
Wenn ihr aber den Watchdog zum aktivieren des Bootloaders braucht, ihr
vorher noch nie ein Firmwareupdate gemacht habt und jetzt feststellt das
der Bootloader nicht Watchdogresistent ist, habt ihr ein echtes Problem.
Denn dann könnt ihr die Firmware nicht updaten und den Watchdog vorher
abschalten.
Es gibt eine Möglichkeit in den Bootloader zu springen ohne einen Reset
durchzuführen:
in C:
1. Prozedur Starte_Bootloader deklarieren als Pointer auf die Adresse
des Bootloaders (man muss die korrekte Bootloader-Adresse eintragen, die
kann abweichen, da die Bootloader-Sektion je nach eingestellten
Fuse-Bits unterschiedlich groß ist, bei mir lautet die Adresse 0x3C00)
1
void(*Starte_Bootloader)(void)=(void*)0x3C00;// hier richtige
2
//Bootloader-Adresse eintragen
2.
im Hauptprogramm ggf. alle Interrupts und den Watchdog abschalten
3.
danach Prozedur aufrufen: