AVR Bootloader optiboot Assemblerversion

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Einleitung

Der optiboot Bootloader wurde in der Sprache C von Peter Knight und Bill Westfield entwickelt. Die Version 6.2 wurde als Basis für die hier beschriebene überarbeitete Assembler Version benutzt. Der optiboot Bootloader wurde nicht völlig neu entwickelt, sondern lediglich optimiert und weiter entwickelt. Es werden Teile des STK500 Kommunikations-Protokols benutzt, die in der AVR061 Dokumentation von Atmel veröffentlicht wurde. Das komplette Programm wurde in die AVR-Assemblersprache umgeschrieben und die Erzeugung der .hex Datei in einen bash Shell Script verlegt. Dabei wird die Programmlänge automatisch weiterverarbeitet und damit die Startadresse des Bootloaders sowie die Fuses des ATmega passend eingestellt. Ziel für diesen Schritt war hautpsächlich, einen Bootloader zu erhalten, der auch dann in 512 Byte Flash Speicher paßt, wenn die Fähigkeit zum EEprom Beschreiben integriert ist. Eine komplette Beschreibung der Untersuchungen und der verwendeten Methoden findet man in deutscher Sprache im Unterverzeichnis Doku/german und in englischer Sprache im Verzeichnis Doku/english mit dem Dateinamen bootloader.pdf.

Eigenschaften der Assemblerversion von optiboot

Um viele Fallstricke bei der Erzeugung eines lauffähigen Bootloaders zu umgehen, wurde die Erzeugung der Bootloader Datei weitgehend automatisiert. Zusätzlich werden Einstellungen auch geprüft und die Erzeugung mit einer entsprechenden Fehlermeldung abgebrochen, wenn beispielweise die gewählte Betriebsfrequenz (AVR_FREQ) nicht zu der mit den Fuses (CKSEL,CKDIV8) eingestellten Möglichkeiten für den Takt paßt. Ein Empfang von Programmdaten für optiboot ist derzeit nur über eine serielle Schnittstelle möglich.

Hier sind einige der Fähigkeiten des optiboot Programms aufgelistet:

  • Unterstützt eine große Zahl von AVRs, wobei fast alle auf Funktion getestet wurden.
  • Unterstützt das Laden von Daten in den EEprom Speicher.
  • Passt in den meisten Fällen in 512 Byte Flash-Speicher.
  • Die Anpassung der Programmgröße und die Änderung der notwendigen Fuses wird automatisch vorgenommen.
  • Die von der Programmgröße und dem AVR Modell abhängige Startaddresse wird automatisch berechnet und auf dem Bildschirm angezeigt.
  • Alle beim jeweiligen AVR-Prozessor vorhandenen seriellen Schnittstellen können frei gewählt werden. Als Standard wird immer das erste UART benutzt.
  • Kann die serielle Schnittstelle über Software emulieren. Damit werden auch ATtiny Prozessoren ohne UART unterstützt. Außerdem können die TX und RX Pins bei SOFT_UART völlig frei gewählt werden.
  • Bei der SOFT_UART Lösung kann die serielle Kommunikation auch über nur einen AVR Pin durchgeführt werden.
  • Kann eine automatische Baudraten-Anpassung vornehmen. Dabei wird die Baudzeit aus dem ersten empfangenen Datenbyte gemessen. Verschiedene Methoden der Baudzeit-Messung können dabei ausgewählt werden. Wenn der so konfigurierte optiboot noch in 512 Byte Flash passen soll, muß die LED Blink Funktion beim Programmstart abgewählt werden.
  • Kann auch für AVRs ohne Bootloader Unterstützung benutzt werden. Diese VIRTUAL_BOOT_PARTITION Fähigkeit kann natürlich auch für AVRs benutzt werden, die die Bootloader Unterstützung besitzen. Das optiboot Programm wird dabei größer, kann aber dann auf jeder Flash-Speicher Seite starten.
  • Läßt eine angeschlossene LED standardmäßig drei mal blinken (LED_START_FLASHES=3). Bei eintreffenden seriellen Daten wird das Blinken aber sofort abgebrochen.
  • Anstelle des LED-Blinkens beim Start kann man auch die LED aufleuchten lassen, wenn auf serielle Daten gewartet wird (LED_DATA_FLASH=1). Auch ein Dauerleuchten der LED kann mit LED_DATA_FLASH=4 gewählt werden. Dabei geht die LED erst durch den Watchdog-Reset wieder aus.
  • Die Länge des erzeugten Programms ist nur abhängig vom gewählten AVR-Prozessor und den ausgesuchten Optionen. Die Version des avr-gcc Kompilers spielt keine Rolle wenn die Assembler Quellen benutzt werden. Dies macht eine nachträgliche Kontrolle (Verify) des installierten Bootloaders einfacher, selbst mit einem anderen PC.
  • Unterstützt die Anpassung der Oszillator-Frequenz für den AVR internen RC-Oszillator. Dadurch ist auch in Problemfällen die Benutzung eines Bootloaders mit fester Baudrate möglich.
  • Das Laden des optiboot Programms in den jeweiligen AVR Prozessor kann automatisch mit dem Programm avrdude und einem angeschlossenem ISP-Programmer erfolgen. Dazu ist nur die zusätzliche Eingabe von ISP=1 beim make Aufruf erforderlich. Die zusätzliche Eingabe ISP=2 würde eine Verifikation mit avrdude bewirken. Mit ISP=3 wird der gesamte Programmspeicher (Flash) des angeschlossenen AVR ausgelesen. Mit ISP=4 wird der gesamte EEprom-Speicher des angeschlossenen AVR ausgelesen.

