
Over-the-Air-(OTA-)Firmware-Updates sind eine unverzichtbare Anforderung für im Feld eingesetzte Funkmodule in der Produktion. Ein schlecht konzipierter Update-Mechanismus kann Geräte unbrauchbar machen (brick), Anwendungsdaten beschädigen oder Sicherheitslücken ungepatcht lassen. Dieser Artikel behandelt die Auswahl des Transportprotokolls, das Dual-Bank-flash-Management und Rollback-Sicherheitsnetze mit Codebeispielen für die nRF52- und ESP32-Plattformen.
Vergleich der OTA-Transportprotokolle
| Protokoll | Durchsatz | Overhead | Reichweite | Geeignet für |
|---|---|---|---|---|
| BLE GATT (MBU/DFU) | ~1-5 KB/s | 4 Bytes (ATT-Header) | ~50 m | Feldgeräte mit niedrigem Stromverbrauch |
| BLE L2CAP | ~10-30 KB/s | 4-6 Bytes | ~50 m | Schnellere BLE-Updates |
| Wi-Fi HTTP | ~200-800 KB/s | TCP/IP-Stack | LAN/WAN | Modul mit Wi-Fi-Combo |
| UART kabelgebunden | ~115-921 KB/s | Keiner (seriell) | Nur direkt verbunden | Flashen in der Produktionslinie |
BLE GATT DFU bleibt der dominierende Transport für batteriebetriebene Module. Der DFU over BLE von Nordic verwendet eine Control-Point-Characteristic (UUID 8EC90001-F315-4F60-9FB8-838830DAEA50) und eine Data-Characteristic (8EC90002-F315-4F60-9FB8-838830DAEA50). Die Maximale-MTU-Aushandlung (typischerweise 247 Bytes) begrenzt den Durchsatz mit aktivierten Benachrichtigungen auf ~2.5 KB/s.
Dual-Bank-flash-Architektur
Der Dual-Bank-Ansatz speichert sowohl das aktive Firmware als auch das neue Firmware-Image gleichzeitig. Wenn das Update fehlschlägt oder das neue Image beschädigt ist, bootet das Gerät aus dem als fehlerfrei bekannten Bank. Speicherlayout auf nRF52840 (1 MB flash):
// nRF52840 dual-bank layout (SoftDevice S140)
// Bank 0 (active): 0x00026000 - 0x0005FFFF (214 KB app + 2 slots)
// Bank 1 (update): 0x00060000 - 0x0009FFFF (262 KB)
// SoftDevice: 0x00000000 - 0x00025FFF (152 KB)
// Bootloader: 0x000F8000 - 0x000FFFFF (32 KB)
// Minimum image size for dual-bank: (flash_total - SD - BL) / 2
// = (1048576 - 152000 - 32768) / 2 = 431904 bytes (~421 KB per bank)
// For typical BLE apps (~80-120 KB), dual-bank easily fits.
ESP32-OTA-Partitionstabelle:
# ESP32 partition table (single-bank OTA fallback)
# Name, Type, SubType, Offset, Size
nvs, data, nvs, 0x9000, 0x4000
otadata, data, ota, 0xd000, 0x2000
phy_init, data, phy, 0xf000, 0x1000
factory, app, factory, 0x10000, 1M
ota_0, app, ota_0, 0x110000, 1M
ota_1, app, ota_1, 0x210000, 1M
# otadata stores which partition (ota_0 or ota_1) is active
Firmware-Image-Signierung und -Verifizierung
Nicht signierte Firmware-Images lassen sich trivial manipulieren. Der DFU von Nordic erfordert ECDSA-P256-Signaturen für jedes Image. Der Bootloader verifiziert die Signatur, bevor das Update angewendet wird. Schlägt die Verifizierung fehl, führt das Gerät die vorhandene Firmware weiter aus.
| Sicherheitsmaßnahme | Implementierung | Overhead |
|---|---|---|
| Image-Signierung (ECDSA-P256) | Privater Schlüssel signiert .zip; Bootloader verifiziert öffentlichen Schlüssel | 64 Bytes Signatur + 64 Bytes öffentlicher Schlüssel im Init-Paket |
| SHA-256-Integrität | Hash des Firmware-Binärblocks im Init-Paket gespeichert | 32 Bytes |
| Anti-Rollback | Monotoner Versionszähler im flash; Bootloader lehnt Downgrade ab | 4 Bytes (Versionsfeld) |
| Fragment-CRC | CRC pro Fragment während der Übertragung (16-Bit-CCITT) | 2 Bytes pro Fragment |
Rollback- und Wiederherstellungsstrategie
Auch mit Image-Signierung können Laufzeitfehler auftreten (z. B. neue Firmware stürzt beim Booten ab). Ein dreistufiger Wiederherstellungsmechanismus sichert die Überlebensfähigkeit des Geräts:
- Boot-Validierung: Der Bootloader prüft den App-CRC bei jedem Boot. Ist er beschädigt, wird auf den vorherigen Bank zurückgesetzt.
- Anwendungs-Health-Check: Innerhalb von 30 Sekunden nach dem Boot schreibt die App ein „health OK“-Flag auf eine bestimmte flash-Seite. Fehlt das Flag beim nächsten Boot (App ist vor dem Schreiben abgestürzt), setzt der Bootloader zurück.
- Watchdog-Fallback: Ein unabhängiger Hardware-Watchdog (WDT) setzt den MCU zurück, wenn die App länger als 8 Sekunden hängt. Drei aufeinanderfolgende WDT-Resets lösen den Bootloader-Rollback aus.
// nRF52: Health check implementation
#define HEALTH_ADDR 0x000FE000 // Dedicated flash page for health flag
#define HEALTH_MAGIC 0xDEADBEEF
void app_health_check(void) {{
uint32_t val = 0xDEADBEEF;
sd_flash_write((uint32_t*)&val, HEALTH_ADDR, 1);
}}
// Bootloader check (in DFU bootloader):
// if (flash_read(HEALTH_ADDR) != HEALTH_MAGIC) {{ revert_bank(); }}
Bandbreitenoptimierungstechniken
Über BLE GATT dauert die Übertragung eines 120-KB-Firmware-Images mit 2.5 KB/s etwa 48 Sekunden. Optimierungsstrategien:
| Technik | Beschleunigung | Nachteil |
|---|---|---|
| Delta-Updates (Binär-diff) | 3-10x | Erfordert serverseitige Diff-Berechnung; Basis-Image muss übereinstimmen |
| L2CAP CoC statt GATT | 4-8x | Erfordert Aushandlung der Verbindungsparameter; weniger kompatibel |
| Komprimierung (LZMA/LZ4) | 2-3x | CPU-Kosten für Dekomprimierung; ~20 KB Stack-Overhead |
| MTU 247 + 6 gleichzeitige Benachrichtigungen | 2x gegenüber MTU 23 | Speicher für 6x Benachrichtigungspuffer (6 x 247 = ~1,5 KB) |
Delta-Update-Beispiel: Für eine 120-KB-Firmware mit 8 KB Änderungen zwischen den Versionen erzeugt ein Binär-Patch (bsdiff-Algorithmus) eine ~12-KB-Delta-Datei. Die Übertragungszeit sinkt von 48 Sekunden auf ~5 Sekunden, eine Verbesserung von fast 10x.
Produktions-OTA-Pipeline
- CI/CD erstellt das Firmware-Binärfile (.hex/.bin)
- Der Signier-Server wendet die ECDSA-P256-Signatur an → erzeugt eine signierte .zip
- Der Delta-Generator erstellt einen inkrementellen Patch gegen das vorherige Release
- Der OTA-Server hostet das Firmware-Manifest (Version, Größe, CRC, URL)
- Das Gerät prüft das Manifest, lädt Delta oder vollständiges Image herunter, verifiziert und wendet es an
- Das Gerät bootet in die neue Firmware; der Health-Check bestätigt den Erfolg
Strombudget während der OTA
OTA-Updates sind stromintensiv. Ein mit CR2477 betriebenes BLE-Tag mit 10 μA Durchschnittsstrom springt während des BLE-Empfangs für die Firmware-Übertragung auf ~15 mA. Budget-Berechnung für ein 120-KB-Update:
# OTA power budget
IMAGE_SIZE = 120000 # bytes
THROUGHPUT = 2500 # bytes/sec (BLE GATT)
TRANSFER_TIME = IMAGE_SIZE / THROUGHPUT # = 48 seconds
RX_CURRENT = 15e-3 # 15 mA during RX
VOLTAGE = 3.0 # CR2477 nominal
CHARGE_CONSUMED = RX_CURRENT * TRANSFER_TIME / 3600 # = 0.0002 Ah = 200 μAh
# CR2477 capacity: 1000 mAh
# OTA consumes 0.02% of total battery per update
# With monthly updates: 0.24% annual OTA budget (negligible)
Für eine zuverlässige OTA muss sichergestellt werden, dass das Gerät vor Beginn eines Updates >20% Restakku hat. Der sd_ble_gap_data_length_update()-Aufruf des BLE-Stacks mit MTU=247 und PHY=2M kann den Durchsatz auf ~10 KB/s erhöhen und die Übertragungszeit auf ~12 Sekunden verkürzen.
OTA-Firmware-Engineering ist ein kritisches Zuverlässigkeitsmerkmal für jeden Produktionseinsatz von Bluetooth-Modul. Die Kombination aus Dual-Bank-Architektur, ECDSA-Signierung und Health-Check-Rollback stellt sicher, dass Geräte über Hunderte von Update-Zyklen hinweg sicher und funktionsfähig bleiben. Unser Engineering-Team bietet OTA-Architekturprüfung und Einrichtung der Signier-Infrastruktur für Projekte mit Bluetooth-Modul an – kontaktieren Sie uns für eine technische Beratung.