Forum: Mikrocontroller und Digitale Elektronik AVR Bootloader selber schreiben, suche Infos...


von JaM (Gast)


Lesenswert?

Servus!

Es geht um das Thema AVR (in meinem Fall ein atmega16) und Bootloader.
Ich möchte meinen MC in Zukunft über UART mithilfe eines Bootloaders
flashen. Zu diesem Zweck gibt es ja schon so einiges im Netz
(angeschaut habe ich mir Peter's Bootloader, und MegaLoad).

Ich würde aber meinen Bootloader sehr gerne selber schreiben (nur so
lernt man was), und suche dazu einige anfängertaugliche Informationen.
Im Manual steht zwar schon einiges, aber eben nicht anfängertauglich.
Gibt es so etwas wie ein Bootloader-Tutorial?
Und vorallem, wie's mit AVR-GCC geht?

Danke!
lg,
JaM

von Christian (Gast)


Lesenswert?

Sers JaM,


Du scheinst genauso ein Optimist wie ich zu sein ...
Ich habe es mittlerweile Drann gegeben ...

Vorstellen könnte ich mir das so:

ATMega wird initialisiert und beginnt bei 0x0 zu arbeiten,
ein paar Sekunden auf bestimmtes Command vom UART warten falls da was
kommt, Daten in den EEPROM Schreiben (nach dem Loader natürlich ;-) )
...

Falls nix kommt, an adresse des geflashten codes springen ...

Aber ob Du da mit Plain C weit kommst weiß ich nicht ...

Lg


Christian

von JaM (Gast)


Lesenswert?

Sers Christian,
naja, es sieht so aus, dass ich schon ein wenig über die Funktionsweise
des Bootloaders weiß. Wie er angesprungen wird, das er den Reset nach
0x0000 vornimmt etc.
Was ich eben noch nicht verstanden habe, ist die Sache mit dem Paging,
ein gewisser Z-Pointer? Allgemein, der Zugriff auf den Prog-Flash, und
die ganzen Register, die damit auch involviert sind. Natürlich werden
die alle schön brav im Manual aufgelistet, aber da wird man einfach mit
Infos überrollt, ich hab mein Problem damit, ganz grob zu erkennen, was
wie eingestellt werden muss.

lg,
JaM

von Daniel B. (khani)


Lesenswert?

Hallo JaM,

ich bin im Moment auf dem selben Ast gelandet - für mein Projekt muss
ich das wohl oder übel machen, denn ich habe beim Programmieren über
SPI beim ATmega32 gewisse Probleme mit meiner Peripherie (außerdem ist
das viel sexier, wenn man einen Bootloader hat).

Ich habe mir mal die AppNotes 109 und 911 runtergeladen. Der Vorteil
der 911er Appnote ist, dass man die PC-Seite schon praktischerweise
erschlagen hat. In der 109er AppNote ist das mit den Seiten und SPM,
LPM ganz gut beschrieben. Dazu gibt's dann noch einen IAR-Quellcode.
Ich habe keinen IAR und habe deswegen alle auf gcc portiert (also
lauter eigene Funktionen). Das Problem ist, dass es jetzt nicht
funktioniert ;-).
Lesen kann ich mittlerweile vom AVR mit dem AVROSP (AppNote 911). Nur
schreiben kann ich noch nicht. Es dürfte eigentlich keinen
prinzipiellen Unterschied machen, oob man den ATmeag32 oder ATmega16
verwendet. Wir könnten uns also bei Bedarf mal austauschen (Quälcode
:-), Verständnis usw.)

MfG, Daniel

von André K. (andre-)


Lesenswert?

Das versuche ich auch seit einer ganzen Weile, allerdings komplett in
Asm. Mein Ziel ist es, einen Mega88 ueber BT updaten zu koennen. Bei
allen BLs, die ich bisher getestet habe, ist das genaue Timing so
problematisch, dass die Verzoegerungen, die bei der Uebertragung von BT
entstehen, einfach zu gross sind und das ganze nicht funktioniert. Mein
groesstes Problem sind diese ganzen Teile, in die der Flash geteilt
ist, zB RWW und NRWW. Das kann ich mir im Datenblatt 10mal durchlesen.
Ich versteh nicht, was das ueberhaupt bewirken soll und gleich gar
nicht, wozu es gut sein soll.