Die nachfolgenden Fähigkeiten beziehen sich nur auf den Herstellungsprozess des Bootloaders:

  • Für die Erzeugung des optiboot Bootloaders können wahlweise auch angepaßte C-Quellen benutzt werden. Die meisten Funktionen sind auch hier möglich. Natürlich wird das erzeugte optiboot Programm größer!
  • Der Umfang der Bildschirmausgabe bei der Erzeugung von optiboot kann mit der Systemvariablen VerboseLev verändert werden. Der Wert kann zwischen 1 und 4 liegen, wobei 2 der Standardwert ist.
  • Die Bildschirmausgabe kann mit der Systemvariablen WITH_COLORS=1 bunter gestaltet werden. Mit WITH_COLORS=2 wird reiner Text ausgegeben.
  • Die Erzeugung des optiboot Programms wird in einer Bash Script Datei gesteuert, wobei die Text-Datei avr_params.def die notwendigen Daten für alle unterstützten AVR-Prozessoren liefert. In dieser avr_params.def Datei sind auch für jeden unterstützten Prozessor Standard-Werte für die Fuses, Arbeitsfrequenz und Baudrate festgelegt.
  • Die für die jeweiligen Prozessoren verfügbaren Pinbelegungen findet die Script Datei in dem avr_pins Verzeichnis in einer passenden Datei. Hier werden bei Bedarf auch Standardwerte für die von SOFT_UART benutzten Pins und für die LED gefunden.
  • Die Erzeugung des optiboot Programms läuft unter Linux mit installierten avr Paketen. Eine Erzeugung unter Windows10 ist möglich, wenn zusätzlich zum Arduino Paket Programmpakete installiert sind, die die bei der Erzeugung erforderlichen Programme wie bash, bc, echo und andere zur Verfügung stellt. Geprüft habe ich das Cygwin64 Paket auf einen Windows10 Laptop mit vorher installierten Arduino Paket.
  • Die bei der Programmerzeugung gewählten Parameter werden sowohl am Ende einer .lst Datei als auch in einer .log Datei festgehalten.

Optionen für die optiboot Makefile

