Forum: Compiler & IDEs Bootloader - Theoriefragen


von Julian von Mendel (Gast)


Lesenswert?

Hallo!

Ich habe eine Platine aetzen lassen, auf der drei ATMEGA168 sitzen, die 
untereinander per SPI kommunizieren koennen. Einer der ATMEGAs ist ueber 
die serielle Schnittstelle mit einem WLAN-PDA verbunden. Im Moment kann 
man die Atmels per ISP programmieren, man waehlt den zu programmierenden 
Atmel ueber einen Jumper aus. Da die Platine zusammen mit einem kleinen 
Roboter rumfahren soll, moechte ich sie gerne nicht nur per WLAN 
debuggen, sondern auch programmieren koennen. Das bedeutet im Klartext, 
dass der Atmel der mit dem PDA verbunden ist Daten vom PDA an die per 
SPI verbundenen Atmels weiterleiten koennen muss, und dass jeder der 
Atmels einen Bootloader braucht, der die Daten per USART/SPI bekommt und 
in den eigenen Flash schreibt.
Ich stelle mir das so vor: PDA sagt, er moechte Atmel Nr. 2 
programmieren, ist aber mit Atmel Nr. 1 verbunden. Atmel Nr. 1 leitet 
diese Nachricht an Atmel 2 weiter, der dann aus dem normalen 
User-Programm zum Bootloader springt. Der PDA schickt ein Hex-File, 
Atmel Nr. 1 leitet es weiter, Atmel Nr. 2 empfaengt es per SPI und 
schreibt es in den Flash. Wenn er fertig ist springt er zurueck zur 
Anwendung. Ist das machbar? Das bedeutet natuerlich auch, dass wenn das 
Anwendungsprogramm von Atmel Nr. 1 oder Nr. 2 kaputt ist, man nicht mehr 
drahtlos programmieren kann, da die Daten nicht weitergeleitet werden 
bzw. nicht zurueck zum Bootloader gesprungen werden kann. Dann muesste 
man wieder auf die Programmierung per ISP zurueckgreifen.
Da ich keine Erfahrung mit Bootloadern habe, wollte ich einen fertigen, 
schoenen anpassen. Ich kann kein Assembler und moechte eigentlich das 
ganze Programm C-basiert haben. Ich verwende eine aktuelle avr-libc und 
avr-gcc unter Linux. Ich konnte bei avrfreaks.net nur einen einzigen 
Bootloader finden, der aus reinem C-Code besteht 
(http://shaoziyang.googlepages.com/avrub_v3.htm). Unter 
http://www.nongnu.org/avr-libc/user-manual/group__avr__boot.html#gf08aabaebbd69da659357f402d4d28ce 
findet sich ausserdem ein Code-Ausschnitt, der wohl ein Ideal-Beispiel 
fuer's Schreiben einer Seite in den Flash sein sollte.

Jetzt zu den Fragen ;)
Ist es sinnvoll, Pruefsummen zu uebertragen? Haelt sich die 
Wahrscheinlichkeit eines Uebertragungsfehlers eigentlich nicht sehr in 
Grenzen? Beim Programmieren per ISP werden Uebertragungsfehler ja auch 
nicht ueberprueft, oder?
Wie schnell kann man in den Flash schreiben (damit ich eine Orientierung 
habe, was fuer eine Baud-Rate sich ueberhaupt lohnt)?
Per
1
void (*jump_to_app)(void) = 0x0000;
2
jump_to_app();
 wird in einem Bootloader, den ich mir angesehen habe, zum 
Anwendungsprogramm gesprungen. Bezieht sich die Adresse 0 hier auf den 
Anfang des Anwendungsprogramms? Wie springt man dann aus der Anwendung 
zum Bootloader? (<-- wichtige Frage)
Wenn der Bootloader keine 2er-Potenz als Groesse hat bleibt ein Teil der 
Boot-Section ungenutzt, oder? Warum gibt es ueberhaupt eine "Boot 
section"? Ich verstehe nicht, warum man nicht einfach den Bootloader an 
den Anfang schreibt, der Bootloader weiss, in welcher Seite er endet und 
direkt dannach das Anwendungsprogramm schreibt.

Dankeschoen fuer's Lesen und ggf. auch fuer Tipps :)
Julian

von Mark .. (mork)


Lesenswert?

Hallo Julian!


>Per
>
>void (*jump_to_app)(void) = 0x0000;
>jump_to_app();
>
 >wird in einem Bootloader, den ich mir angesehen habe, zum
>Anwendungsprogramm gesprungen. Bezieht sich die Adresse 0 hier auf den
>Anfang des Anwendungsprogramms? Wie springt man dann aus der Anwendung
>zum Bootloader? (<-- wichtige Frage)

Ja, die Anwendung fängt bei 0x0000 an. Wenn Du aus der Anwendung zum 
Bootloader springen willst, musst Du anstatt 0x0000 die Adresse 
eintragen, wo der Bootloader anfängt. Diese musst Du selbst ermitteln.