MfG

von Michael (Gast)


Lesenswert?

Guck doch mal unter:
http://lists.gnu.org/archive/html/avr-gcc-list/2003-08/msg00265.html
Es ist ein X-Modem-Bootloader (Das X-Modem-Protokoll kann selbst
Hyperterminal, was bei Windows inklusive ist.)

Zum Verstehen des Bootloaders braucht man aber auch
Hintergrundwissen...

Michael

von JaM (Gast)


Lesenswert?

@Daniel:
Ich steh gerade aufm Schlauch: Wo kann ich diese AppNotes runterladen?
Und Stichwort Sexier: Auf jeden Fall, ein Bootloader ist einfach das
non-plus-ultra... :D

@André:
Gerade das mit dem RWW und NRWW verstehe ich auch nicht... wenn sich da
mal ein "Wissender" zu äußern könnte...

lg,
JaM

von JaM (Gast)


Lesenswert?

Nachtrag: Hab die AppNotes auf der atmel-Seite doch noch gefunden... :)

lg,
JaM

von Peter D. (peda)


Lesenswert?

"Bei allen BLs, die ich bisher getestet habe, ist das genaue Timing so
problematisch, dass die Verzoegerungen, die bei der Uebertragung von
BT
entstehen, einfach zu gross sind und das ganze nicht funktioniert."

Wie kommst Du denn darauf ???

Die SPM-Instruktionen sind zeitgeschützt, d.h. sie müssen innerhalb 4
Zyklen nach Laden von SPMCSR erfolgen.

Ansonsten gibt es nicht die geringsten Timing-Einschränkungen, Du
kannst auch nur ein Byte pro Tag senden, wenns Dir denn Spaß macht.

Das einzige, was taktabhängig ist, ist die Baudrateneinstellung bei
Verwendung der UART.


Ich habe meinen Bootloader auch nur anhand des Datenblattes
geschrieben, da sind doch sogar Beispiele drin. Besser als im
Datenblatt kann ichs auch nicht erklären.


Das mit dem RWW und NRWW bedeutet nur, das die CPU bei Beschreiben des
Bootloaderbereichs anhält, sonst nicht.

Wird der Bootloaderbereich nicht voll ausgenutzt und soll zusätzlich
beschreibbar sein, d.h. nicht LARGEBOOTSTART, dann muß man das
Protokoll so definieren, das während des Löschens bzw. Schreibens keine
neuen Daten gesendet werden.


Peter

von André K. (andre-)


Lesenswert?

"Die SPM-Instruktionen sind zeitgeschützt, d.h. sie müssen innerhalb 4
Zyklen nach Laden von SPMCSR erfolgen."

Darum gehts es nicht. Eher darum, dass ich keine Flusskontrolle am
BTmodul verwende und dadurch der Puffer ueberlaeuft. Anschliessend ist
die BT Verbindung leider erstmal weg.
D.h. ich muessen ein sinnvolles Protokoll basteln, das dafuer sorgt,
dass eben nicht zu viel gesendet wird. Um nun nicht einen fertigen
Loader soweit umzubasteln, bis er gar nix mehr macht, hatte ich vor
einen komplett eigenen zu schreiben :)

MfG

von Peter D. (peda)


Lesenswert?

"Eher darum, dass ich keine Flusskontrolle am BTmodul verwende und
dadurch der Puffer ueberlaeuft."

Na und warum machst Du es dann nicht ?

Ohne Flußkontrolle geht es eben nicht, so einfach ist das.

Z.B. mein Bootloader geht davon aus, daß der Mega mindestens 512 Byte
SRAM Puffer hat, d.h. er wartet nach 512 Byte einfach auf das O.K. für
die nächsten 512 Byte.


Peter

von JaM (Gast)


Lesenswert?

Ich lese gerade die AppNotes zum Thema, das bringt mich weiter!
Danke Daniel!

lg,
JaM

von André K. (andre-)


Lesenswert?

"Na und warum machst Du es dann nicht"

Weil der Rest der Applikation das nicht zulaesst. Die Flusskontrolle
ist nicht in der FW des BT moduls enthalten, da sie aufgrund der VM auf
dem Modul natuerlich auch Zeit braucht um zu laufen (SW auf der VM ist
so schon langsam...). Und diese Zeit ist schlicht und ergreifend nicht
da.

