AVR Bootloader optiboot Assemblerversion
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.
- LFUSE : Gibt einen Wunschwert für die Low Fuse des AVR an. Erlaubt ist nur die Angabe von zwei Hex Zeichen.
- HFUSE : Gibt einen Wunschwert für die High Fuse des AVR an. Erlaubt ist nur die Angabe von zwei Hex Zeichen.
- EFUSE : Gibt einen Wunschwert für die Extendet Fuse des AVR an. Erlaubt ist nur die Angabe von zwei Hex Zeichen.
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.
Tipps für die Benutzung der Optiboot Erzeugung
Es ist sinnvoll, zunächst mit einer Standardeinstellung für einen der AVR-Prozessoren zu beginnen und dabei die Bildschirmausgabe zu prüfen, ob die Voreinstellungen passen. So erzeugt beispielsweise make atmega8 einen Bootloader für den ATmega8 Mikrocontroller. Aus der Bildschirmausgabe kann man erkennen, daß der Bootloader für einen 16 MHz Betrieb mit einer Baudrate von 115200 der seriellen Schnittstelle konfiguriert wurde. Die benutzten Pins für die serielle Kommunikation (RX und TX) werden ebenso aufgezählt wie der benutzte Pin für eine Kontroll-LED (PB5). Mit zusätzlichen Optionen in der make Zeile kann man die Einstellungen dann ändern und mit einem erneuten Durchlauf das Bildschirmprotokoll wieder prüfen. Dabei kann man auch die Größe des erzeugten Bootloaders im Auge behalten. Wenn eine passende Konfiguration gefunden ist, kann man den optiboot mit dem zusätzlichen Parameter ISP=1 bei korrekt angeschlossenem ISP Programmer mit dem Programm avrdude installieren.
Erstes Beispiel mit ATmega8 ohne Quarz
Wenn der ATmega8 ohne Quarz betrieben werden soll, muß die Standardeinstellung der Low Fuse geändert werden z.B. auf LFUSE=E4 für den internen RC Taktgenerator. Dann passen aber sowohl die voreingestellte Taktrate als auch die Baudrate nicht mehr. Also sollte der korrekte Aufruf für die Erzeugung des passenden Bootloaders dann make atmega8 LFUSE=E4 F_CPU=8000000 BAUD_RATE=57600 lauten. Dieser Bootloader sollte jetzt auch ohne Quarzbetrieb laufen. Vorraussetzung ist aber, daß die Arbeitsfrequenz von 8 MHz auch relativ genau eingehalten wird. Sollte das nicht der Fall sein, gibt es nun zwei Möglichkeiten, das Problem zu lösen.
- Die erste Möglichkeit nutzt die Fähigkeit der AVR-Prozessoren, den RC-Oszillator abzustimmen. Für die Optiboot-Erzeugung kann das mit der Option OSCCAL_CORR genutzt werden. Dazu ist aber eine Möglichkeit zur Kontrolle der Arbeitsfrequenz erforderlich wie ein Frequenzzähler oder ein Oszilloskop. Da dieser Prozessor aber auch keine Möglichkeit hat, die Taktfrequenz auf einem Ausgabepin herauszuführen, müsste man ein Testprogramm für die Kontrolle der Frequenz schreiben. Der Bootloader optiboot hat aber auch eine nicht weiter dokumentierte Option TEST_OUTPUT, mit der der Bootloader nach dem Start nichts anderes macht, als fortwährend das gleiche Zeichen U auf den seriellen Ausgabepin auszugeben. So wäre zwar der Abgleich der Oszillator-Frequenz möglich, das ist aber doch sehr mühsam und muß natürlich für jedes Exemplar erneut wiederholt werden.
- Die zweite Möglichkeit nutzt eine ganz andere Fähigkeit des optiboot, die automatische Baudraten-Anpassung. Hier wird die Übertragungszeit der seriellen Bits des ersten empfangenen Zeichens ausgemessen und dabei die passende Baudrate eingestellt. Das können wir als nächstes mit make atmega8 LFUSE=E4 F_CPU=8000000 BAUD_RATE=32 ausprobieren. Hier teilt uns die Bildschirmausgabe mit, daß eine Baudrate zwischen 244 und 80k möglich ist. Doch leider braucht das Programm jetzt 518 Bytes und damit würde es 1024 Bytes Flash Speicher belegen. Der Bootloader würde zwar laufen, aber es müssen nur 6 Byte eingespart werden, um mit der Hälfte des Speichers auszukommen. Mit der BAUD_RATE=22 für das Messen von nur 2 Bits statt 4 Bits würde man nur 4 Byte sparen und das wäre auch schon die sparsamste Variante der Baudratenmessung. Nun gibt es aber noch drei weitere Möglichkeiten Platz zu sparen. Man könnte auf die Fähigkeit zum Beschreiben des EEproms verzichten (SUPPORT_EEPROM=0), auf das LED-Blinken beim Start verzichten (LED_START_FLASHES=0) oder auf das Löschen der Flash-Speicherseite vor dem Datenempfang (NO_EARLY_PAGE_ERASE=1) verzichten. Alle drei Möglichkeiten führen zum Erfolg, kosten aber auch Funktion. Ein ebenfalls möglicher Kompromiss wäre nur einmal Blinken (LED_START_FLASHES=1) oder auf die Überwachung des seriellen Eingangs beim Blinken zu verzichten (LED_START_FLASHES=-3). Man kann auch das Blinken ganz abwählen (LED_START_FLASHES=0) und statt dessen die LED_DATA_FLASH Funktion benutzen. Was auch immer man wählt, die 6 Byte sind leicht einzusparen ohne viel an Funktion einzubüßen. Der Aufwand ist überschaubar und mehr Speicher wird bei sorgfältiger Konfiguration auch nicht belegt.
Zweites Beispiel ATtiny84 mit RC-Oszillator, Autobaud und Ein-Pin serieller Schnittstelle
Da der Standardbetrieb mit Quarz vorgesehen ist, müssen wir zunächst der RC-Oszillatorbetrieb mit einer Vorgabe für die Low Fuse starten wie make attiny84 LFUSE=E2 F_CPU=8000000 BAUD_RATE=32. Hier erfahren wir aus dem Bildschirmprotokoll, daß 10 Flash Speicherseiten für den Bootloader benutzt werden. Ein spezieller Bootbereich ist für diesen Prozessor nicht vorhanden. Deshalb braucht hier auch die Option VIRTUAL_BOOT_PARTITION nicht angegeben zu werden. Für die serielle Schnittstelle würden hier die Pinne A3 und A4 von der Software benutzt. Ein UART ist ja auch nicht vorhanden beim ATtiny84. Wir wollten ja aber nur einen Pin für die serielle Kommunikation benutzen. Das ist einfach möglich durch die Benennung des gleichen Wunschpins für TX und RX. Also muß der Aufruf make attiny84 LFUSE=E2 F_CPU=8000000 BAUD_RATE=32 UART_RX=A4 UART_TX=A4 lauten. Wenn man keine blinkende Kontroll-LED haben möchte, kann man die mit LED_START_FLASHES=0 abwählen. Weniger Speicherseiten werden dadurch aber nicht belegt. Für den Betrieb der seriellen Schnittstelle mit nur einem Pin muß man durch eine Zusatzschaltung dafür sorgen, daß die Echos des Sendesignals TXD des PCs zum Empfangssignal RXD des PCs unterdrückt werden. Bei dem von avrdude verwendeten STK500 Protokoll wird im Halbduplexbetrieb gearbeitet. Es sendet im Regelfall immer nur eine Seite zur gleichen Zeit. Wenn die PC-Seite sendet, werden die Daten zum AVR über den 1k Widerstand weitergeleitet. Wenn der AVR dann die Antwort sendet, ist der TX Pegel des PCs im Ruhezustand, also 5V. Der 1k Widerstand dient dann als Pullup Widerstand für die TX Funktion des AVR, der nur die 0V Pegel aktiv schaltet. Beide gezeigten Schaltungen leiten die 0V Daten des AVR leicht verzögert über die CMOS Gatter zum RX-Pin des PCs weiter. Wenn der PC selber den 0V Pegel sendet, wird entweder über den zweiten NAND Gatter Eingang (Pin 6) oder über die Dioden der zweiten Schaltung die Rückmeldung des 0-Pegels zum RX-Pin des PCs verhindert. Damit auch keine Impulse an den Schaltflanken durchkommen, wird bei der ersten Schaltung der 0V Pegel nur leicht verzögert und die Rückkehr zum 5V Pegel deutlich länger verzögert. Die 0V Verzögerung muß dabei kleiner sein als die Gatterverzögerung des ersten NAND Gatters. Bei der zweiten Schaltung sperrt eine Diode das 0V Signal direkt, die zweite Diode sperrt mit dem durch zwei Inverter und zusätzlichem RC-Glied verzögerten 0V Signal. Dadurch ist ein Betrieb des unveränderten avrdude möglich.
Alternativ ist auch eine Schaltung mit dem 6-Fach Inverter 74HC14 möglich, der ebenfalls Schmitt Trigger Eingänge besitzt.
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
Das vierte Beispiel erzeugt einen Bootloader für eine ATtiny84
make attiny84 Optiboot für 8000000 Hz (8.00 Mhz) Betrieb mit Baudrate 57600 und EEprom Unterstützung konfiguriert. >>> Starte optiboot für AVR attiny84 erstellen: LED-Pin PA4 benutzt Pin 9-PDIP14 1-QFN20, mit Spezialfunktionen: PCINT4 T1 SCL USCK ADC4. RX-Pin PA3 benutzt Pin 10-PDIP14 2-QFN20, mit Spezialfunktionen: PCINT3 T0 ADC3. TX-Pin PA4 benutzt Pin 9-PDIP14 1-QFN20, mit Spezialfunktionen: PCINT4 T1 SCL USCK ADC4. avr-gcc -g -Wall -Os -fno-split-wide-types -mrelax -mmcu=attiny84 -fno-diagnostics-show-caret -DBAUD_RATE=57600 -DLED_START_FLASHES=3 -DSUPPORT_EEPROM=1 -DVIRTUAL_BOOT_PARTITION=1 -DLED=pA4 -DUART=00 -DSOFT_UART=01 -DUART_RX=pA3 -DUART_TX=pA4 -DF_CPU=8000000 -DHFUSE=hexDD -DLFUSE=hexFF -DBOOT_PAGE_LEN=64 -DVerboseLev=2 -c -o optiboot.o optiboot.S -------------------------------------------------------------------------------- BAUD RATE CHECK: Desired: 57600, SoftUART_Real: 57553, Delay: 116*1, Difference=-.07% -------------------------------------------------------------------------------- # # # # # # # # # # # # # # # # # # # # # # Urlader Startadresse: 0x1D80 = 7552 # # # # # # # # # # # # # # # # # # # # # # text data bss dec hex filename 580 0 0 580 244 optiboot.elf Benötigt 10 Flash Seiten, je 64 Bytes, das ist 7.8% des Flash Speichers Keine Boot Seiten vorhanden!
Zwei Beispiele für eine fehlerhafte LFUSE Einstellung
Im ersten Beispiel paßt die Betriebsfrequenz 16 MHz nicht zu dem gewählten RC-Oszillator Betrieb. Korrekt wäre ein Aufruf wie make atmega328p LFUSE=E2 F_CPU=8000000 BAUD_RATE=38400. Hier soll aber gezeigt werden, daß beim Erstellen des Bootloaders versucht wird, Fehler zu vermeiden.
make atmega328p LFUSE=E2 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=0 -DUART_RX=pD0 -DUART_TX=pD1 -DF_CPU=16000000 -DHFUSE=hexDE -DLFUSE=hexE2 -DBOOT_PAGE_LEN=512 -DVerboseLev=2 -c -o optiboot.o optiboot.S In file included from optiboot.S:277:0: check_fuses.h:212:5: Fehler: #error "Int RC mode, wrong Lfuse setting for this frequency (ATmega...8)!" Makefile:1191: recipe for target 'hex_file' failed make: *** [hex_file] Error 1
In nächsten Beispiel paßt die Betriebsfrequenz nicht zu dem Quarzbetrieb mit dem /8 Vorteiler. Korrekt wäre hier ein Kommando wie make atmega329p LFUSE=7F F_CPU=1000000 BAUD_RATE=9600. Aber hier wieder zur Demonstration der falsche Aufruf:
make atmega328p LFUSE=7F 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=0 -DUART_RX=pD0 -DUART_TX=pD1 -DF_CPU=16000000 -DHFUSE=hexDE -DLFUSE=hex7F -DBOOT_PAGE_LEN=512 -DVerboseLev=2 -c -o optiboot.o optiboot.S In file included from optiboot.S:277:0: check_fuses.h:254:5: Fehler: #error "LP Crystal mode, wrong Lfuse setting for this frequency (ATmega...8)!" Makefile:1191: recipe for target 'hex_file' failed make: *** [hex_file] Error 1
Bootloader für Arduino-Nano mit automatischer Baudraten-Anpassung inklusive avrdude Aufruf
make atmega328p BAUD_RATE=52 LED_START_FLASHES=0 ISP=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=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 ####### Start von program_target.sh für atmega328p ############# Die Fuses in program_target.sh sind gesetzt auf lfuse=0xFF, hfuse=0xDE, efuse=0xFD Bootloader HFUSE wird auf 0xDE gesetzt, OK! BootLoader Startadresse ist gesetzt auf 0x7E00, 32256 ##### Lösche den atmega328p und setze die Fuses avrdude -C ./avrdude.conf -c avrisp2 -B 200 -p atmega328p -P usb -b 115200 -q -q -e -u -U efuse:w:0xFD:m -U hfuse:w:0xDE:m -U lfuse:w:0xFF:m ##### Schreibe den optiboot Bootloader auf atmega328p und setze die Lock Bits avrdude -C ./avrdude.conf -c avrisp2 -B 1.50 -p atmega328p -P usb -b 115200 -D -U flash:w:optiboot_atmega328p.hex:i -U lock:w:0xef:m
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e950f (probably m328p) avrdude: reading input file "optiboot_atmega328p.hex" avrdude: writing flash (32768 bytes):
Writing | ################################################## | 100% 0.00s
avrdude: 32768 bytes of flash written avrdude: verifying flash memory against optiboot_atmega328p.hex: avrdude: load data flash data from input file optiboot_atmega328p.hex: avrdude: input file optiboot_atmega328p.hex contains 32768 bytes avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ... avrdude: 32768 bytes of flash verified avrdude: reading input file "0xef" avrdude: writing lock (1 bytes):
Writing | ################################################## | 100% 0.01s
avrdude: 1 bytes of lock written avrdude: verifying lock memory against 0xef: avrdude: load data lock data from input file 0xef: avrdude: input file 0xef contains 1 bytes avrdude: reading on-chip lock data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ... avrdude: 1 bytes of lock verified
avrdude: safemode: Fuses OK (E:FD, H:DE, L:FF)
avrdude done. Thank you.
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).
Inzwischen wurde der bootloader aus dem Transistortester Projekt herausgelöst und auf github verschoben. Zu finden hier: https://github.com/kubi48/avr-assembler-optiboot