>Wenn der Bootloader keine 2er-Potenz als Groesse hat bleibt ein Teil der
>Boot-Section ungenutzt, oder?

Jepp. Nicht alle Zweierpotenzen sondern nur 512, 1024 oder 2048 Bytes. 
Wenn Dein Bootloader also 256 Bytes hat, sind 256 Bytes ungenutzt.


>Ich verstehe nicht, warum man nicht einfach den Bootloader an
>den Anfang schreibt, der Bootloader weiss, in welcher Seite er endet und
>direkt dannach das Anwendungsprogramm schreibt.

Am Anfang steht die VIT, das ist eine Tabelle, wo die Vektoren für die 
ISRs stehen. Das kann man nicht ändern, das ist nun man so. Zudem denkt 
der Compiler, dass der Flash bei 0x0000 anfängt, und berechnet daraus 
die Adresen der einzelnen Funktionen. Wenn der Code aber um die Größe 
der Bootloaders verschoben ist, dass stimmen diese Adressen nicht und 
der Controller führt demnach fasche Sprungbefehle aus, die zum Absturz 
führen.


MfG Mark

von Julian von Mendel (Gast)


Lesenswert?

Hallo Mark,

danke dir!

> Wenn Du aus der Anwendung zum
> Bootloader springen willst, musst Du anstatt 0x0000 die Adresse
> eintragen, wo der Bootloader anfängt. Diese musst Du selbst ermitteln.

Wie mache ich das?

> Nicht alle Zweierpotenzen sondern nur 512, 1024 oder 2048 Bytes.

Betraegt die Maximalgroesse meines Bootloaders demnach 2048 Byte?

Theoretisch sollten inline-Funktionen genauso wenig Platz benoetigen wie 
eine Makro-Funktion, oder? Kann mir jemand kurz sagen, wie man bei 
avr-gcc sich die Groesse des erzeugten Programms anzeigen laesst?

Schoene Gruesse
Julian

von Mark .. (mork)


Lesenswert?

Hallo Julian.

>> Wenn Du aus der Anwendung zum
>> Bootloader springen willst, musst Du anstatt 0x0000 die Adresse
>> eintragen, wo der Bootloader anfängt. Diese musst Du selbst ermitteln.
>
>Wie mache ich das?

Das kannst Du im Datenblatt unter "Boot Loader Parameters" nachgucken.

>> Nicht alle Zweierpotenzen sondern nur 512, 1024 oder 2048 Bytes.
>
>Betraegt die Maximalgroesse meines Bootloaders demnach 2048 Byte?

Theoretisch gingen mehr als 2048 Bytes, aber dann müsstest Du den Code 
splitten, so dass ein Teil der Bootloaders im Bootloader-Bereich ist und 
ein Teil nicht. Ich weiss aber nicht ob man das auch in der Praxis 
umsetzen kann.

PS: ich hab gerade im Datenblatt nachgeguckt, es gehen auch 256Bytes und 
nicht nur 512.

>Kann mir jemand kurz sagen, wie man bei
>avr-gcc sich die Groesse des erzeugten Programms anzeigen laesst?

Wenn Du ein Programm Compiliert und gelinkt hast gibts am Ende eine 
Zusammenfassung :
1
Size after:
2
testpp.elf  :
3
section            size      addr
4
.text             32464         0
5
.bss                  7   8388704
6
.stab               888         0
7
.stabstr            113         0
8
.debug_aranges       32         0
9
.debug_pubnames      91         0
10
.debug_info         500         0
11
.debug_abbrev       335         0
12
.debug_line         443         0
13
.debug_frame         64         0
14
.debug_str          317         0
15
.debug_loc           19         0
16
Total             35273
17
18
19
20
-------- end --------

Bei .text steht dann, wie groß dann der Code ist.

MfG Mark

von kosmonaut pirx (Gast)


Lesenswert?

hallo,

>Kann mir jemand kurz sagen, wie man bei
>avr-gcc sich die Groesse des erzeugten Programms anzeigen laesst?

scnr, aber um korrekt zu sein, macht das nicht der avr-gcc. das ist nur 
ein übersetzer, nicht mehr und nicht weniger ("ein compiler ist ein 
compiler ist ein compiler)". und auch nicht das makefile, aus dem 
vermutlich Mark sein ausschnitt stammt.

dafür gibt es die tools aus den binutils. namentlich avr-size, 
avr-readelf (avr-objdump auch? mag sein). da gibt's doku im netz oder in 
den man-pages. meist werden die gleich durch ein makefile aufgerufen, 
aber das muss ja nicht immer so sein

hth, bye kosmo

von Julian M. (jvm)


Lesenswert?

Hey du!

