
In diesem Teil des Tutorials fügen wir Unterstützung für das Timing von Aufgaben und die Planung von Aufgaben hinzu, die in der Zukunft ausgeführt werden sollen. Den fertigen Code dieses Blog-Beitrags kannst du bei Ruuvi GitHub herunterladen.
Bitte folge Teil 1 der Serie für Details dazu, wie du das Repository klonst und den Code kompilierst, wobei du das Repository als https://github.com/ruuvi/ruuvi.nrf5_sdk15_bootloader.c.git anpasst. Die finale Hex-Datei dieses Tutorials kann von der Releases-Seite im GitHub-Repository heruntergeladen werden.
Bootloader
Bisher haben wir die Tags mit dem Ruuvi DevKit programmiert, was völlig in Ordnung ist, solange man tatsächlich ein DevKit hat. Die überwiegende Mehrheit der Nutzer hat jedoch keines, würde aber dennoch gerne ihre Tags aktualisieren können.
Es liegt nahe, die Bluetooth-Verbindung zu nutzen, um neue Firmware auf die Tags zu übertragen, da jeder, der den Bluetooth-Sensor-Beacon nutzt, ein Bluetooth-fähiges Gerät besitzt. Es gibt jedoch ein großes Problem: Was passiert, wenn die neue Anwendung beschädigt ist, der Strom ausfällt oder während des Updates ein anderes Problem auftritt?
Der Bootloader ist die Antwort auf diese Probleme. Wenn das Gerät eingeschaltet wird, ist der Bootloader das erste Programm, das auf dem RuuviTag ausgeführt wird. Der Bootloader prüft die Integrität unserer Anwendung, und wenn die Anwendung korrekt installiert ist, lässt der Bootloader die Anwendung laufen. Wenn die Anwendung nicht ordnungsgemäß installiert ist oder der Nutzer signalisiert hat, dass er die Anwendung aktualisieren möchte, lässt der Bootloader die Anwendung nicht laufen, sondern bietet dem Nutzer eine Methode zur Aktualisierung der Anwendung an.
Einen ordentlichen Bootloader zu schreiben, ist eine Aufgabe, die eine eigene Blog-Serie verdient hätte. Daher nehmen wir hier eine Abkürzung und verwenden den Bootloader von Nordic Semiconductor. Nordic hat seine Software Development Kit (SDK) Version auf 15.2 aktualisiert, also aktualisieren wir bei dieser Gelegenheit auch gleich das SDK 15.0, das wir bisher verwendet haben.
Einrichten des Nordic Bootloader-Projekts
Als Erstes benötigen wir die Micro elliptic curve cryptography library, die nicht als vorkompilierte Binärdatei im Nordic SDK enthalten ist. Gehe in das SDK-Verzeichnis external/micro-ecc und führe den Befehl aus:
git clone https://github.com/kmackay/micro-ecc.git
cd nrf52hf_armgcc/armgcc
makeAls Nächstes kopieren wir das debug-bootloader-Beispiel unter SDK/examples/dfu/secure_bootloader/pca10040_ble_debug in unser Projekt, entfernen alle außer den Segger Embedded Studio (SES) Kompilierungsumgebungen und passen die Dateipfade in der emProject-Datei so an, dass sie auf das SDK-Root und das Projekt-Root zeigen, wo dies erforderlich ist.
Lass uns ein paar Konfigurationsparameter in sdk_config.h ändern. Das Booten ist ein seltenes Ereignis, daher können wir die CRC nach dem System-Off prüfen. Wir wollen später buttonless DFU unterstützen. Nennen wir den DFU-Dienst „RuuviBoot“, um den aktuellen Namen des Bootloaders beizubehalten. Wir wollen Downgrades auf frühere Versionen zulassen. Und schließlich wählen wir als HW-Version 0x0b, wie in „RuuviTag B“.
#define NRF_BL_APP_CRC_CHECK_SKIPPED_ON_SYSTEMOFF_RESET 0
#define NRF_BL_DFU_ENTER_METHOD_BUTTONLESS 1
#define NRF_DFU_BLE_ADV_NAME "RuuviBoot"
#define NRF_DFU_APP_DOWNGRADE_PREVENTION 0
#define NRF_DFU_HW_VERSION 0x0bDer SDK12 Ruuvi-Bootloader ist eine Debug-Variante und hat seine Flash-Startadresse bei 0x75000. Unser Bootloader wird dieselbe Startadresse haben, da eine Änderung der Bootloader-Startadresse im Allgemeinen zu Problemen führt, wenn man Softdevice + Bootloader von SDK12 auf SDK15 über BLE aktualisiert. Der Debug-Bootloader passt jedoch standardmäßig nicht in den vorgegebenen Platz; wir müssen einiges an Logging deaktivieren, um in den verfügbaren Platz zu passen. Am einfachsten lässt sich Platz sparen, indem man das Standard-Log-Level von „Debug“ auf „Info“ erhöht. Die nächsten paar Bytes werden gespart, indem der Error-Code-to-String-Konverter und NRF_SDH_BLE_LOG, der die Konvertierungsfunktion nutzt, deaktiviert werden. Schließlich deaktivieren wir die Float-Formatierung in printf.
#define NRF_LOG_DEFAULT_LEVEL 3
#define NRF_STRERROR_ENABLED 0
#define NRF_SDH_BLE_LOG_ENABLED 0
Wir wollen auch das ruuvi.boards.c-Repository verwenden, das wir haben, um die Pflege von zwei Board-Konfigurations-Repositories zu vermeiden. Lass uns ruuvi.boards.c als Submodul hinzufügen.
Nachdem wir etwas Glue-Logik in custom_board.h hinzugefügt und Board-Definitionen zu den SES-Präprozessor-Direktiven hinzugefügt haben, können wir den Pin zum Aufrufen des Bootloaders als RUUVI_BOARD_BUTTON_1 definieren.