Die optiboot hex Datei wird über einen make Aufruf erzeugt, der den gewünschen Zielprozessor oder eine der Platinen als Parameter angibt. Dazu können auch verschiedene Optionen für die Erzeugung angegeben werden, die hier aufgelistet werden:

  • F_CPU : Teilt dem Programm die Taktrate des Prozessors mit. Die Angabe erfolgt in Hz (Schwingungen pro Sekunde). Das Beispiel F_CPU=8000000 gibt eine Frequenz von 8 MHz an.
  • BAUD_RATE : Gibt die Baud-Rate für die serielle Kommunikation an. Es werden immer 8 Datenbits ohne Parity verwendet. Werte <100 aktivieren eine Messung and Anpassung der Baudrate mit verschiedenen Verfahren. Der Vorteil der automatischen Anpassung besteht darin, daß man problemlos auf eine niedrigere Baudrate ausweichen kann, wenn Probleme mit einer hohen Baudrate auftauchen.
  • SOFT_UART : Wählt Software-Lösung für die serielle Kommunikation.
  • UART_RX : Gibt den Port und die Bitnummer für die seriellen Empfangsdaten an. Das Beispiel UART_RX=D0 nimmt Bit 0 des D Ports für den seriellen Eingang.
  • UART_TX : Gibt den Port und die Bitnummer für die seriellen Sendedaten an. Das Beispiel UART_TX=D1 nimmt Bit 1 des D Ports für den seriellen Ausgang.
  • UART : Wählt eine serielle Schnittstelle des Chips für die Kommunikation. Eine Auswahl setzt das Vorhandensein mehrerer Schnittstellen voraus, funktioniert dann aber auch mit SOFT_UART.
  • INVERSE_UART : Invertiert die Pegel von RX und TX Signalen. Die Option kann nur bei Software UART benutzt werden.
  • LED_START_FLASHES : Wählt die Anzahl der Blink-Zyklen für die Kontroll-LED. Bei 1 oder -1 wird nur einmal geblinkt ohne Wiederholung. Negative Vorgaben bedeuten, daß in der Programmschleife das RX Bit der seriellen Schnittstelle nicht überwacht wird. Bei positiven Werten wird die Binkschleife sofort abgebrochen, sobald eingehende RX-Daten festgestellt werden. Bitte beachten Sie,daß das Blinken den Start des Anwenderprogramms verzögert.
  • LED : Wählt das Port-Bit für die Kontroll-LED. Beim Beispiel LED=B3 würde eine an das Bit 3 des Port B angeschlossene LED blinken.
  • LED_DATA_FLASH : Die Kontroll-LED leuchtet während des Wartens auf Empfangsdaten der seriellen Kommunikation, wenn der Wert auf 1 gesetzt wird. Ein Wert von 4 bewirkt, daß die LED nur beim Start einmalig eingeschaltet wird. Hiermit kann man auch erkennen, daß der Bootloader gestartet wurde und es wird viel weniger Platz im Programmspeicher gebraucht.

Weitere Optionen sind meist nur für Software-Untersuchungen, die Frequenzkalibration des RC-Generators und für Prozessoren ohne Bootloader-Bereich interessant.

  • TIMEOUT_MS : Diese Option gibt eine Zeitschranke in Millisekunden vor für den Empfang von Boot-Daten. Nach dieser Zeit wird der Bootvorgang abgebrochen und versucht, das Anwenderprogramm zu starten. Mögliche Werte für TIMEOUT_MS sind 500, 1000, 2000, 4000 und 8000. Der tatsächlich mögliche Wert kann je nach Prozessor auf 2 Sekunden begrenzt sein. Wenn kein TIMEOUT_MS angegeben wird, wird die Zeitschranke auf 1 Sekunde gesetzt.
  • SUPPORT_EEPROM : Wählt für das Bootloader-Programm die Lese- und Schreib-Funktion für EEproms. Wenn als Quelle das Assembler-Programm gewählt wurde, ist die EEprom Unterstützung ohne gesetzte Option eingeschaltet, kann aber abgeschaltet werden, wenn die SUPPORT_EEPROM Option auf 0 gesetzt wird.
  • C_SOURCE : Wählt als Programmquelle das C-Programm anstelle des Assembler-Programms (0 = Assembler). Die Assembler Version benötigt weniger Speicherplatzund unterstützt alle Funktionen. Bei der C-Quelle muß die Funktion SUPPORT_EEPROM extra eingeschaltet werden (Standard = aus).
  • BIGBOOT : Wählt zusätzlichen Speicherverbrauch für das Bootloader-Programm. Das dient nur zum Test der automatischen Anpassung an die Programmgröße in dem Bash-Script.
  • VIRTUAL_BOOT_PARTITION : Ändert die Programmdaten eines Anwenderprogramms so ab, daß der Bootloader beim Reset angesprochen wird. Für den Start des Anwenderprogramms wird ein anderer Interrupt-Vektor benutzt.
  • save_vect_num : Wählt eine Interrupt-Vektornummer für die VIRTUAL_BOOT_PARTITION Methode aus.
  • OSCCAL_CORR : Mit der Option OSCCAL_CORR kann der interne RC-Generator des AVR abgeglichen werden. Ist bei Quarz-Betrieb oder externem Takt unwirksam! Der Korrekturwert wird vom voreingestellten OSCCAL Byte abgezogen. Bei positivem Korrekturwert wird die Frequenz normalerweise niedriger. Da die erzeugte Baud-Rate direkt vom Prozessortakt abhängt, ist ein richtig eingestellter Prozessortakt für eine erfolgreiche serielle Kommunikation wichtig. Normalerweise sollte ein Wert zwischen -20 und +20 ausreichen.
  • NO_EARLY_PAGE_ERASE : Verhindert das Löschen der Flash Seite bevor die Daten über die serielle Schnittstelle empfangen sind. Da das Löschen sonst parallel zum Datenempfang abläuft, ist das programmieren des Flashs mit dieser Option um etwa 30% langsamer. Da der normalerweise auch durchgeführte Datenvergleich (verify) etwa genau so viel Zeit braucht, ist der Zeitverlust nicht so erheblich. Dafür spart man beim optiboot Bootloader etwa 14 Bytes Platz in der Bootloader-Seite, was wegen der AVR-Technik in der Praxis auch eine Halbierung des Platzbedarfs bedeuten kann.