MfG

von Peter D. (peda)


Lesenswert?

"Weil der Rest der Applikation das nicht zulaesst."


Nun, dann gibt es nur eine Möglichkeit:

- Der Bereich über LARGEBOOTSTART ist tabu, d.h. kann nicht beschrieben
werden.

- Die Baudrate ist so langsam zu wählen, daß das Füllen des
SRAM-Puffers mit der nächsten Page länger dauert, als das Löschen und
Schreiben der vorherigen Page.

Nur dann geht es auch ohne Flußkontrolle.


Peter

von Peter D. (peda)


Lesenswert?

P.S.:

Was ist VM ?


Flußkontrolle heißt nicht, daß etwas länger dauert, sondern ganz im
Gegenteil !

Man muß nicht garantierte Maximalzeiten abwarten, sondern macht schon
dann weiter, wenn die Gegenseite wirklich bereit ist.


Peter

von André K. (andre-)


Lesenswert?

VM = Virtual Machine. Laeuft neben dem eigentlichen BT Stack auf dem
BTmodul und ermoeglicht dem Benutzer eigene Programme in den Flash des
Moduls zu laden. Leider ist das ganze nur ein Interpreter und so
natuerlich besonders schnell..... ;)

Leider haette ich dann aber das Problem, dass die Flusskontrolle nicht
erwuenscht ist, wenn das eigentliche Programm auf dem AVR laeuft. Alles
etwas ungewoehnlich *g

An der Zeit zum Flashen solls nicht mangeln, es geht lediglich darum,
dass das Geraet am Ende wartbar ist.

MfG

von JaM (Gast)


Lesenswert?

frage: wenn sich z.b. nur ein byte innerhalb einer page des flashs
geändert hat, kann ich dann nur dieses byte neu schreiben? oder muss
ich trotzdem (so hab ich es verstanden) die ganze page erasen und neu
schreiben? bei dieser frage geht es mir um eine art "schonung" des
flashs...

lg,
JaM

von Thomas K. (thkais)


Lesenswert?

Das Flash kann nur Seitenweise beschrieben werden.
Theoretisch (ausprobiert habe ich das noch nicht) sollte es möglich
sein, nachträglich Bits zu löschen, also z.B. aus einem $C6 ein $C4 zu
machen. Setzen lassen sich die Bits im Flash aber ausschließlich durch
den Erase-Befehl.

von JaM (Gast)


Lesenswert?

noch ne frage:
wie bekomme ich denn den code in die bootsection? in asm wahrscheinlich
mit dem .org befehl, aber wie geht's mit avr-gcc?

lg,
JaM

von Werner B. (Gast)


Lesenswert?

@JaM

Sieh Dir mal das makefile von
http://www.mikrocontroller.net/forum/read-4-183976.html#new
an.

von Daniel B. (khani)


Lesenswert?

Hallo JaM,

wie man den Code komplett dahin bekommt habe ich mich auch etwas länger
gefragt. Bei der avr-libc-Dokumentation ist (ich weiß nicht mehr genau
wo) beschrieben, wie man die gesamte .text-section in der Gegend
umherschiebt (ist eine Linker-Option). Ich kann heute abend mal mein
Makefile zum Bootloader anschauen, denn ich habe im Moment die exakte
Syntax nicht im Kopf.

MfG, Daniel.

von JaM (Gast)


Lesenswert?

ich habs gerade eben selber mit dem --section-start kommando
hinbekommen. allerdings muss ich den bootloader-code jetzt immer in die
hexdatei rein copy-n-pasten, die als app-code auf den avr drauf soll.
das ist natürlich ungünstig. gibt's ne möglichkeit, den bootloader zu
flashen, und dann diesen flash zu sperren, so dass mir ein neues
hex-file (benutzte pony) den bootloader am ende nicht mit 0x00
überschreibt?

und irgendwie gefällt mir das alles nicht... z.b. brauch mein
bootloader doch keine interrupt-vektor-tabelle, oder? kann ich dem
compiler irgendwie erklären, er soll das bitte weglassen?

lg,
JaM
ps. aber immerhin, es geht voran...

von Werner B. (Gast)


Lesenswert?

> brauch mein
> bootloader doch keine interrupt-vektor-tabelle, oder?