>>> Wenn Du aus der Anwendung zum
>>> Bootloader springen willst, musst Du anstatt 0x0000 die Adresse
>>> eintragen, wo der Bootloader anfängt. Diese musst Du selbst ermitteln.
>>
>>Wie mache ich das?
>
> Das kannst Du im Datenblatt unter "Boot Loader Parameters" nachgucken.

Danke. Verstehe ich es richtig, dass bei einer Bootsektor-Groesse von z. 
B.
1024 Woertern ich nach 0xC00 huepfen muesste, um aus der Anwendeung zum 
Bootloader zu kommen? Wenn ja hast du mir sehr geholfen :)


>>Kann mir jemand kurz sagen, wie man bei
>>avr-gcc sich die Groesse des erzeugten Programms anzeigen laesst?
>
> Wenn Du ein Programm Compiliert und gelinkt hast gibts am Ende eine
> Zusammenfassung :

Bei mir nicht.
Ich linke per
1
avr-gcc -g -mmcu=atmega168 -Wall -Werror -Wstrict-prototypes -mcall-prologues -Os -o main.elf -Wl,-Map,main.map main.o functions.o com.o ios.o drive.o navigation.o boot_support.o

von Julian M. (jvm)


Lesenswert?

Danke kosmo, mit "avr-size *.elf" geht's.

von Julian M. (jvm)


Lesenswert?

Ich meinte natuerlich 0x1C00.

von Mark .. (mork)


Lesenswert?

>Danke. Verstehe ich es richtig, dass bei einer Bootsektor-Groesse von z.
>B.
>1024 Woertern ich nach 0xC00 huepfen muesste, um aus der Anwendeung zum
>Bootloader zu kommen?

Eher 0x1C00. 0xC00 wären beim AtMega88.


EDIT------------
>Ich meinte natuerlich 0x1C00.
Jepp. Da war ich wohl zu spät.

von Julian M. (jvm)


Lesenswert?

In den Flash werden direkt die Binärdaten geschrieben. Also sollte ich 
auf dem PDA ein Programm laufen lassen, das eine Intel-Hex-Datei in eine 
Binärdatei verwandelt und seitenweise zum Atmel überträgt, oder?
Zum Konvertieren von Intel-Hex-Dateien in Binärcode habe ich kein 
einziges Opensource-Programm gefunden. Hat da jemand einen Tip fuer 
mich?

von kosmonaut_pirx (Gast)


Lesenswert?

hallo,
hex-dateien beschreiben doch schon binärcode, sie sind nur eine mögliche 
repräsentation. daher brauchst du nichts umwandeln.
bye kosmo

von Julian M. (jvm)


Lesenswert?

Wenn mein Atmel-Programm direkt die Daten die es bekommt reinschreibt 
muss der Sender die Repräsentation der Daten vorher direkt in die 
Binärdaten umwandeln, oder nicht?

von kosmonaut_pirx (Gast)


Lesenswert?

hallo,
ja, du hast recht. avrdude macht sowas, denke ich. bisher war ich immer 
zu faul, mir einen hex-interpreter zu basteln, weil das in gängiger 
programmiersoftware schon getan ist.
bye kosmo

von Julian M. (jvm)


Lesenswert?

Soweit ich das in den Parametern von avrdude sehen konnte kann man es 
nicht nur fuer diese Konvertierung nutzen?

von kosmonaut_pirx (Gast)


Lesenswert?

"es"?

von Julian M. (jvm)


Lesenswert?

Das avrdude-Dings ;)

von kosmonaut_pirx (Gast)


Lesenswert?

nun ja, steht alles auf der seite.
ist auch recht leicht zu erweitern, wenn man mal bedarf nach einem 
eigenem protokoll hat, aber keinen nerv, sich um
standard-dinge wie einlesen der hex-files oder einlesen von optionen 
u.ä.
zu kümmern. bevor du also das rad neu erfindest ...

von Mark .. (mork)


Lesenswert?

Hallo,

wieso wollt ihr überhaupt Hex-Dateien verwenden und scheibt beim 
Erstellen der Hex(ich vermute mal mit avr-objcopy) nicht einfach 
'binary' anstatt 'ihex'? Dann wird eine Binärdatei erzeugt.

MfG Mark

von Julian M. (jvm)


Lesenswert?

Danke Mark! Ich wusste nicht, dass das so einfach geht :)

von Julian M. (jvm)


Lesenswert?

Hallo!

Was muss ich denn tun, damit der Bootloader, den ich geschrieben habe in 
der Boot Section von meinem Atmel landet? Wie sage ich dem Linker, dass 
die Adressen um die Position der Boot section verschoben sind? Wie 
bringe ich den Atmel dazu, mit dem Programm in der boot section zu 
beginnen, und nicht mit dem Programm bei 0x0000?

Danke fuer die Hilfe.

von Julian M. (jvm)


Lesenswert?

Erledigt. --section-start=.text=3C00 fuer den Linker hat gereicht.

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.