Kurzanleitung

Zunächst müssen Sie mit dem Arbeitsverzeichnis in das optiboot Verzeichnis wechseln (Change Directory -- cd). Hier können Sie sich die Optionen mit make oder mit make help anzeigen lassen. Eine Liste der unterstützten AVR Prozessoren erhalten sie mit make pl. Zum Erzeugen einer optiboot hex Datei müssen Sie einen der unterstützten Prozessoren als Parameter beim make Aufruf angeben. Ein make atmega328p erzeugt eine Bootloader Datei mit dem Namen optiboot_atmega328p.hex. Daneben werden auch noch die Dateien optiboot_atmega328p.lst und optiboot_atmega328p.log erzeugt. In der .log Datei werden die gewählten Optionen festgehalten, die .lst wird durch Disassemblieren der .elf Datei erzeugt. Beim Erzeugen der .hex Datei werden Informationen auf dem Bildschirm ausgegeben, die besonders bei angewählten Optionen beachtet werden sollten.

Zum Übertragen des Bootloaders zum AVR-Zielprozessor wird das Programm avrdude benutzt, wenn zusätzlich die Option ISP=1 angegeben wird. Je nach angeschlossenem ISP-Programmer muß auch noch der Port für avrdude (ISPPORT) eingestellt werden. Neuere Programmer benutzen oft eine serielle Schnittstelle, die an einem USB-Gerät hängt. Diese seriellen Schnittstellen haben unter Linux entweder den Namen /dev/ttyUSBx oder /dev/ttyACMx. Bei Windows haben serielle Schnittstellen einen COMx Namen. Das x steht jeweils für eine vom System vergebene Ziffer. Für einen angeschlossenen Diamex ISP-PRog-NG (AVR-ISP2) wäre das bei Linux z.B. /dev/ttyACM0, so daß ein vollständiger Aufruf zum Installieren des Bootloaders make atmega328p ISP=1 ISPPORT=/dev/ttyACM0 heißen kann. Als ISPPORT ist usb voreingestellt, was für einen Diamex ALL-AVR ISP-Programmer (ERFOS AVRISP MkII Clone) passen würde. Für diesen Typ Programmer würde also das Kommando make atmega328p ISP=1 ohne die Angabe eines Ports reichen.

Beispiele für die Bootloadererzeugung

Das erste Beispiel benutzt eine Software für die serielle Kommunikation.

make atmega328p SOFT_UART=1

