This is an old revision of the document!
» ![]() ![]() |
---|
» ![]() ![]() |
Ein Bootloader ist ein kleines Programm im AVR (bei unseren Reglern meist ein ATMega8), welches am Ende des Flash gespeichert ist. Über entsprechend gesetzte Fuses, wird beim Einschalten des AVR nicht das Hauptprogramm auf Adresse 0, sondern der Bootloader am Ende des Flash gestartet. Der Bootloader wartet jetzt eine Weile ob er angesprochen wird, wenn ja, wird er aktiv, wenn nicht wird das Hauptprogramm (die eigentliche Reglerfirmware) gestartet. Wird der Bootloader aktiv, hat dieser klassischerweise 2 Funktionen: Daten aus einer externen Datenquelle einlesen und diese in den Flash des AVR schreiben. Generell gibt es unterschiedliche Bootloader für UART, SPI, I2C, SD-Karten, Ethernet oder auch, hier wird es interresant: UART über einen einzigen Draht. D.h. in dem hier beschriebenen Fall empfängt unser Bootloader das Programm welches in den Flash des AVR eingespielt werden soll über ein 1-Wire Verbindung zum PC und “brennt” dieses in den Flash des AVR, wo das Programm beim nächsten Reset des AVR - sollte nicht wieder aktiv der Bootloader angesprochen werden - gestartet wird.
Erst wird der Bootloader mittels eines ISP-Adapters in den AVR eingespielt. Anschließend kann durch Verwendung des Bootloaders über eine serielle 1-Draht Verbindung die eigentliche Reglerfirmware in den AVR eingespielt werden. Der Bootloader wird dabei nicht überschrieben und dessen Funktion auch in Zukunft erhalten.
Wir können durch Einsatz des 1-Wire Bootloaders die Regler im Kopter belassen, eingeschrumpft oder in CFK-Rohren verbaut und können einzig über GND und den MOT-Anschluß die Regler mit neuer Firmware versehen.
Da jeder Bootloader über eine eigene Kennung verfügt ist es sogar möglich, z.B. 8 Regler an einer MOT-Leitung verbunden zu programmieren - nicht alle gleichzeitig (dies macht ja keinen Sinn, das “Problem” der Regler-ID/Motornummer stellt sich sonst in den Weg), aber nacheinander, einzeln.
Das ist vor allem praktisch wenn man eine Firmware an neue Motoren anpassen möchte, Anlaufverhalten verbessern möchte und derlei.
Natürlich ist das kein Muss, sondern ein Kann. Eines das sehr zeitsparend sein kann, wenn man mal eine andere Firmware im Regler benötigt.
Neben der Installation des Bootloadercode am AVR, ist die einzige notwendige Vorbereitung am Kopter: Die MOT-Leitung muss vom Armoboard getrennt werden können und an ein hochwissenschaftlich entwickeltes Spezialprogrammierkabel angeschlossen werden.
Da der Bootloader auch im AVR gespeichert werden muss gehen ein paar Byte vom Flash verloren für unsere Anwendung. In dem hier vorgestellten Fall sind das 512 Byte, der verfügbare Flash reduziert sich beim Mega8 damit auf 7,5kB.
Beim Einschalten der Regler startet zuerst der Bootloader der 500ms darauf wartet ob er angesprochen wird. Erst danach wird die Reglerfirmware gestartet. Im Fall der Quax-Software kann man in dieser die 2x “wait260ms” auskommentieren, damit spart man sogar 20ms ;).
Sollte ein Regler im Flugbetrieb resetieren, d.h. der Bootloader aktiv werden während Daten vom ARMO-Board übertragen werden, bleibt der Regler NICHT im Bootloader hängen. Dazu müssten in den ersten 500ms nach dem Reset die passende Kennung vom Bootloader erkannt werden. Selbst wenn diese Sequenz zufälligerweise in den Motorstelldaten vorkommen würde, ist anschließend eine Zwei-Weg Kommunikation zwischen Bootloader und PC-Software notwendig. Da dies im Flugbetrieb nicht auftreten kann, übernimmt nach dem Bootloadertimeout von 500ms die Reglerfirmware den Betrieb (und versucht sofort den Motor zu starten da Sollwerte vom ARMO-Board empfangen werden).
Dieser Artikel bezieht sich auf die Version 6 von Hagen's Bootloader!
Im Groben sieht die Verwendung des Bootloaders so aus, Details zu den einzelnen Schritten sind weiter unten beschrieben:
Jeder AVR sollte mit einer eigenen Bootloaderkennung programmiert werden, d.h. mit einer anderen HEX-Datei. Geschieht dies nicht, können die Regler mit der gleichen Kennung später nicht über eine gemeinsame Leitung angesprochen werden! Entsprechend sollte (von außerhalb erkennbar) jeder Regler markiert werden, um (vielleicht auch mal Jahre?) später die richtige Bootloaderkennung von der Beschriftung ableiten zu können. Ist die Bootloaderkennung eines Reglers nicht mehr bekannt, kann natürlich der Bootloader über ISP neu geflashed werden, dazu ist dann aber wieder der ISP-Adapter und ein auspacken des Reglers notwendig und die ganze Arbeit mit dem Bootloader ad absurdum geführt.
Die Bootloaderkennung ist nicht mit der Motornummer zu verwechseln!
Das ganze benötigte Paket besteht aus
Für unsere Anwendung (TTL & 1-wire) sind gegenüber der Standarddistribution ein paar Anpassungen notwendig, diese sind in den verlinkten Dateien bereits berücksichtigt und im folgenden dokumentiert.
Generell hat der Bootloader noch einige Zusatzfunktionen, so könnte die Firmwaredatei verschlüsselt werden, Versionschecks durchgeführt werden, EEPROM und RAM ausgelesen und modifiziert werden. Diese Funktionen sind in den bereitgestellten HEX-Dateien komplett deaktiviert da für die Reglerprogrammierung nicht notwendig und der durch den Bootloader im AVR benötigte Speicher so gering wie möglich gehalten wird.
In der avrootloader.ini ist eine Anpassung vorzunehmen:
Sind eigene HEX-Dateien vom Bootloader zu erstellen, so kann der Originalsourcecode von Hagen verwendet werden, in diesem Fall sind die im weiteren genannten Anpassungen zu beachten. Wird der hier bereitgestellt Sourcecode genutzt ist für einen ATMega8 lediglich die jeweilige Bootloaderkennung zu ändern und beim kompilieren die Vorkehrungen für den Wert CodeSize zu treffen.
In der avrootloader.asm gilt es ein paar Anpassungen vorzunehmen:
.include "m8def.inc" ; ATmega8
Achtung, es darf nur ein Definitionsdatei aktiviert sein, d.h. es ist sicherzustellen das in diesem Block keine weitere Datei inkludiert wird.
Im folgenden die Standardparameter mit welchen die bereitgestellten HEX-Dateien erstellt wurden:
.equ UseWDR = 0 ; Watchdog support (2 sec timeout, remember to deactivate WDT in your application if not needed) .equ UseSaveMCUSR = 0 ; save MCUSR on stack (RAMEND) for access by application (on UseWDR=1 MCUSR must be cleared) .equ UseE2Write = 0 ; EEPROM write command (have implicit verify) .equ UseE2Read = 0 ; EEPROM read command .equ UseCrypt = 0 ; cryptography (crypt.inc) .equ UseCryptFLASH = 0 ; explicit use of cryptography for writing to FLASH .equ UseCryptE2 = 0 ; explicit use of cryptography for writing to EEPROM .equ UseVerify = 0 ; Verify FLASH command (FLASH write/erase have implicit verify, can be deactivated) .equ UseVersioning = 0 ; Versioning for application software (stored 4/6 bytes before BootStart) .equ UseSRAM = 0 ; SRAM read/write commands (attention! can be a security risk) .equ UseSpecialBootVect = 0 ; use a rjmp BootStart at end of FLASH to start bootloader from application code .equ UseSpecialWrite = 0 ; special function "write_flash" to reprogram FLASH .equ UseSpecialWriteBoot = 0 ; "write_flash" can write to bootloader section with magic code, only usefull if SPM is allowed by lockbit fuses in BLS .equ UseSpecialRead = 0 ; special function "read_flash" to read from FLASH .equ UseSpecialMsg = 0 ; special function to return address and size of BootMsg ; look into AVRootloader.h and M162 test project in folder \test\ for use of special funcs .equ UseAutobaud = 1 ; Baudrate detection .equ UseResetDelay = 0 ; Reset the boot delay everytime if any activity is detected on RX pin. ; First after BootDelay milliseconds inactivity the application is called. ; Otherwise the timeout BootDelay defines an overall timeout for connection. .equ UseUartInvert = 1 ; invert UART levels (for RS232 drivers such as MAX232) .equ UseRS485 = 0 ; activate RS-485 Data Enable pin .equ UseRS485Invert = 0 ; inverted logic of RS-485 DE pin (HIHGH for receive, LOW for transmit) .equ RX_PORT = PORTD ; Receive port and pin .equ RX = PD0 .equ TX_PORT = PORTD ; Transmit port and pin .equ TX = PD0 .if UseRS485 .equ DE_PORT = PORTB ; DE enable pin of RS-485 .equ DE = PB2 ; must be only set if RS485 DE is used .endif .set XTAL = 16000000 ; .set BootDelay = XTAL/2 ; about 250ms (don't set to fast to avoid connection problems) .set BootBaudrate = 115200 ; only used if no Baudrate detection activated, XTAL is than important .set BootVersion = 6 ; Version 6 (must be not changed) .set BootCodeSize = 412 ; set to 0, compile and set to value in [.cseg] Used, compile again ; after this step cseg used is +2 bytes greater, ignore it (AVRStudio 4.16 bugfix)
Wichtig sind die Parameter UseUartInvert & UseResetDelay auf 0, die Bootbaudrate ist egal solange UseAutoBaud = 1.
Die Bootloaderkennung ist die eindeutige ID über welche ein einzelner Bootloader angesprochen werden kann. Diese sollte nicht zu kurz sein, da der Bootloader im AVR eine automatische Baudratenerkennung verwendet, diese am Anfang der Kommunikation - wo auch die Bootloaderkennung vom PC gesendet wird - aktiv ist und es bei kurzen Kennungen zu einer geringeren Erfolgsquote bei den Verbindungsversuchen kommen kann.
In den bereitgestellten HEX-Dateien ist die Kennung “BLCLOADER1”, “BLCLOADER2” … “BLCLOADER8” - entsprechend dem Dateinamen des jeweiligen HEX-Files.
Groß & Kleinschreibung sind hier zu beachten
BootSign: .db "BLCLOADER1"
Sollen mehrere AVRs an einer Leitung programmiert werden (= in einem Kopter verbaut werden), so benötigt jeder dieser Regler eine eindeutige Bootloaderkennung!
Beim Kompilieren der Firmware ist nach jeglichen Anpassungen zuerst die Variable CodeSize auf 0 zu setzen und die Kompilierung einmalig durchzuführen. AVRStudio listet am Ende des Übersetzungsvorganges auf, wieviel Speicher in welchem Bereich vom Kompilat belegt wird. Hier ist in der Spalte [cseg] der Wert in der Zeile “used” auszulesen und bei CodeSize einzutragen. Anschließend kompiliert man nochmals, der von AVRStudio gezeigte Wert bei [cseg]/used erhöht sich um 2 Byte gegenüber dem eingestellten - das ist in Ordnung.
Die Installation der vor- oder selbstgefertigen HEX-Datei erfolgt mittles ISP Adapter auf dem gleichen weg wie jedes andere HEX-File mittels ISP programmiert wird. Für den Spezialfall Bootloader sind anschließend Fuses zu programmieren, im Fall des ATMega8 sind dies BOOTRST & BOOTSZ:
AVR-Studio:
PonyProg:
Bei den bereitgestellten HEX-Dateien ist als Startadresse $0F00 einzustellen (“SecondBootStart”), nimmt man Änderungen an den Einstellungen vor sind die Ausgaben von AVRStudio beim kompilieren zu beachten, hier findet eine Ausgabe “Set BOOTSZ to…” statt welche als Hinweis für den korrekten Wert der BOOTSZ Fuse dient.
Wie im Bild zu sehen sollte die High-Fuse auf 0xCC und die Low-Fuse auf 0x2E programmiert werden.
Da jedes ISP-Programm und Adapter hier anders umgeht ist besondere Vorsicht geboten. Manchmal bedeuted ein gesetztes Häckchen das die Fuse gesetzt ist (was aber beim AVR den BitWert 0 entspricht, manchmal bezieht sich das gesetzte Häckchen aber auf das FuseBit selbst, d.h. wird genau umgekehrt interpretiert).
Ein paar weiterführende Links zum Thema AVR & ISP, Fuses und den dazugehörigen Programmen:
» ![]() ![]() |
---|
Der Bootloader selbst wird mittels ISP in den AVR übertragen, dazu ist neben dem üblichen ISP Adapter keine besondere Hardware notwendig. Wird über den Bootloader Firmware in den AVR übertragen, so ist speziell zur 1-wire Kommuniktaion ein “Spezialkabel” notwendig.
Das dargestellt Kabel entspricht der Schaltung von Hagen, da gerade bei 1-wire & TTL der Pullupwiderstand je nach Anzahl der AVRs an der Leitung angepasst werden muss, teils entfernt oder durch einen Pulldown ersetzt werden muss, empfiehlt sich eine flexiblere Variante des Kabels zu basteln:
Im Beispiel ist das Kabel an einem FTDI USB Wandler von Sparkfun angeschlossen.
Schaltung TTL Adapterkabel. Der Widerstand R2 wird entweder als Pullup oder Pulldown gesteckt, je nach Anforderung der Regler. Einen Kurzschluß zu produzieren oder Energie in Wärme umzuwandeln ist nicht das Ziel ;)
Prinzipiell muss ein Pullup-Widerstand an der 1-Wire Leitung angeschlossen werden, der PullUp sollte zum VCC vom TTL-Adapter verbunden werden (kann aber auch mit VCC vom Regler beschalten werden. Dieser Pullup sollte zwischen 10 und 100k liegen.
Je nach Regler kann es aber sein, das dort bereits ein Pullup-Widerstand eingebaut ist, des weiteren ist das verhalten bei mehreren verbundenen AVRs anders. Hier muss man also ggf. je Regler ein wenig experimentieren.
Erfahrungswerte mit weiteren, noch nicht gelisteten Reglern Bitte hier einpflegen!
Reglertyp | Pullup/down Werte | |||||||
---|---|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
Mystery 12A / Hobbyking MT12A Blue Series Forendownload der Umbauanleitung | 10-100k Pullup | 10k Pulldown | 10k Pulldown | 4k7 Pulldown | n.g. | n.g. | n.g. | n.g. |
Mystery 20A / Hobbyking MT20A Blue Series LINK | keine Widerstände | n.g. | n.g. | 4k7 Pulldown | n.g. | n.g. | n.g. | n.g. |
Mystery 30A / Hobbyking MT30A Blue Series LINK | n.g. | n.g. | n.g. | n.g. | n.g. | keine Widerstände | n.g. | n.g. |
Mystery 40A / Hobbyking MT40A Blue Series Forendownload der Umbauanleitung Forendownload der Umbauanleitung | 4k7 Pulldown | 4k7 Pulldown | 4k7 Pulldown | 4k7 Pulldown | n.g. | n.g. | n.g. | n.g. |
Hobbyking 18A und andere ohne Pull-Up am UART Forendownload der Umbauanleitung | kein Pullup/Down | kein Pullup | kein Pullup/Down | kein Pullup/Down | n.g. | n.g. | n.g. | n.g. |
Turborix 30A Forendownload der Umbauanleitung | kein Pullup/Down | kein Pullup/Down | kein Pullup/Down | kein Pullup/Down | 4k7 Pulldown | 4k7 Pulldown | n.g. | n.g. |
n.g. - nicht getestet
Über RS232 sollte sich mithilfe des Bootloaders ebenfalls im 1-wire Betrieb neue Firmware auf AVRs übertragen lassen, dies habe ich aber noch nicht getestet. Als Vorlage würde natürlich die Kabelbeschaltung von Hagen im mikrocontroller.net Wiki dienen, eventuell sind auch hier je nach Anzahl der AVRs Anpassungen bei den PullDown/-Up Widerständen notwendig