Ein Bootloader ist ein Programm, das im zu programmierenden Mikrocontroller abläuft. Es empfängt neue Programminformationen extern über ein Kommunikationsmittel und schreibt diese Informationen in den Programmspeicher des Prozessors.
Dies steht im Gegensatz zu der normalen Art, das Programm in den Mikrocontroller zu bekommen, der zu diesem Zweck über spezielle Hardware in das Mikro eingebaut ist. Bei PICs ist dies eine SPI-ähnliche Schnittstelle. Wenn ich mich recht erinnere, verwenden AVRs Jtag oder zumindest einige von ihnen. In beiden Fällen ist eine externe Hardware erforderlich, die die Programmierstifte genau richtig bewegt, um die Informationen in den Programmspeicher zu schreiben. Die HEX-Datei, die den Inhalt des Programmspeichers beschreibt, stammt von einem Universalcomputer, sodass diese Hardware auf der einen Seite mit dem Computer und auf der anderen Seite mit den speziellen Programmierstiften des Mikros verbunden ist. Mein Unternehmen stellt PIC-Programmierer unter anderem als Nebentätigkeit zur Verfügung, daher bin ich mit diesem Prozess für PICs bestens vertraut.
Der wichtige Punkt der externen Programmierung über spezielle Hardware ist, dass sie unabhängig von den vorhandenen Inhalten des Programmspeichers funktioniert. Mikrocontroller beginnen mit einem gelöschten oder unbekannten Programmspeicher, sodass nur durch externe Programmierung das erste Programm in ein Mikro geschrieben werden kann.
Wenn Sie sich sicher sind, welches Programm Sie in Ihr Produkt laden möchten und Ihr Volumen hoch genug ist, können Sie den Hersteller oder einen Distributor Programmchips für Sie haben. Der Chip wird wie jeder andere Chip auf die Platine gelötet und das Gerät ist betriebsbereit. Dies kann zum Beispiel für ein Spielzeug angemessen sein. Sobald die Firmware fertig ist, ist sie ziemlich fertig und wird in großen Mengen produziert.
Wenn Ihr Volumen geringer oder wichtiger ist, erwarten Sie eine kontinuierliche Firmware-Entwicklung und Fehlerbehebungen. Sie möchten keine vorprogrammierten Chips kaufen. In diesem Fall werden leere Chips auf die Platine montiert und die Firmware muss im Rahmen des Produktionsprozesses auf den Chip geladen werden. In diesem Fall müssen die Hardware-Programmierzeilen irgendwie zur Verfügung gestellt werden. Dies kann über einen expliziten Anschluss oder über Pogo-Pin-Pads erfolgen, wenn Sie bereit sind, eine Produktionstestvorrichtung zu erstellen. Oft müssen solche Produkte trotzdem getestet und kalibriert werden, so dass die zusätzlichen Kosten für das Schreiben des Programms auf den Prozessor in der Regel minimal sind. Manchmal, wenn kleine Prozessoren verwendet werden, wird zuerst eine spezielle Firmware für den Produktionstest in den Prozessor geladen. Dies erleichtert das Testen und Kalibrieren des Geräts. Dann wird die echte Firmware geladen, nachdem bekannt ist, dass die Hardware funktioniert. In diesem Fall gibt es einige Überlegungen zum Schaltungsentwurf, um den Zugriff auf die Programmierleitungen ausreichend zu ermöglichen, damit der Programmiervorgang funktioniert, aber auch um die Schaltung nicht zu sehr zu stören. Weitere Einzelheiten hierzu finden Sie unter myIn-Circuit-Programmierung schreiben.
Soweit so gut und es wird kein Bootloader benötigt. Ziehen Sie jedoch ein Produkt mit einer relativ komplexen Firmware in Betracht, die vor Ort aktualisiert werden soll, oder lassen Sie sogar zu, dass der Endkunde ein Upgrade durchführt. Sie können nicht davon ausgehen, dass der Endkunde über ein Programmiergerät verfügt oder weiß, wie man eines richtig einsetzt, selbst wenn Sie eines zur Verfügung gestellt haben. Eigentlich macht das einer meiner Kunden. Wenn Sie ihre spezielle Feldanpassungsoption kaufen, erhalten Sie einen meiner Programmierer mit dem Produkt.
In den meisten Fällen möchten Sie jedoch, dass der Kunde ein Programm auf einem PC ausführt und die Firmware auf magische Weise aktualisiert. Hier kommt ein Bootloader ins Spiel, insbesondere wenn Ihr Produkt bereits über einen Kommunikationsanschluss verfügt, der problemlos mit einem PC wie USB, RS-232 oder Ethernet verbunden werden kann. Der Kunde führt ein PC-Programm aus, das bereits im Micro mit dem Bootloader kommuniziert. Dadurch wird die neue Binärdatei an den Bootloader gesendet, der sie in den Programmspeicher schreibt und dann den neuen Code ausführt.
Klingt einfach, ist es aber nicht, zumindest nicht, wenn dieser Prozess robust sein soll. Was ist, wenn ein Kommunikationsfehler auftritt und die neue Firmware zum Zeitpunkt des Eintreffens beim Bootloader beschädigt ist? Was ist, wenn die Stromversorgung während des Startvorgangs unterbrochen wird? Was ist, wenn der Bootloader einen Bug hat und auf sich selbst scheißt?
Ein vereinfachtes Szenario ist, dass der Bootloader immer nach dem Zurücksetzen ausgeführt wird. Es wird versucht, mit dem Host zu kommunizieren. Wenn der Host antwortet, teilt er dem Bootloader entweder mit, dass er nichts Neues hat, oder sendet ihm neuen Code. Wenn der neue Code eintrifft, wird der alte Code überschrieben. Sie fügen immer eine Prüfsumme mit hochgeladenem Code ein, damit der Bootloader erkennen kann, ob die neue App intakt ist. Wenn nicht, bleibt es im Bootloader und fordert ständig einen Upload an, bis etwas mit einer gültigen Prüfsumme in den Speicher geladen wird. Dies kann für ein Gerät akzeptabel sein, das immer verbunden ist und auf dem Host möglicherweise eine Hintergrundaufgabe ausgeführt wird, die auf Bootloader-Anforderungen reagiert. Dieses Schema eignet sich nicht für Einheiten, die weitgehend autonom sind und nur gelegentlich eine Verbindung zu einem Host-Computer herstellen.
Normalerweise ist der oben beschriebene einfache Bootloader nicht akzeptabel, da kein Fail-Safe besteht. Wenn ein neues App-Image nicht intakt empfangen wird, soll das Gerät das alte Image weiterhin ausführen und nicht tot sein, bis ein erfolgreicher Upload durchgeführt wurde. Aus diesem Grund enthält die Firmware normalerweise zwei spezielle Module, einen Uploader und einen Bootloader. Der Uploader ist Teil der Haupt-App. Im Rahmen der regelmäßigen Kommunikation mit dem Host kann ein neues App-Image hochgeladen werden. Dies erfordert einen vom Haupt-App-Image getrennten Speicher, z. B. ein externes EEPROM, oder verwendet einen größeren Prozessor, sodass die Hälfte des Programmspeicherplatzes für die Speicherung des neuen App-Image reserviert werden kann. Der Uploader schreibt nur das empfangene neue App-Image, führt es jedoch nicht aus. Wenn der Prozessor zurückgesetzt wird, was auf Befehl des Hosts nach einem Upload passieren kann, Der Bootloader läuft. Dies ist jetzt ein völlig eigenständiges Programm, das keine externe Kommunikationsfähigkeit benötigt. Es vergleicht die aktuelle und die hochgeladene App-Version, überprüft deren Prüfsummen und kopiert das neue Image in den App-Bereich, wenn sich die Versionen unterscheiden, und überprüft die neue Image-Prüfsumme. Wenn das neue Image beschädigt ist, wird die alte App einfach wie zuvor ausgeführt.
Ich habe viele Bootloader gemacht, und keiner ist derselbe. Es gibt keinen Allzweck-Bootloader, auch wenn einige der Mikrocontroller-Unternehmen dies wünschen. Jedes Gerät hat seine eigenen Anforderungen und besonderen Umstände im Umgang mit dem Host. Hier sind nur einige der Bootloader- und manchmal Uploader-Konfigurationen, die ich verwendet habe:
- Einfacher Bootloader. Dieses Gerät hatte eine serielle Leitung und wurde an einen Host angeschlossen und bei Bedarf eingeschaltet. Der Bootloader wurde nach dem Zurücksetzen ausgeführt und hat einige Antworten auf Upload-Anforderungen an den Host gesendet. Wenn das Upload-Programm ausgeführt wird, antwortet es und sendet ein neues App-Image. Wenn es nicht innerhalb von 500 ms antwortet, gibt der Bootloader die vorhandene App auf und führt sie aus. Um die Firmware zu aktualisieren, mussten Sie zuerst die Updater-App auf dem Host ausführen, dann die Verbindung herstellen und das Gerät einschalten.
- Programmspeicher-Uploader. Hier haben wir das nächstgrößere PIC verwendet, das doppelt so viel Programmspeicher hatte. Der Programmspeicher wurde grob in 49% Haupt-App, 49% neues App-Image und 2% Bootloader aufgeteilt. Der Bootloader wird nach dem Zurücksetzen ausgeführt und kopiert das neue App-Image unter den richtigen Bedingungen auf das aktuelle App-Image.
- Externes EEPROM-Image. Wie Nr. 2, außer dass ein externes EEPROM zum Speichern des neuen App-Images verwendet wurde. In diesem Fall wäre der Prozessor mit mehr Arbeitsspeicher auch physisch größer und in einer anderen Unterfamilie, die nicht über den von uns benötigten Peripheriemix verfügte.
- TCP-Bootloader. Dies war der komplexeste von allen. Ein großer PIC 18F wurde verwendet. Das letzte Viertel des Arbeitsspeichers enthielt den Bootloader, der über eine eigene vollständige Kopie eines TCP-Netzwerkstapels verfügte. Der Bootloader wurde nach dem Zurücksetzen ausgeführt und hat versucht, eine Verbindung zu einem speziellen Upload-Server an einem bekannten Port mit einer zuvor konfigurierten IP-Adresse herzustellen. Dies galt für große Installationen, bei denen immer ein dedizierter Server für das gesamte System vorhanden war. Jedes kleine Gerät meldet sich nach dem Zurücksetzen beim Upload-Server an und erhält bei Bedarf eine neue App-Kopie. Der Bootloader würde die vorhandene App mit der neuen Kopie überschreiben, sie jedoch nur ausführen, wenn die Prüfsumme überprüft wurde. Wenn nicht, kehrt es zum Upload-Server zurück und versucht es erneut.
Da der Bootloader selbst ein komplizierter Code war, der einen vollständigen TCP-Netzwerkstapel enthielt, musste er auch vor Ort aktualisierbar sein. Die Art und Weise, wie wir das gemacht haben, war, dass der Upload-Server ihm eine spezielle App zufüttert, deren einziger Zweck es war, den Bootloader nach seiner Ausführung zu überschreiben und dann den Computer zurückzusetzen, damit der neue Bootloader ausgeführt wird, wodurch der Upload-Server den sendet aktuelles Haupt-App-Image. Technisch gesehen war ein Stromausfall in den wenigen Millisekunden, die die spezielle App benötigte, um ein neues Image über den Bootloader zu kopieren, ein nicht behebbarer Fehler. In der Praxis ist das nie passiert. Wir waren mit der sehr unwahrscheinlichen Möglichkeit einverstanden, da es sich bei diesen Geräten um Teile großer Anlagen handelte, in denen bereits Personen für die Wartung des Systems zuständig waren, was gelegentlich bedeutete, die eingebetteten Geräte aus anderen Gründen zu ersetzen.
Hoffentlich können Sie sehen, dass es eine Reihe anderer Möglichkeiten gibt, von denen jede ihre eigenen Kompromisse in Bezug auf Risiko, Geschwindigkeit, Kosten, Benutzerfreundlichkeit, Ausfallzeiten usw. aufweist.