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
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
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
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
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
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
>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.
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?
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?
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
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 ...
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
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.