
Einführung
Derzeit bietet der Markt eine breite Palette von Einzelzahlern für jeden Geschmack zu einem erschwinglichen Preis.
In der Regel dienen verschiedene Baugruppen von Herstellern zur Bewertung der Plattform und sind Ausgangspunkt eines neuen Projekts, daher sind sie nicht immer für bestimmte Aufgaben geeignet. Bei Aufgaben, bei denen eine hohe Zuverlässigkeit erforderlich ist, steht der Entwickler vor der Frage, wie das Distributionskit fertiggestellt und dann nicht mit einer vollständigen Überarbeitung des Images und des Aktualisierungssystems bezahlt werden kann.
Im Internet gibt es fast keine Informationen darüber, wie der Release-Build aussehen sollte und wie das Update implementiert werden soll. Daher muss der Entwickler ein „Fahrrad“ entwickeln oder seine eigenen Entwicklungen verwenden, die nicht immer zu 100% getestet werden.
Da ich an der Entwicklung von Software für verschiedene Linux-Geräte beteiligt bin (mein Portfolio kann unter dem Wort develinux google sein) und auch Autor des 11-teiligen Projekts bin, muss ich mich regelmäßig nicht nur mit Baugruppen befassen, sondern auch mit der Entwicklung von Aktualisierungsmechanismen über WEB oder USB-Flash.
In diesem Artikel möchte ich meine Erfahrungen und Kenntnisse in relevanten Bereichen teilen.
Montageanforderungen
Bei der Entwicklung von Baugruppen und Updates für verschiedene Geräte habe ich verschiedene Anforderungen an mich selbst ermittelt:
- Die Baugruppe darf nicht beschädigt werden, wenn die Stromversorgung plötzlich ausgeschaltet wird.
- Montage sollte schnell geladen werden;
- Der Bootloader sollte einwandfrei funktionieren.
- Die Assembly muss das Update unterstützen.
Ich werde versuchen, diese Anforderungen im Folgenden näher zu erläutern, und anschließend drei Ansätze für die Unterteilung von Bildern in Abschnitte und deren Aktualisierungen beschreiben.
Die Baugruppe darf nicht beschädigt werden, wenn die Stromversorgung plötzlich ausgeschaltet wird.
Wer braucht ein Gerät, das nach einem zehnten Neustart nicht mehr funktioniert? Für niemanden! Wenn Sie vorgefertigte Distributionen verwenden (und es gibt nur sehr wenige davon für Embedded), sind sie ohne eine Datei aus der Box in dieser Hinsicht alle sehr unzuverlässig. Ich erinnerte mich sehr gut an das Projekt, bei dem ich Ubuntu unter imx6 verwendete. Die Dateisysteme auf der Karte waren beschädigt, manchmal ab dem zehnten Neustart, manchmal ab dem vierzigsten, es hing von den Sternen am Himmel ab. Das Projekt rettete FS aufs. Tatsache ist, dass Ubuntu nicht schreibgeschützt ist und immer etwas schreiben sollte. Ich erinnere mich an eine ähnliche Situation in einem anderen Projekt, in dem yocto auf einer SD-Karte verwendet wurde. Beachten Sie also, dass SD-Karten im Allgemeinen die hässlichste Art von Laufwerk sind, die am schnellsten abstürzt, viel zuverlässiger als emmc und nand. Wenn Sie eine SD-Karte verwenden, ist es ratsam, während des Betriebs so wenig wie möglich darauf zu schreiben. Die Hintergrundübertragungsalgorithmen für Sektoren sind sehr unvorhersehbar. Ich habe mit Dutzenden verschiedener SD-Karten von Weltmarken gearbeitet und keine einzige Karte gefunden, die ich empfehlen könnte.
SD-Karten bieten jedoch mehrere Vorteile: Sie sind erschwinglich, kostengünstig und praktisch beim Debuggen von Software.
Warum bin ich ... Und hier ist die Sache - der Root-FS sollte schreibgeschützt sein, es sollten während des Betriebs keine Einträge darin sein. Sie werden wahrscheinlich denken: wie so? Millionen von Android-Geräten schreiben immer etwas und scheitern nicht. Das stimmt, aber das liegt daran, dass die meisten Android-Geräte zum einen über einen Akku verfügen und zum anderen der Root-FS als Ramdisk gerahmt ist und die Systempartition schreibgeschützt ist.
Wenn das System zuverlässig sein sollte, können alle möglichen Dinge beim Installieren von Paketen im Root-FS viel verderben. Ich empfehle squashfs als Dateisystem. Es funktioniert schnell, kann nichts schreiben, spart Platz durch Komprimierung ...
Aber was ist mit dem Speichern von Konfigurationen, dem Herunterladen von Dateien usw. fragst du
Dazu müssen Sie jedoch separate RW-Partitionen erstellen. Wenn Sie in NAND schreiben möchten, empfehle ich eine bewährte Option - UBIFS. Wenn in NOR, dann jffs2. Wenn ich auf ein anderes Laufwerk schreibe, empfehle ich ext4, btrfs, ReiserFS. Ich kann nicht auf den besten FS unter ihnen hinweisen, da Es gab verschiedene Probleme mit allen.
Überprüfen Sie in diesem Fall immer vor dem Mounten von rw-Partitionen die Partitionen mit fsck-ähnlichen Dienstprogrammen auf Fehler.
Die Montage sollte schnell geladen werden
Die Download-Geschwindigkeit des Geräts wirkt sich auf die allgemeine Benutzerfreundlichkeit aus. Bei einigen Aufgaben beträgt die Ladezeit nicht mehr als 30 Sekunden, bei einigen sind 5 Minuten zulässig. Für mich selbst habe ich Zeit bis zu 1 Minute trainiert, je weniger desto besser. Warten Sie zu lange länger als eine Minute auf den Download. Möglicherweise scheint das Gerät hängen geblieben zu sein. Wenn Sie also die Zeit verkürzen können, ist es besser, es zu verwenden.
Der Bootloader sollte reibungslos funktionieren
Der Lader ist das, ohne das die Baugruppe nicht startet. In letzter Zeit beobachte ich oft, wie Single-Board-Hersteller die Entwicklung erleichtern, indem sie eine Demo für eine SD-Karte mit einer Beschreibung zum Registrieren eines Bootloaders oder eines fertigen Images bei einem Bootloader hochladen, die einfach mit dem Befehl dd ausgefüllt wird. Aber was ist, wenn die SD-Karte einfriert? Das gleiche ist nicht ungewöhnlich. Persönlich fielen in meiner Praxis die Karten oft ab. Auf diese Weise arbeiten Sie mehrere Stunden lang gegen eine Gebühr, schreiben Software, bam und das ist alles ... Fehler im Kernel fließen ein, die Karte fällt ab. Aber was ist, wenn dies ein Gerät ist, das in den Feldern ohne Neustart funktionieren sollte? Übrigens, ein Neustart einschließlich Watchdog belebt nicht immer eine blockierte Karte, die Karte hat kein Rücksetzsignal, dies ist kein emmc, natürlich ist dies eher eine Frage für die Schaltung der Karte, wenn die Karte die Leistung der Karte zurücksetzt, wird dies sparen, aber dies ist nicht überall. Bei einigen Boards hilft es nur, die Leistung oder Karte zu verzerren. Aufgrund meiner Erfahrung empfehle ich nicht, den Bootloader mit der Hauptbaugruppe auf dem Laufwerk zu speichern, wenn während des Betriebs eine Aufzeichnung auf dem Laufwerk durchgeführt wird. Wenn das System mit dem Bootloader nichts auf das Laufwerk schreibt und dies selten vorkommt, dann bitte. Nach meiner Erfahrung wurde das Dateisystem im schreibgeschützten Modus nur aufgrund von Hardwarefehlern deformiert, nicht jedoch aufgrund von Softwarefehlern.
Der Bootloader sollte an einem sicheren Ort, auf einem zuverlässigen Laufwerk, beispielsweise in einem separaten NOR- oder EEPROM-Chip, aufbewahrt werden. Unten sehen Sie ein Beispiel für ein Modul, das auf dem imx6ull-Chip basiert und SPI NOR zum Speichern des Bootloaders enthält.
Build muss ein Upgrade unterstützen
Nirgendwo ohne Update ... Ich habe an vielen Projekten teilgenommen und nie die perfekte Software für die Lieferung von Arbeiten bekommen. Ein Fehler wird immer erkannt oder eine Funktionsverbesserung ist erforderlich. Sie müssen verstehen, dass Menschen, die Software schreiben, Fehler machen, während sie das Gerät verwenden, etwas mehr wollen. In 90% der Fälle kann das Fehlen eines durchdachten Update-Systems sowohl zu Kopfschmerzen für den Hersteller als auch zum Zusammenbruch des gesamten Projekts führen. Zum Beispiel wurde ein Videoüberwachungssystem für den Transport entwickelt, das System wurde in ganz Russland installiert, und es stellte sich heraus, dass Vermarkter den Markt unterschätzten und kein Streaming vorsahen. Außerdem wurden mehrere Fehler in der Firmware gefunden, und der Verbraucher beginnt, in die Richtung der Wettbewerber zu blicken, weil sie dies getan haben Es gibt nur etwas, das nicht im gekauften Gerät enthalten ist ... Ja, ja, in einem seltsamen Garten sind Erdbeeren schmackhafter und das Wetter ist besser (Psychologie).
Was tun in einer solchen Situation? Wenn das Update unterstützt wird, gibt es viele Lösungen, Fehler können behoben, Stream-Broadcasting verbessert und die Funktionalität für den Verbraucher angepasst werden. Geben Sie der Verbraucher-Firmware Anweisungen und das ist alles. Wenn dies jedoch nicht unterstützt wird, wird der Hersteller große Abenteuer mit Geschäftsreisen von Servicetechnikern bis hin zum Austausch von Geräten erleben.
Das Update-System im Gerät sollte bis ins kleinste Detail durchdacht und zu 100% getestet werden. Ein Fehler in diesem Teil verwandelt das Eisen in Ziegel, daher sollte es keine Toleranzen und Ausnahmen geben.
Der Aktualisierungsvorgang muss gegen das Ausschalten des Geräts beständig sein und darf das Gerät unter keinen Umständen beschädigen.
Eine Übersicht über Partitionierungsansätze für zukünftige Updates
Von den vielen Ansätzen kann ich 3 Typen empfehlen, die ich persönlich implementiert habe. Dies sind nicht alle Ansätze, deren Umfang den Rahmen dieses Artikels sprengt. Alle drei Typen haben Mängel und sind alles andere als ideal, aber, wie es mir scheint, liegen sie nahe am goldenen Mittel des gesunden Menschenverstandes.
Ansatz Nr. 1
Der einfachste und kostengünstigste Weg:
Ein Image wird auf ein Laufwerk gelegt, z. B. eine SD-Karte, die vom U-Boot in das integrierte Laufwerk des Geräts geflasht wird, z. B. NAND-Flash.
In U-Boot müssen Sie dafür Skripte vorbereiten.
Von den Pluspunkten - dies ist die einfachste Art der Aktualisierung, deren Entwicklung maximal 1 Tag dauern wird.
Die Nachteile dieses Ansatzes sind das Fehlen einer Visualisierung des Prozesses und die sehr begrenzten Fähigkeiten des Bootloaders, d.h. Keine komplizierte Logik mit Standardtools, es sei denn, Sie haben natürlich einen eigenen U-Boot-Befehl (aber dies ist eine andere Art von Update, C ist eine große Kraft). Diese Methode ist nicht für Aktualisierungen über WEB vorgesehen. Es ist problematisch, die Integrität des Firmware-Images zu kontrollieren. In einigen Fällen sollte die Baugruppengröße die RAM-Größe nicht überschreiten.
Darüber hinaus ist es bei einigen Aufgaben erforderlich, die Einstellungen während des Upgrades zu speichern. Dies ist bei diesem Ansatz nicht einfach zu implementieren.
Ansatz Nr. 2
Die zuverlässigste und geschützteste Methode der betrachteten, aber die schwierigste. Ich empfehle diese Methode, um in besonders verantwortungsvollen Entwicklungen eingesetzt zu werden Es schützt sowohl vor fehlerhaften Bildern als auch vor physischen Schäden am Hauptlaufwerk, da die Schaltung ein zusätzliches verwendet.
Der Ansatz verwendet einen minimalen Build (Ramdisk-Größe von 8-16 MB) und den Haupt-Build. Ramdisk ist ein komprimiertes Archiv, sodass ein 16-MB-Build physisch um ein Vielfaches kleiner ist.
Das Ziel einer minimalen Baugruppe besteht darin, die Hauptbaugruppe zu bewerten und zu laden.
Ramdisk wird mit den Kernel- und U-Boot-Skripten in einem FIT-Image gehostet.
Warum FIT Image und was gibt es? Das FIT-Image ist ein Format, das von U-Boot unterstützt wird. Es stellt die Integrität aller Komponenten (Kernel, DTS, Ramdisk, Skripte) sicher. Das Entpacken des FIT-Images erfolgt im U-Boot. Wenn die Prüfsumme nicht konvergiert, lehnt U-Boot das Laden ab. Dies ist zweckmäßig, d.h. Sie müssen sich nicht selbst um die Integritätskontrolle kümmern, müssen nicht mehrere Dateien separat schreiben oder Ihre eigenen Bilder erfinden. Alles wird mit dem FIT-Bild erledigt. Normalerweise nimmt ein FIT-Image 7 bis 20 MB ein. Es sollte auf ein separates, hochzuverlässiges Laufwerk geschrieben werden, z. B. in qspi oder Flash. Die Hauptbaugruppe kann in einem billigeren und unzuverlässigen Speicher gespeichert werden, z. B. NAND-Flash. Da die Hauptarbeiten in der Hauptbaugruppe stattfinden, wird genau diese zuerst beschädigt. In diesem Fall wird ein separates Laufwerk mit minimalen Rootfs zur Rettung kommen.
Startvorgang.
u-boot lädt ein Skript herunter, das versucht, FIT-Updates (FIT2) und anschließend die FIT-Werksfirmware (FIT1) zu verwenden.
Wenn FIT2 nicht vorhanden ist oder seine Integrität verletzt wird, schlägt der Fit-Test fehl und U-Boot lädt die erste FIT (FIT1). Wenn es FIT-Updates gibt (FIT2) und es nicht kaputt ist, wird seine Ramdisk geladen, die die Rootfs-Updates (Rootfs2) überprüft.
Wenn Rootfs2 fehlerhaft ist, löschen die Skripte die FIT-Updates (FIT2). Nach dem Neustart wird das aus FIT (FIT1) und Rootfs1 bestehende Factory-Image heruntergeladen.
Aktualisierungsprozess.
Das Update-Image enthält FIT, Rootfs und verschiedene Assembly-Informationen, einschließlich Prüfsummen aller seiner Komponenten. Baugruppeninformationen werden während des Upgrades verwendet, um die Integrität und Kompatibilität zu überwachen.
Aktualisieren Sie den Fortschritt in Schritten:
- Überprüfen des Images auf Kompatibilität mit Hardware und Software,
- Überprüfen der Integrität des Abbilds in der Aktualisierungsdatei,
- Kopieren von Rootfs2 aus der Aktualisierungsdatei in einen zuvor vorbereiteten Abschnitt,
- Überprüfen der Integrität des kopierten Bildes im Abschnitt,
- Kopieren Sie FIT2 in den entsprechenden Abschnitt.
- Neustart.
Wenn der Prozess fehlschlägt, wird das Fehlen oder Beschädigen von FIT2 das System nicht ruinieren u-boot weigert sich einfach, es zu verwenden und lädt das Factory-Image. Daher wird während des Upgrades die Integrität von FIT2 nicht überprüft.
Nach dem Update wird die neue Assembly in Form von FIT2 und Rootfs2 auf dem Hauptlaufwerk platziert.
Diese Methode ist beständig gegen mechanische Beschädigungen des Antriebs und FS-Fehler.
Bei kritischen Fehlfunktionen wird das Factory-Image gestartet, in dem die Wiederherstellungssoftware funktioniert, mit der beispielsweise NAND überprüft, die Firmware mithilfe des SSH-Protokolls aus dem Netzwerk heruntergeladen und anschließend aufgezeichnet werden kann.
Ich habe nur ein Beispiel für die Wiederherstellung gegeben, es gibt viele Möglichkeiten. Bei diesem Ansatz wird der Wiederherstellungsprozess von vollwertigem Linux gesteuert, das alles kann ... und nicht vom Bootloader wie in der ersten Version.
Ansatz Nr. 3
Diese Art von Update wird in fast allen 11-teiligen Projekten verwendet, da es sehr gut funktioniert hat.
Das Update eignet sich für alle Baugruppengrößen und Laufwerkstypen. Im Gegensatz zum vorherigen Typ wird hier SPI NOR nur für U-Boot verwendet, daher hat es eine geringere Größe und geringere Kosten, 1 MB ist ausreichend.
Diese Art der Aktualisierung erfordert keine separate Erstellung von Ramdisk, was bedeutet, dass Programmierzeit für die zukünftige Entwicklung und Unterstützung gespart wird.
In diesem Beispiel wird ein SD-Kartenlaufwerk verwendet, es kann jedoch auch NAND mit UBIFS verwendet werden, kein Unterschied. Bei diesem Ansatz wird Rootfs RO vor dem Laden nicht überprüft. Wenn die Baugruppe beschädigt ist, weiß das System nicht, dass sie beschädigt wurde, und lädt sie in einem Kreis. Hierbei wird davon ausgegangen, dass die Daten im RO-Bereich in keiner Weise geändert werden können. Dieser Ansatz beseitigt die physische Fehlfunktion des Antriebs. Wenn das Laufwerk physisch nicht fehlerfrei ist, muss das Gerät zu einem Servicecenter gebracht werden. Es wird keine Selbstheilung bereitgestellt. Dies ist der Preis, den Sie zahlen müssen, um die Entwicklungsgeschwindigkeit, die billigere Unterstützung und die billigere Elementbasis zu erhöhen, aber dies ist gerechtfertigt. Warum gegen etwas versichern, das so gut wie nie passiert?
Die Logik zum Herunterladen und Aktualisieren ist dieselbe wie im vorherigen Ansatz.
Beim Laden lädt u-boot zuerst FIT-Updates (FIT2) herunter. Wenn diese nicht vorhanden sind oder die Integrität verletzt wird, lädt u-boot die erste FIT (FIT1), die werkseitig zusammengesetzte Baugruppe, und so weiter, bis das System aktualisiert wird. Wenn das System aktualisiert wird, werden FIT2 und Rootfs2 angezeigt. In diesem Fall wird beim Booten des Geräts zuerst das FIT-Update (FIT2) gestartet. In den U-Boot-Skripten, die in jeder FIT gespeichert sind, muss geschrieben werden, welche Rootfs gemountet werden sollen.
Gemeinsame Partition RW
In Diagrammen gibt es überall einen gemeinsam genutzten Partitionsblock. Dies ist eine Gruppe von Abschnitten zum Schreiben. Alle Einträge werden nur dort vorgenommen. Die freigegebene Partition wird aus Gründen der Übersichtlichkeit als eine Partition angezeigt. Tatsächlich gibt es drei davon: zwei kleine für Konfigurationen, die im Spiegel arbeiten, und eine große für alles andere. Außerdem empfehle ich, dass Sie beim Aktualisieren einige der Konfigurationen beibehalten. Dies ist praktisch, wenn Sie beispielsweise das Netzwerk konfigurieren und aktualisieren, müssen Sie die Netzwerkeinstellungen nicht neu konfigurieren.
Zusammenfassend
Der Artikel beschreibt drei Arten von Assemblys mit Unterstützung für Updates, die alle von mir persönlich überprüft wurden. Sie können sie sicher in Projekten verwenden.
Im Moment benutze ich nur die letzten beiden, da sie für die Anforderungen am besten geeignet sind. Der Übersichtlichkeit halber sehen Sie Beispiele für Geräte, auf denen diese Arten von Updates verwendet werden (Details im 11-Teile-Portfolio):
- RS485-Repeater über 4G / WiFi / LAN,
- 4K V-By-One-Steuerplatine für industrielle Anzeigesteuerung,
- integriertes Hangar-Klimatisierungssystem,
- 2DisplayPort-LVDS Industrieanzeige-Videocontroller,
- Leitungssteuerungssystem
- VPN-Gateway.
Wenn mein Artikel nützlich und interessant ist, bin ich bereit, meine Erfahrungen und bewährten technischen Lösungen im Bereich Embedded Linux auf dieser Website weiterzugeben.
Danke an alle.
Gorchakov Ilya
Telegramm:
develinux