AVR Bootloader

Aus TippvomTibb
Zur Navigation springen Zur Suche springen

Basisinformation

http://ww1.microchip.com/downloads/en/Appnotes/Atmel-8242-XMEGA-Boot-Loader-Quick-Start-Guide_ApplicationNote_AVR1605.pdf

https://web.archive.org/web/20140803113418/http://www.atmel.com/Images/doc7618.pdf

Vorsicht bei diesem Artikel, da steht ziemlich viel Verwirrendes/Unzutreffendes drin.

Bootloader Code

Am Beispiel ATmega328(P)

Den Bootloader für diesen Typ findet man im Sourcecode und als kompilierte Version (.hex) unter hier. Im Installationsverzeichnis der Arduino IDE auch im /hardware/arduino/avr/bootloaders/atmega zu finden.

ATmegaBOOT_168.c

ATmegaBOOT_168_atmega328.hex

ATmegaBOOT_168_diecimila.hex

ATmegaBOOT_168_pro_8MHz.hex

ATmegaBOOT_168_atmega1280.hex

ATmegaBOOT_168_atmega328_pro_8MHz.hex

ATmegaBOOT_168_ng.hex

Makefile

Wie diesem Artikel zu entnehmen ist, wurde der (Original-)Bootloader des Nano ab Januar 2018 von o.g. Bootloader zu Optiboot geändert. Dies erklärt auch in der Arduino IDE mit der Boardauswahl 'Nano' die Menüauswahl Werkzeuge->Prozessor-ATmega328P (ab 01/2018)und ATmega328P(Old Bootloader bis 01/2018).


Man findet unter /hardware/arduino/avr/bootloaders/optiboot folgendes:

Makefile

boot.h

omake

optiboot.c

optiboot_atmega168.lst

optiboot_atmega328.hex

optiboot_atmega8.hex

pin_defs.h

README.TXT

makeall

omake.bat

optiboot_atmega168.hex

optiboot_atmega328-Mini.hex

optiboot_atmega328.lst

optiboot_atmega8.lst

stk500.h

Wer tiefer in die Booloader-Programmierung einsteigen möchte findet hier einen sehr gelungenen Artikel.

Bootloader auslesen

TODO

Bootloader schreiben

Wichtiger beim Schreiben als beim Lesen, bzw. Abspeichern ist zu wissen in welchem (internen) Format ein HEX-File abgelegt ist. Die Extension .hex , .intel, . bin oder .raw sind KEIN Indiz für das Format des Dateiinhaltes.

Avrdude unterstützt folgende Fileformate:

The filename field indicates the name of the file to read or write. The format field is optional and contains the format of the file to read or write. Possible values are:

i Intel Hex
s Motorola S-record
r raw binary; little-endian byte order, in the case of the flash ROM data
m immediate mode; actual byte values specified on the command line, separated by commas or spaces in place of the filename field of the ‘-U’ option. This is useful for programming fuse bytes without having to create a single-byte file or enter terminal mode. If the number specified begins with 0x, it is treated as a hex value. If the number otherwise begins with a leading zero (0) it is treated as octal. Otherwise, the value is treated as decimal.
a auto detect; valid for input only, and only if the input is not provided at stdin.

d decimal; this and the following formats are only valid on output. They generate one line of output for the respective memory section, forming a comma-separated list of the values. This can be particularly useful for subsequent processing, like for fuse bit settings.
h hexadecimal; each value will get the string 0x prepended.

o octal; each value will get a 0 prepended unless it is less than 8 in which case it gets no prefix.
b binary; each value will get the string 0b prepended.
The default is to use auto detection for input files, and raw binary format for output files. 

Die Beschreibung findet sich wie so oft auf Wikipedia:

Intel Hex Format
Motorola

Um den Inhalt nicht mit hexdump inspizieren zu müssen, lohnt sich ein Blick auf die Ausgabe von

objdump -s file.hex

oder

srecord

Um z. B. das Optiboot-Hex-File des 328P genauer unter die Lupe zu nehmen kann man es erst mal umwandeln:

srec_cat optiboot_atmega328.hex -intel -o optiboot_atmega328.bin -binary

und sich mit

hexdump -C optiboot_atmega328.bin | more 

anschauen.

Dann erkannt man sofort, dass der Bereich 0x0000 bis 0x7dff mit 0x00 gefüllt ist und der Bootcode an der Adresse 0x7e00 beginnt und bei 0x7fff endet, also nur die letzten 512 Byte des Flashspeichers belegt. Das BIN-File ist, wie zu erwarten, für den ATmega328(P) genau 32768 Bytes groß. Da der ATmega in Words (16 Bit) organisiert ist beginnt der Bootsektor bei 0x3f00.

avrdude  -c usbtiny -p m328p -U flash:w:./optiboot_atmega328.hex:i flash:v:./optiboot_atmega328.hex:i 

Um den genauen Pfad des Bootloaders schnell zu finden.

locate optiboot_atmega328.hex

Evtl. vorher noch ein updatedb machen.

Um den Port heraus zu bekommen genügt unter Umständen schon ein

dmesg |grep ttyUSB

Wenn man mehrere (verschiedene) Controller angestöpselt hat muss man etwas genauer hinschauen.

ls -lR /dev/serial

Überträgt man einen Sketch mit der Arduino IDE bekommt man im Statusfenster die Größe des übertragenen Programmcodes angezeigt.

Der Sketch verwendet 2778 Bytes (9%) des Programmspeicherplatzes. Das Maximum sind 30720 Bytes.
Globale Variablen verwenden 1240 Bytes (60%) des dynamischen Speichers, 808 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.

Die 30270 Bytes in dem hier genannten Beispiel ergeben sich aus 32768 Bytes (GesamtFlashSpeicher des ATmega328) minus 2048 Bytes (für den Bootloader durch BOOTSZ[0:1] reservierte Speicherplatz. Jetzt könnte man auf die Idee kommen, dass die Arduino IDE hier die hfuses ausliest und den Speicherplatz aus dem Zustand von BOOTSZ[0:1] berechnet. Leider ist dem nicht so. Der Wert wird statisch in der boards.txt vorgegeben: nano.menu.cpu.atmega328.upload.maximum_size=30720 :-((

Um einfach die Fuses zu überprüfen/bestimmen sei unbedingt diese Seite und diese Seite empfohlen.

Fsues an Bootlaoder anpassen

avrdude  -c usbtiny -p m328p -U hfuse:r:-:b