Willkommen im Club :-p

von Daniel B. (khani)


Lesenswert?

Hallo Freunde,

das mit der Interrupt-Vektortabelle ist mir auch schon aufgestoßen.
Nach einiger Recherche hier im Forum ist mir allerdings aufgefallen,
sie lieber einfach zu ignorieren (so viel Platzt benötigt die ja auch
wieder nicht). Zumindest vertraten die Leute, die sich mit sowas
auskennen diese Meinung (Jörg Wunsch, so weit ich mich erinnere).

Ich glaube wir sollten, wenn wir es irgendwann mal schaffen einen
Bootloader zu schreiben, unsere Erfahrungen damit schriftlich
niederlegen und der Nachwelt so ein Feld erschließen, das nicht so
leicht zu beackern ist wie ein Wechselblinker oder ein elektronischer
Würfel.

Ich weiß, dass es genug Bootloader gibt, die alles viel besser können
und viel schöner machen - aber vom benutzen lernt man nix, sonst
bräuchten die meisten hier sich garnicht erst mit dem Microcontroller
als Hobby zu beschäftigen.

MfG, Daniel.

von Peter Dannegger (Gast)


Lesenswert?

"allerdings muss ich den bootloader-code jetzt immer in die
hexdatei rein copy-n-pasten, die als app-code auf den avr drauf
soll."


???

Ich versteh nur Bahnhof.

Der Bootloader wird doch nach jedem Reset angesprungen und wartet dann
darauf, daß die Applikation programmiert wird.

D.h. mit einem SPI-Programmer wird einmalig der Bootloader reingebrannt
und die Bootloaderstartfuse gesetzt, mehr nicht.

Die Applikation enthält nur die Applikation und wird über den
Bootloader reingebrannt, denn dazu hat man ihn ja extra gemacht.

Natürlich sollte der Bootloader jeden Versuch, sich selbst zu
zerstören, abweisen !
Z.B. wenn die Applikation mal versehentlich zu groß geworden ist.


Peter

von JaM (Gast)


Lesenswert?

@Daniel: "...unsere Erfahrungen damit schriftlich niederlegen und der
Nachwelt so ein Feld erschließen...": absolut! dabei ist das mit dem
bootloader doch gar nicht so schlimm, wie man am anfang denkt. die
informationen zu dem thema sind nur sehr weit gestreut und wenig in
zusammengefasster form auffindbar.

zum thema int-tabelle: ja, wirklich stören tut sie ja nicht, der jmp am
anfang überspringt den "müll" eben, wie üblich, nur dass die tabelle
im "bootsector" einfach unnütz ist (außer man möchte ints im
bootloader nutzen). dabei wäre es ganz einfach, das teil
"rauszuschneiden" (quasi manuell im hex-file), nur das dann die
adress-angaben im code nicht mehr stimmen.
ich muss ehrlich sagen, je länger ich jetzt mit avr-gcc arbeite, desto
unsympathischer wird mir die hochsprachen-sache. da weiss man
eigentlich ganz genau, was man will, kanns dem compiler aber nicht
beibringen.
da ist noch was anderes, was mich stört:
1
    asm ("jmp 0x0000" ::);
2
    38da:  0c 94 00 00   jmp  0x0
3
}
4
    38de:  80 e0         ldi  r24, 0x00  ; 0
5
    38e0:  90 e0         ldi  r25, 0x00  ; 0
6
    38e2:  0c 94 73 1c   jmp  0x38e6
7
8
000038e6 <_exit>:
9
    38e6:  ff cf         rjmp  .-2        ; 0x38e6
das ist das ende des bootloader-codes, man sieht schön den finalen
"jmp 0x0". doch was kommt danach? der müll riecht doch gewaltig nach
dem "int main ()"-overhead, den eine MCU doch eh nie verwendet. so
etwas nervt mich. code, der nie ausgeführt wird... der compiler soll
sich was schämen.

lg,
JaM

von JaM (Gast)


Lesenswert?

@Peter: Da hast du natürlich Recht, ich habe vergessen zu erwähnen, dass
mein "Bootloader" im Moment noch gar keinen Code lädt, d.h. er sagt
nur "Hallo, bin da!" und startet die App. D.h. ich lade auch den
App-Code über den SPI-Programmer, und dabei wird natürlich immer der
Bootloader mit 0x0 überschrieben. Daher habe ich ihn einfach in das
app-hex-file rein-gepastet, ganz billig, damit ponyprog den code
mitflasht.