Optiboot für 16000000 Hz (16.00 Mhz) Betrieb mit Baudrate 115200 und EEprom Unterstützung konfiguriert.
>>> Starte optiboot für AVR atmega328p erstellen:
LED-Pin PB5 benutzt Pin 19-PDIP28 17-TQFP32, mit Spezialfunktionen: SCK PCINT5.
RX-Pin PD0 benutzt Pin 2-PDIP28 30-TQFP32, mit Spezialfunktionen: PCINT16 RXD.
TX-Pin PD1 benutzt Pin 3-PDIP28 31-TQFP32, mit Spezialfunktionen: PCINT17 TXD.
avr-gcc -g -Wall -Os -fno-split-wide-types -mrelax -mmcu=atmega328p  -fno-diagnostics-show-caret -DBAUD_RATE=115200 -DLED_START_FLASHES=3 -DSUPPORT_EEPROM=1 -DLED=pB5 -DUART=00 -DSOFT_UART=01 -DUART_RX=pD0 -DUART_TX=pD1 -DF_CPU=16000000 -DHFUSE=hexDE -DLFUSE=hexFF -DBOOT_PAGE_LEN=512 -DVerboseLev=2 -c -o optiboot.o optiboot.S
 
--------------------------------------------------------------------------------
BAUD RATE CHECK: Desired: 115200,  SoftUART_Real: 115107, Delay: 116*1, Difference=-.07%
--------------------------------------------------------------------------------
# # # # # # # # # # # # # # # # # # # # # #
Urlader Startadresse: 0x7E00 = 32256
# # # # # # # # # # # # # # # # # # # # # #

   text	   data	    bss	    dec	    hex	filename
    506	      0	      0	    506	    1fa	optiboot.elf
Benötigt 1 Boot Seite mit 512 Bytes, das ist 1.5% des Flash Speichers
BOOTSZ=3, das bedeutet 1 Boot Seite

Das zweite Beispiel benutzt die automatische Baudratenanpassung

make atmega328p BAUD_RATE=52 LED_START_FLASHES=0

Optiboot für 16000000 Hz (16.00 Mhz) Betrieb mit automatischer Baudrate und EEprom Unterstützung konfiguriert.
 >>> Starte optiboot für AVR atmega328p erstellen:
RX-Pin PD0 benutzt Pin 2-PDIP28 30-TQFP32, mit Spezialfunktionen: PCINT16 RXD. 
TX-Pin PD1 benutzt Pin 3-PDIP28 31-TQFP32, mit Spezialfunktionen: PCINT17 TXD.
avr-gcc -g -Wall -Os -fno-split-wide-types -mrelax -mmcu=atmega328p  -fno-diagnostics-show-caret -DBAUD_RATE=52  -DLED_START_FLASHES=0 -DSUPPORT_EEPROM=1 -DLED=p -DUART=00 -DSOFT_UART=0 -DUART_RX=pD0 -DUART_TX=pD1 -DF_CPU=16000000 -DHFUSE=hexDE -DLFUSE=hexFF -DBOOT_PAGE_LEN=512 -DVerboseLev=2 -c -o optiboot.o optiboot.S
 
--------------------------------------------------------------------------------
Simple Baudrate measurement with time limit implemented in optiboot! (4-bit, Clk/8)
UART Minimum 488 Baud, Difference surely less than 4% up to 160.0 kBaud
--------------------------------------------------------------------------------
# # # # # # # # # # # # # # # # # # # # # # 
Urlader Startadresse: 0x7E00 = 32256
# # # # # # # # # # # # # # # # # # # # # #

   text	   data	    bss	    dec	    hex	filename
    498	      0	      0	    498	    1f2	optiboot.elf 
Benötigt 1 Boot Seite mit 512 Bytes, das ist 1.5% des Flash Speichers

BOOTSZ=3, das bedeutet 1 Boot Seite

Das dritte Bespiel benutzt die automatische Baudratenanpassung mit Software UART

make atmega328p BAUD_RATE=52 LED_START_FLASHES=0 SOFT_UART=1 NO_EARLY_PAGE_ERASE=1

Optiboot für 16000000 Hz (16.00 Mhz) Betrieb mit automatischer Baudrate und EEprom Unterstützung konfiguriert.
 >>> Starte optiboot für AVR atmega328p erstellen:
