In diesem Artikel möchte ich das Thema Bootloader vorstellen. Während wir zunächst damit beginnen uns die Theorie anzueignen und verstehen möchten was überhaupt ein Bootloader ist, geht es im Zweiten Teil dieses Artikels dann auch schon ans Eingemachte: Wir werden einen Bootloader auf einen PIC-Mikrocontroller übertragen und diesen dann verwenden.
Was ist ein Bootloader?
Ein Bootloader beschreibt ein (in der Regel) kleines Programm, das neben der eigentlichen Benutzeranwendung, also dem Programm, das ihr ursprünglich für eure Mikrocontroller-Schaltung entwickelt habt, auf dem Controller vorhanden ist. Dieses kleine Programm was nun also neben dem Benutzerprogramm im Mikrocontroller vorhanden ist, kommt nur relativ selten zum Vorschein, im normalen Betrieb ist dieses Programm gewissermaßen “unsichtbar”. Es gibt eine Reihe von Mikrocontrollern die in der Lage sind in ihren eigenen Flash-Programmspeicher zu schreiben. Im Flash-Programmspeicher liegt das Programm, das der Controller abarbeiten soll. Diese Tatsache erlaubt es, dass sich der Controller selber flashen kann. Natürlich geht das nicht von Zauberhand, hier kommt der Bootloader zum Einsatz. Dieser empfängt auf eine gewisse Art und Weise Datensätze die zusammengesetzt das Benutzerprogramm ergeben und schreibt diese an die jeweils richtigen Adressen in sein eigenes Flash. Nachdem er alle Datensätze empfangen und ins Flash geschrieben hat, hat er sich selbst programmiert.
Der Vorteil daran ist, dass man nun ohne konventionelles Programmiergerät, wie etwa einem PICKit3, in der Lage ist eine neue Firmware/Programm auf den PIC zu übertragen. Jetzt kann man sich natürlich die Frage stellen wie denn dann der Bootloader auf den PIC kommt? Hierfür ist einmalig ein Programmiergerät notwendig, das initial den Bootloader auf dem PIC lädt. Wenn der Bootloader dann auf dem PIC vorhanden ist, ist das Programmiergerät nicht mehr notwendig. Denkbar wäre zum Beispiel die Auslieferung eines Produktes mit bereits geladenem Bootloader und ggf. einer ersten Version eines Benutzerprogramm auf dem PIC. Wenn es dann im Laufe der Zeit zu Firmware-Updates kommt, können die “Kunden” dieses ganz einfach vom PC aus auf den Controller übertragen ohne hierzu ein Programmiergerät besitzen zu müssen.
Wo befindet sich der Bootloader?
Der Bootloader oder das Bootloader-Programm muss also parallel zum eigentlichen Benutzerprogramm auf dem Flash-Speicher vorhanden sein. Gleichzeitig soll des das Benutzerprogramm nicht bei seiner Arbeit stören oder sonst irgendwelche Auswirkung während dessen Ausführung haben. Grundsätzlich werden zwei Ansätze verfolgt, die in der Lage sind dieses gewünschte Verhalten zu realisieren.
- Bootloader am Anfang des Flash-Speichers
- Bootloader am Ende des Flash-Speichers
Der Nachteil der ersten Variante ist gleichzeitig der Grund weshalb ich die zweite Methode präferiere: Wenn man den Bootloader an den Start des Flash-Speichers platziert, dann muss dies im Benutzerprogramm berücksichtigt werden, denn normalerweise würde dort das Benutzerprogramm beginnen. Dieses muss nun jedoch auf den Bereich des Flash-Speichers hinter den Bootloader verlagert werden. Auch liegen die Adressen der Interrupts in diesem Bereich. Auch diese müssen dann logischerweise verzweigt werden. Das führt wiederum dazu, dass sich die Länge der Ausführung eines Interrupts um zwei Befehlszyklen verlängert.
Legt man den Bootloader stattdessen an das Ende des Flash-Speichers, so sind keine Änderungen am Benutzerprogramm notwendig. Die Adresse des Reset-Vektors wird lediglich auf den Start des Bootloaders “verbogen” und leitet somit den Start dessen beim Reset ein. Dies wird mit einem einfachen GOTO an Adresse 0x0000 erledigt. Der GOTO Befehl muss nicht selber programmiert werden! Das PC-Tool des Bootloaders macht dies automatisch. Wenn der Bootloader nichts zu tun hat oder fertig ist, springt der Controller einfach zum Start des Flash-Speichers wo sich das Benutzerprogramm befindet und startet dieses. Die Interrupt-Vektoren bleiben wo sie sind und benötigen keine Verzweigung (keine Laufzeitverlängerung).
Bootloader für PIC16 und PIC18
Nun möchte ich damit beginnen einen Bootloader für PIC16 und PIC18 Mikrocontroller vorzustellen. Ich habe den Bootloader nicht selber entwickelt, sondern es handelt sich um einen von Microchip selbst entwickelten Bootloader samt Anwendungssoftware für den PC. Es gibt im Internet Unmengen an verfügbaren Bootloadern, die sich in der Regel in zwei wesentlichen Aspekten unterscheiden:
- Speicherbedarf des Bootloaders selber
- Kompatibilität für jeweilige PIC-Typen
Es gibt bereits Bootloader die mit erstaunlich wenig Speicher auskommen. Mir geht es jedoch mehr um die einfache Anwendung und eine möglichst lange Liste an kompatiblen PIC-Typen. Ich werde in den Weblinks zu diesem Artikel einige weitere Bootloader verlinken, die ich im Laufe meiner Recherche im Internet gefunden habe.
Der Bootloader um den es in diesem Artikel geht wird unter anderem in der Application Note AN1310 beschrieben (EN). Damit das Einarbeiten etwas einfacher fällt, beschreibe ich die wesentlichen Schritte in diesem Artikel noch einmal ergänzend in deutsch. Der PC-Programm wird zum letztendlichen Übertragen der Firmware zum Bootloader/auf den PIC verwendet. Ich biete die beiden Downloads hier lokal von meinem Server aus an, da bei Microchip auch schon mal in die Jahre gekommene Projekte ausgegliedert werden und dann unter Umständen nicht mehr verfügbar sind. Die Gefahr besteht bei diesem Bootloader wohl vorerst nicht aber man weiß ja nie.
Der Bootloader von Microchip hat folgende Eigenschaften, wer sich noch detailierter in die Eigenschaften einlesen möchte, kann das gerne mit Hilfe der oben verlinkten Application Note tun.
- Speicherbedarf von weniger als 450 Befehlen
- automatische Baudraten-Synchronisierung (bis zu 3 Mbps)
- CRC Prüfung mit 16 Bit
- automatische BL-Einleitung durch MCLR-Kontrolle
- fertige PC-Anwendung
- …
Download
- Application Note AN1330
- ZIP-Archiv (Bootloader, PC-Software) (~4 MB)
- MPLAB-Projekt (PIC18, für Config-Bits im Code vorbereitet*)
* Ich habe festgestellt, dass man Probleme beim Importieren des alten MPLAB-Projektes in die neue MPLABX IDE bekommt. Und zwar kann man zwar problemlos das Projekt importieren und auch im Anschluss kompilieren, doch die Konfiguration, die man in den Code einpflegt (MPLABX unterstützt nur noch das Setzen des Konfigurationswortes direkt im Code) sind nicht wirksam. Das äußert sich dadurch, dass Ihr zwar problemlos eine Verbindung zum Bootloader bekommt, dieser das gewünschte HEX-File auch ohne weiteres in den Controller lädt, das Programm auf dem PIC dann aber nicht ordnungsgemäß bzw. gar nicht funktioniert! Das scheint daran zu liegen, dass in dem originalen MPLAB (8) Projekt des PIC-Bootloaders das Konfigurationswort direkt durch die IDE eingestellt wird. Ich habe daher einmal das MPLAB 8 Projekt geöffnet und die Einstellung entfernt, so dass das Konfig.-Wort wieder über den Code eingestellt werden kann. Ich empfehle Euch daher dringend dieses Projekt zu verwenden, wenn Ihr mit MPLABX arbeitet und das Projekt für euren jeweiligen Controller importiert. Bei Fragen könnt Ihr euch jederzeit im Forum melden.
Hardware
Dann schauen wir uns doch als nächstes einmal an, wie die Hardware beschaffen sein muss, damit der Bootloader zum Einsatz kommen kann. Da die beliebte RS232-Schnittstelle in der ursprünglichen Form an modernen Rechnern nicht mehr anzutreffen ist muss man eine Alternative suchen. Die aktuelle und zukünftige Schnittstelle ist natürlich USB. Somit ist klar, dass auch wir über USB unsere Schaltungen mit neuer Firmware versorgen möchten. Da die USB-Spezifikation jedoch ein ganz schön dicker Brocken ist, möchten wir einen eleganten Umweg gehen. Die Firma FTDI hat diesen Umstand auch erkannt und hat entspreche Chips entwickelt, die aus einem gewöhnlichen USB-Port eine serielle Schnittstelle zaubern. Der PC sieht USB, die Controller die serielle Schnittstelle. Damit wir auch im PC die serielle Schnittstelle “sehen”, wird mit den Treibern, die zum FTDI-Chip (dem FT232RL) gehören, eine virtuelle serielle Schnittstelle emuliert. Also nochmal kurz zusammen gefasst:
PC COM FTDI-Treiber USB FT232RL RX/TX MCU
Wir haben ja bereits gelernt, dass der Bootloader immer zum Reset des PIC aktiv ist und auf eine eventuell neue Firmware wartet, die er über die RX/TX-Leitungen des FT232RL-Chips bekommen würde. Wenn jedoch keine Aktivität zu erkennen ist, sprich keine neue Firmware aufgespielt werden soll, wird das Benutzerprogramm gestartet. Es gibt auch Ansätze, die das Setzen eines Jumpers oder Drücken eines Tasters zum Reset erfordern, damit der Bootloader gestartet wird. In meinen Augen ist das jedoch eher umständlich. Wenn man sich vorstellt, dass man eventuell an die Hardware gar nicht mehr dran kommt, dann sind diese Methoden sogar gänzlich ungeeignet.
Wir halten also fest, dass automatisierte Starten des Bootloaders in Kombination auf das Warten auf Aktivität auf der Schnittstelle ist bereits eine elegante Variante. Jetzt stellt sich natürlich die Frage, wie man vom PC aus einen Reset am Controller auslöst, damit man eine neue Firmware übertragen kann. Hierzu kann man einen kleinen Trick anwenden. Die serielle Schnittstelle verfügt über ein sogenanntes Hardware-Handshake. Dies wurde in früheren Zeiten verwendet um die Kommunikation zu steuern und eventuelle Überläufe zu verhindern. Heutzutage kommt dieses Verfahren jedoch kaum noch zum Einsatz. Das schöne daran ist jedoch, dass wir uns diese Ressource zu Nutze machen können um beim Controller einen Reset auszulösen.
Die RTS Leitung (request to send) wird zu Beginn einer Übertragung (PC MCU) von Low auf High gezogen. Damit fragt der PC bei der MCU nach ob diese bereit zum Empfangen von Daten ist. Die MCU würde dies mit einem Wechsel des Pegels von Low auf High des CTS-Signals (clear to send) quittieren. Diese Signale sind auch (negiert) beim FT232RL vorhanden. Wir können also RTS mit MCLR des PIC verbinden um einen Reset auszulösen und den Bootloader zu starten. Dann starten wir mit der Übertragung der neuen Firmware, die dann entsprechend vom Bootloader entgegen genommen wird.
Der gezeigte Schaltplan (Ausschnitt) zeigt die notwendige Verschaltung von RX, TX und dem RTS-Signal, das zum Auslösen des Resets am Mikrocontroller benötigt wird. Die Widerstände R1, R2 und R4 dienen lediglich zum Schutz der Ausgangstreiber im Fehlerfall und könnten rein theoretisch auch weg gelassen werden. Wichtig: Wenn euer PIC mit 3,3V betrieben wird, dann müsst ihr den FT232RL so beschalten, dass dieser auch nur 3V3-Pegel an seinen Ausgängen führt, siehe hierzu das Datenblatt des Chips oder meinen separaten Artikel zu diesem Chip.
Außerdem sollte beachtet werden, dass Ihr evtl. einen Jumper einbaut, der den FT232RL vom MCLR des PIC trennen kann. Das kann hilfreich sein, wenn man den PIC auf dem konventionellen Weg mit PICKit3 oder ähnlichem programmieren möchte. Die hohe Programmiers-Spannung könnte andernfalls einen negativen Einfluss auf den FT232RL haben.
Software (PIC)
Ich habe es bereits erwähnt: Damit der Bootloader seine Arbeit verrichten kann, muss er natürlich erstmal in den PIC geladen werden und dazu benötigt man einmalig ein Programmiergerät (zum Beispiel der Hersteller eines jeweiligen Boards). Wenn ihr das Archiv (Download-Link oben) heruntergeladen und die Installation ausgeführt habt, dann wurde das Bootloader-Programm in das folgende Verzeichnis geladen:
C:\Microchip Solutions\Serial Bootloader AN1310 v1.05\PIC18 Bootloader
Das Programm muss nun entsprechend für euren PIC kompiliert und geflasht werden. Hierzu müsst ihr mit MPLABX ein neues Projekt erstellen und im Project Wizzard das Konvertieren eines alten MPLAB 8 Projektes auswählen, da der Bootloader noch mit MPLAB 8 programmiert wurde. Da es sich um ein Assembler-Projekt handelt wird dieser entsprechend zum Kompilieren ausgewählt. Im nächsten Schritt muss das Konfigurationswort eingestellt werden. Die nachfolgende Liste hilft bei den Einstellungen:
- Watchdog-Timer: Disabled*
- Extended-Instruction-Set: Disabled
- Oscillator-Setting: Entsprechend der Hardware wählen
- Fail-Safe-Clock-Monitor: Enabled (wenn vorhanden)
- Low-Voltage-Programming: Disabled
- Table-Read-Protect: Disable (wenn vorhanden)
* Kann bei den meisten PIC-Typen später im Code wieder aktiviert werden.
Bei mir am PIC18F45K22 sehen die eingepflegten Zeilen für das Konfigurationswort wie folgt aus (eingefügt im oberen Bereich der PIC18 Bootlader.asm Datei).
CONFIG FOSC = INTIO67 ; Internal oscillator block CONFIG PLLCFG = OFF ; Oscillator used directly CONFIG WDTEN = OFF ; Watch dog timer off CONFIG XINST = OFF ; Extended Instruction Set off CONFIG FCMEN = ON ; Fail-Safe Clock Monitor on CONFIG LVP = OFF ; Single-Supply ICSP disabled CONFIG EBTR0 = OFF ; Table Read Protection off CONFIG EBTR1 = OFF ; ... CONFIG EBTR2 = OFF ; ... CONFIG EBTR3 = OFF ; ...
Wenn das Konfigurationswort richtig eingefplegt wurde, kann im Anschluss der Bootloader kompiliert und mit einem geeigneten Programmiergerät (PICKit3 oder ähnlich) in den Mikrocontroller übertragen werden.
Programm (PC)
Das Anwendungsprogramm für den PC ist relativ einfach gehalten und somit sehr übersichtlich. Der nachfolgende Screenshot zeigt das Tool, wie es beim Öffnen der EXE-Datei aussieht.
Wenn das Programm das erste mal gestartet wurde, müssen noch ein paar Einstellungen bezüglich der seriellen Schnittstelle getroffen werden. Hierzu navigiert ihr einfach in folgendes Menü: Program Settings … und stellt hier entsprechend eurem Aufbau die Schnittstelle ein. Auf dem Screenshot des Menüs (siehe unten) ist kein COM Port ausgewählt, da zum Zeitpunkt als ich diese Anleitung geschrieben habe, kein entsprechender PIC mit FT232-Chip am PC angeschlossen war.
Wenn ihr euren PIC mit der besprochenen Hardware an den PC anschließt, sollte ein entsprechender COM-Port in der Drop-Down-Liste zur Auswahl stehen. Eine nicht all zu hohe Baudrate hilft initial eine stabile Verbindung herzustellen. Ein Wert von 19,2kbps (siehe Screenshot) ist zu Beginn eine gute Wahl. Um nun das Benutzerprogramm (also das Programm was eigentlich in den PIC geladen werden soll), müsst ihr dieses zunächst öffnen (die Hex-Datei des Projektes). Im Anschluss wird die Hex-Datei im Anzeigefenster des Programms angezeigt. Jetzt muss der Bootloader im PIC aktiviert werden (Restart auslösen). Hierzu wird der rote Stopp-Button (Bootloader-Mode) gedrückt. Wenn das funktioniert hat, erscheint die Bootloader-Version und die PIC-Typen-Information in der Statusleiste. Jetzt kann der PIC ausgelesen, gelöscht, verifiziert oder beschrieben werden. Hierzu dienen die zusätzlichen vier Buttons in der Werkzeugleiste (siehe rechts neben dem Bootloader-Mode-Button).
Bei den Write Options sollte man besonders vorsichtig sein was die Einstellung der Config Bits betrifft. Bereits beim Übertragen des Bootloaders sollten durch das entsprechende Programmiergerät die Konfigurationsbits eingestellt werden, wie man es voraussichtlich für die jeweilige Anwendung benötigt. Man kan natürlich weiterhin in dem eigentlichen Benutzerprogramm die Konfigurationsbits mit den entsprechenden #pragma Anweisungen festlegen, doch sie werden keine Auswirkung haben, da der Bootloader die Bits nicht mehr ändert. Wenn man jedoch einen Haken in den Write Options unter Config Bits setzt, dann werden die Konfigurationen sehr wohl eine Auswirkung auf die Konfiguration des PIC haben. Diese Tatsache ist einerseits sehr nützlich, kann jedoch auch dazu führen, dass man sich aus dem System aussperrt, wenn man die Konfiguration so verändert, dass der Bootloader nicht mehr arbeiten kann. Generell gilt also den Haken bei Config Bits immer weglassen, es sei denn ihr wisst genau was ihr da tut 🙂
Übrigens: Wenn Ihr in MPLABX an eurem Projekt arbeitet und dieses neu compiliert wird das von dem PC-Tool des Bootloaders registriert, so dass dieser automatisch den Controller in den Bootloader-Modus versetzt und die neue Firmware auf den PIC aufspielt. Im Anschluss wird dann der PIC wieder in den Modus “Run” versetzt. Auf diese Weise merkt Ihr quasi keinen Unterschied mehr zwischen einem echten Programmiergerät und dem Bootloader für PIC16 und PIC18 Damit dieses automatische Flashen der neuen Hex-Datei funktioniert muss diese nur einmalig mit dem Bootloader-Tool geöffnet werden.
Neue PIC-Typen
Wenn es einmal vorkommen sollte, dass euer PIC-Typ nicht vom Bootloader unterstützt wird, so gibt es die Möglichkeit die vorhandene Datenbank des Bootloaders um einen Eintrag für diesen PIC zu erweitern. Nach der Installation des Bootloader-Paketes wurde zusätzlich die kleine Anwendung “Device Database” installiert. Diese kann zum Laden einer fertigen XML-Datei verwendet werden, die die entsprechenden Parameter für euren PIC enthält. Diese können dann in die SQL-Datenbank des Bootloaders geladen werden. Zusätzlich muss die DEVICES.inc Datei des Bootloaders (später befindlich im PIC selber) entsprechend erweitert werden. Eine vollständige Liste mit den (sofort) unterstützten PIC-Typen findet Ihr in der Devices.inc Datei.
Die einfachste Methode einen neuen PIC-Typen für den Bootloader kompatibel zu machen ist es, dessen *.PIC Datei mit der Anwendung Device Database zu öffnen (sie unten Download aller *.PIC Dateien als Zip-Archiv). Das Tool extrahiert die notwendigen Informationen und bereitet sie entsprechend für ein direktes Drag & Drop in die Datenbank vor. Wenn ihr die *.PIC Datei eures PIC-Typen mit dem Tool geöffnet habt, dann sieht das Fenster wie folgt aus:
Den gesamten Code aus dem Reiter devices.sql müsst ihr nun kopieren und entsprechend in die Datei devices.sql hineinkopieren. Der alte Inhalt in dieser Datei wird zuvor gelöscht, so dass nur noch der kopierte Inhalt in der Datei steht. Speichern, schließen. Die Datenbank-Datei devices.sql findet ihr unter folgendem Pfad:
C:\Microchip Solutions\Serial Bootloader AN1310 v1.05\Device Database\devices.sql
Im Anschluss müsst Ihr die Datenbank neu erstellen. Dafür öffnet ihr die Eingabeaufforderung von Windows und navigiert in den Pfad in dem auch die devices.sql liegt. Ein kleiner Trick, der eim das ganze Navigieren durch die Ordnerstrukturen erspart: Geht einfach im Dateiexplorer wieder eine Ebene nach oben und führt einen Rechtsklick bei gedrückter Shift-Taste auf den Ordner aus, in dem ihr die Eingabeaufforderung öffnen möchtet.
Es öffnet sich ein Kontextmenü das euch unter anderem die Möglichkeit bietet die Eingabeaufforderung direkt im angewählten Verzeichnis zu öffnen 🙂 In die offene Eingabeaufforderung geht ihr nun folgenden Befehl ein um die Datenbank zu aktualisieren:
sqlite3.exe -init devices.sql -batch ..\devices.db .quit
Wenn alles geklappt hat, sollte eure Eingabeaufforderung nun so aussehen wie bei mir (siehe Screenshot) nun wurde die Datenbank des PC-Programms neu erzeugt und beinhaltet nun den neu von euch angelegten PIC-Typen.
Als letzten Schritt müssen wir nun noch die DEVICES.inc Datei des Bootloaders selber erweitern. Hierzu öffnet ihr die Datei innerhalb MPLAB Umgebung. Falls ihr es noch nicht getan habt, solltet ihr ein neues MPLAB X Projekt erzeugen und das Konvertieren eines alten MPLAB IDE 8 Projektes auswählen, da der Bootloader mit dem C18-Compiler unter MPLAB IDE 8 erzeugt wurde (siehe auch Kapitel Software (PIC) ). Das Projekt, dass ihr nun konvertieren sollt findet ihr in folgendem Verzeichnis:
C:\Microchip Solutions\Serial Bootloader AN1310 v1.05\PIC18 Bootloader
Wenn ihr den Project Wizzard abgeschlossen habt, seht ihr links im Reiter Projects den Ordner Header-Files. In diesem Ordner ist die DEVICES.inc Datei enthalten, die ihr nun öffnet. Ganz zu Beginn haben wir damit angefangen die *.PIC Datei mit dem Programm Device Database zu öffnen. Das Programm hat uns darauf hin einen gewissen “Code” ausgegeben. Nun brauchen wir den Inhalt des Reiters devices.inc, den wir nun in die Datei, die wir in MPLAB geöffnet haben, hinein kopieren. Hierbei solltet ihr auch nochmal darauf achten, dass die DEVICEID mit der ID übereinstimmt, die wir zu Beginn in die devices.sql Datei kopiert haben 😉 Wenn auch dieser Schritt erledigt ist, kann das MPLAB X Projekt (der Bootlader) kompiliert werden.
Download der *.PIC Dateien
Normalerweise sind die *.PIC Dateien bei der Installation von MPLAB IDE bereits enthalten, jedoch konnte ich die Dateien im Installationsordner von MPLABX nicht finden. Für alle, die also nur noch mit MPLAB X arbeiten und somit nicht an die entsprechenden *.PIC Dateien heran kommen, stehen diese hier als Archiv für jeweils PIC16 und PIC18 zum Download bereit.
- PIC16-Zip-Archiv (~2,5 MB)
- PIC18-Zip-Archiv (~5 MB)
Siehe auch
- FTDI FT232RL – USB zu Seriell-Wandler
- RxTx – Virtuelle COM-Schnittstelle für Java