#include "ruuvi_boards.h"
#define NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN RUUVI_BOARD_BUTTON_1Als letzten Schliff benennen wir die Projektdateien von pca10040 in ruuvitag_b um. Unser Entwicklungsverzeichnis sieht nun so aus:

Verwendung des Bootloaders
Wir können den Bootloader innerhalb von SES wie gewohnt auf unseren RuuviTag flashen. Wie man sich denken kann, bricht der Code beim ersten Durchlauf sofort mit einem Assert ab. Das liegt daran, dass der Beispielcode versucht, eine dritte LED zu verwenden, die wir am RuuviTag nicht haben. Ein schneller Fix in main.c – das Entfernen aller Aktionen mit BSP_BOARD_LED_2 – und schon kann es losgehen.

Erstellen eines Device Firmware Update-Pakets
Das Erstellen eines DFU-Pakets für unseren Bootloader ist ein Kinderspiel: Wir laden die finale Hex-Datei aus unserem vorherigen Tutorial herunter:
wget http://jenkins.ruuvi.com/job/ruuvi.firmware.c/lastSuccessfulBuild/artifact/targets/ruuvitag_b/armgcc/_build/nrf52832_xxaa.hexund führen den nrfutil-Befehl zur Paketerstellung darauf aus:
nrfutil pkg generate --application nrf52832_xxaa.hex --application-version 1 --application-version-string "3.11.0" --hw-version 0x0b --sd-req 0xAF --key-file ~/git/ruuvi.nrf5_sdk15_bootloader.c/ruuvi_open_private.pem RuuviTagB_RuuviFW_3.12.0_dfu.zipWenn du ein anderes Softdevice anstrebst, kannst du die sd-req-Codes im nrfutil-Repository nachschlagen.
Hochladen des Pakets
Das Hochladen eines DFU-Pakets mit nRF Connect ist ein vertrauter Prozess, der bei RuuviLab gut beschrieben ist. Wir können die Info-Logs von unserem Tag während des Paket-Uploads überprüfen.

Die rote LED am Tag blinkt mit 1 Hz, und ein kurzer Blick in die Ruuvi Station App zeigt, dass die Daten vom Tag ankommen. Wir haben unsere Firmware erfolgreich über Bluetooth aktualisiert.
Fazit
Dieser Beitrag war ein kleiner Exkurs von der eigentlichen Anwendung, aber ich denke, er ist als Teil des gesamten Stacks, den wir aufbauen, gerechtfertigt. Wir können die Anwendung nun über Bluetooth hochladen und könnten bei Bedarf auch ein neues Softdevice und einen neuen Bootloader hochladen, um den gesamten Stack zu aktualisieren.
Bleib dran und folge @ojousima und @ruuvicom auf Twitter für #FirmwareFriday-Beiträge!