RX-Pin PD0 benutzt Pin 2-PDIP28 30-TQFP32, mit Spezialfunktionen: PCINT16 RXD.
TX-Pin PD1 benutzt Pin 3-PDIP28 31-TQFP32, mit Spezialfunktionen: PCINT17 TXD.
avr-gcc -g -Wall -Os -fno-split-wide-types -mrelax -mmcu=atmega328p  -fno-diagnostics-show-caret -DBAUD_RATE=52 -DLED_START_FLASHES=0 -DSUPPORT_EEPROM=1 -DNO_EARLY_PAGE_ERASE=1 -DLED=p -DUART=00 -DSOFT_UART=01 -DUART_RX=pD0 -DUART_TX=pD1 -DF_CPU=16000000 -DHFUSE=hexDE -DLFUSE=hexFF -DBOOT_PAGE_LEN=512 -DVerboseLev=2 -c -o optiboot.o optiboot.S
 
--------------------------------------------------------------------------------
Simple Baudrate measurement with time limit implemented in optiboot! (4-bit, Clk/8) 
SoftUART Minimum 10302 Baud, Difference surely less than 4% up to 163.2 kBaud, Fast 8-Bit loop with N*6 cycles
--------------------------------------------------------------------------------
# # # # # # # # # # # # # # # # # # # # # #
Urlader Startadresse: 0x7E00 = 32256
# # # # # # # # # # # # # # # # # # # # # #

   text	   data	    bss	    dec	    hex	filename
    506	      0	      0	    506	    1fa	optiboot.elf
Benötigt 1 Boot Seite mit 512 Bytes, das ist 1.5% des Flash Speichers
BOOTSZ=3, das bedeutet 1 Boot Seite

Hier wurde die Option NO_EARLY_PAGE_ERASE benutzt, um Flash Speicher einzusparen. Ohne diese Option wäre das Ergebnis so:

make atmega328p BAUD_RATE=52 LED_START_FLASHES=0 SOFT_UART=1

Optiboot für 16000000 Hz (16.00 Mhz) Betrieb mit automatischer Baudrate und EEprom Unterstützung konfiguriert.
 >>> Starte optiboot für AVR atmega328p erstellen: 
RX-Pin PD0 benutzt Pin 2-PDIP28 30-TQFP32, mit Spezialfunktionen: PCINT16 RXD.
TX-Pin PD1 benutzt Pin 3-PDIP28 31-TQFP32, mit Spezialfunktionen: PCINT17 TXD.
avr-gcc -g -Wall -Os -fno-split-wide-types -mrelax -mmcu=atmega328p  -fno-diagnostics-show-caret -DBAUD_RATE=52 -DLED_START_FLASHES=0 -DSUPPORT_EEPROM=1 -DLED=p -DUART=00 -DSOFT_UART=01 -DUART_RX=pD0 -DUART_TX=pD1 -DF_CPU=16000000 -DHFUSE=hexDE -DLFUSE=hexFF -DBOOT_PAGE_LEN=512 -DVerboseLev=2 -c -o optiboot.o optiboot.S
 
--------------------------------------------------------------------------------
Simple Baudrate measurement with time limit implemented in optiboot! (4-bit, Clk/8)
SoftUART Minimum 10302 Baud, Difference surely less than 4% up to 163.2 kBaud, Fast 8-Bit loop with N*6 cycles
--------------------------------------------------------------------------------
# # # # # # # # # # # # # # # # # # # # # #
Urlader Startadresse: 0x7C00 = 31744
# # # # # # # # # # # # # # # # # # # # # #

   text	   data	    bss	    dec	    hex	filename
    520	      0	      0	    520	    208	optiboot.elf
Benötigt 2 Boot Seiten, je 512 Bytes, das ist 3.1% des Flash Speichers
BOOTSZ=2, das bedeutet 2 Boot Seiten

Download

Da diese Bootloader-Version zusammen mit dem Transistortester Projekt entstanden ist, befinden sich die Quellen und die Dokomentation im Unterverzeichnis bootloaders des Transistortester Projekts. Damit ist ein Zugriff mit dem Svnbrowser auf https://www.mikrocontroller.net/svnbrowser/transistortester/bootloaders/ möglich. Hier kann auch ein GNU tarball eines vorher angewählten Verzeichnis runtergeladen werden. Mit Linux ist natürlich auch ein Zugriff direkt mit subversion möglich (svn checkout svn://www.mikrocontroller.net/transistortester/bootloaders).