ist ansich kein echtes problem, es nervt nur... im prinzip ging es mir
darum, wie man dem spi-programmer tool sagen kann, es soll die
bootsection nicht anrühren... wie gesagt, nicht wichtig.

lg,
JaM

von JaM (Gast)


Lesenswert?

@ Michael: ich hab mir jetzt den xnutboot bootloader (der mit dem
x-modem protokoll) angeschaut, das war auch ein guter tipp!

dort wird im makefile „-Ttext=(adr)“ als linkeroption verwendet (um die
startadresse der section .text festzulegen) , das kommt genau aufs
gleiche raus, wie „--section-start=.text=(adr)“.
also die frage, wie man den bootloader dahin bekommt, wo man ihn haben
möchte, wäre geklärt.
und so sieht das ende von main() in xnutboot.c aus:
1
    /*
2
     * Will jump into the loaded code.
3
     */
4
    asm volatile ("jmp 0");
5
6
    /*
7
     * Never return to stop GCC to include a reference to the exit
8
code.
9
     * Actually we will never reach this point, but the compiler
10
doesn't 
11
     * understand the assembly statement above.
12
     */
13
    for (;;);
14
}

der kommentar vor „for (;;);“ erklärt genau das, was ich am compiler
bemängelt hatte. damit wäre auch das geklärt (mit dem trick spart man
den exit() code, das sind n paar bytes).

jetzt kommt für meine wenigkeit die zweite phase: lerne, wie man per
code flasht! :D

lg,
JaM

von Daniel B. (khani)


Lesenswert?

Hallo,

eine freudige Nachricht - nach langer Programmiertätigkeit am gestrigen
Abend, funktioniert mein Bootloader ! Man kann nun mit dem AVROSP Code
in die Applikations-Sektion schreiben und verifizieren und eben alles
tun, was die AppNote 109 so beschreibt.

Das Lesen aus dem Flash hatte ja schon funktionert, aber beim Schreiben
schmierte immer der Bootloader ab (das war zumindest meine Meinung). Ich
habe festgestellt, dass in meinem inline-assembly rund um das SPM ein
Problem auftrat. Siehe dazu auch meinen Thread im GCC-Forum :
http://www.mikrocontroller.net/forum/read-2-215045.html#new

Jetzt funktioniert aber alles und ich habe die Funktion auch schon
durch programmieren des µC mit einem Testprogramm und einer
Verifikation mit Ponyprog (incl. Seriell-Adapter) überprüft.

Jetzt kommt noch ein bißchen Code-Kosmetik und ich kann mich vielleicht
einer kleinen Dokumentation und/oder meinem eigentlichen Projekt wieder
zuwenden. Bei Fragen stehe ich weiter gerne zur Verfügung.

MfG, Daniel.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

>so etwas nervt mich. code, der nie ausgeführt wird... der compiler
>soll sich was schämen.

Es steht Dir frei, den GCC oder auch das ganze WinAVR-Paket zu meiden
und einen "anständigen" Compiler zu kaufen!
Ansonsten: modifiziere den GCC doch einfach in der Weise, wie Du ihn
gerne hättest und stelle die Resultate der GCC-Gemeinde zu Verfügung.
Dann kannst Du den noobs von Compilerbauern mal so richtig Zeigen, wo
der Hammer hängt.

Sorry, aber das "gemotze" über den GCC weil irgendwas nicht so
funktioniert, wie manche sich das ausdenken, nervt.

von Olivier Oswald (Gast)


Lesenswert?

@Daniel: soweit ganz interessant, doch wie ging's denn schlussendlich
weiter?

von Daniel B. (khani)


Lesenswert?

Ja Olivier,

welche Frage hast Du nun genau ? ;-)

MfG, Daniel.

von Olivier Oswald (Gast)


Lesenswert?

Mit der "kleinen Dokumentation" :)

Inzwischen habe ich den folgenden Thread gefunden:
http://www.mikrocontroller.net/forum/read-4-183976.html

Und bin mit dem dortigen Code ganz gut zurecht gekommen....

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.