Ich habe es kürzlich folgendermaßen gemacht: Das Programmupdate kommt
über irgendeine Schnittstelle (in meinem Fall UART) in den Controller.
Die goldene Version schreibt den Datenstrom ab eine bestimmte (freie)
Stelle ins Flash. Der Datenstrom (update Version) besteht aus dem
ausführbaren Code gefolgt (einfach hinten drangelinkt) von den neuen
Interruptvectoren und einer 16Bit CRC. Hat der Controller alles
geschrieben dann führt er einen Softwarereset aus. In der low-level-init
der goldenen Version wird nun geprüft, ob im besagten
Updatespeicherbereich ein gültiges Programm liegt (dazu die CRC). Wenn
die update Version als gültig erkannt wird, werden ebenfalls in der
low-level-init der goldenen Version die Interruptvectoren auf die update
Version umgebogen, anschließend kontrolliert und wieder ein
Softwarereset ausgeführt. Da die Reseteinspungadresse nun auf die update
Version zeigt läuft von nun an die update Version. In der low-level-init
der update Version werden nochmals Gültigkeit und Interruptvektoren
geprüft. Falls hier ein Fehler entdeckt wird, werden wieder die alten
Interruptvektoren der goldenen Version hergestellt (welche in einem
speziell geschützten Bereich des Flashs liegen).
Vorteile:
- Es wird immer eine lauffähige goldene Version vom Auslieferzeitpunkt
vorgehalten, was die Ausfallsicherheit massiv erhöht.
- Man bedient sich einfacher Schnittstellen (UART, SPI, ...).
- Während die Daten rübergeschaufelt werden läuft parallel das normale
Programm, also minimierte blackout-Zeit.
Nachteile:
- Doppelte Speicherbelegung, was bei heutigen Controllern verkraftbar
ist.
- Unterschiedliche Kompilate/Linkerscripte für goldene und update
Version.