Projet personnel
Bootloader OTA + firmware FreeRTOS sur STM32F411
Mise à jour firmware par UART avec rollback automatique sur Nucleo STM32F411RE — bootloader bare-metal, dual-bank, outil PC compagnon.
- C
- Python
- STM32 HAL
- FreeRTOS (app)
- UART
- ARM Cortex-M4
- STM32F411RE Nucleo
Problème
Mettre à jour un firmware déployé à distance sans risque de bricking. Quatre propriétés non négociables : atomicité (une coupure d'alim laisse le système bootable), intégrité (jamais sauter dans une image dont le CRC est faux), rollback (revenir à l'ancienne image si la nouvelle plante), et zéro brick possible.
Architecture
Le plan flash de 512 KB est découpé en cinq zones : bootloader 16 KB (secteur 0), métadonnées 16 KB (secteur 1), Slot A applicatif 96 KB (secteurs 2-4), Slot B applicatif 128 KB (secteur 5), et 256 KB de réserve. Trois acteurs en jeu : le bootloader (bare-metal, premier code au reset), le firmware applicatif (FreeRTOS multi-tâches, vit dans le slot actif avec VTOR repointé), et un outil PC Python qui pousse les nouvelles images via UART. Le bootloader lit les métadonnées au boot, vérifie le CRC du slot actif, gère la machine d'états rollback, puis saute vers l'application.
Points clés
- Bootloader bare-metal 16 KB (secteur 0 @ 0x0800_0000)
- Métadonnées 16 KB (secteur 1) : magic, slot actif, boot_count, CRC, validation
- Slot A (96 KB, secteurs 2-4) et Slot B (128 KB, secteur 5)
- Protocole UART trame [SOF | SEQ | LEN | DATA | CRC16] avec ACK / NAK
- App FreeRTOS multi-tâches, validée à T+10 s par une tâche dédiée
- Rollback automatique après 3 boots consécutifs sans validation
- Outil PC flash_ota.py avec barre de progression (tqdm)
Décisions techniques
01.Bare-metal pour le bootloader, FreeRTOS pour l'app
Le bootloader doit être minimal, déterministe, et tenir dans 16 KB. Pas de RTOS, pas de système de fichiers, pas de drivers exotiques — juste UART, flash, CRC, et un saut. L'applicatif, lui, gère plusieurs IO concurrents : un RTOS clarifie le code.
02.Dual-bank A/B avec métadonnées dédiées
Deux slots applicatifs plutôt qu'un seul : la nouvelle image s'écrit dans le slot inactif pendant que l'ancienne tourne. Une coupure d'alim pendant l'upload ne touche jamais le slot fonctionnel, donc le système reste bootable.
03.Validation par l'app + boot_count
Le bootloader ne peut pas savoir si une image démarre correctement. C'est donc à l'app de se déclarer valide (écriture du flag validated dans les métadonnées) après quelques secondes de fonctionnement nominal. Si elle plante avant — HardFault, watchdog reset — elle ne valide pas. Le bootloader incrémente boot_count et bascule sur l'autre slot après 3 tentatives.
04.Protocole UART simple avec ACK / NAK + CRC16
Trame [SOF | SEQ | LEN | DATA | CRC16], un octet de réponse par trame (ACK 0x06 ou NAK 0x15), retransmission côté PC. Choix volontaire de ne pas réutiliser XMODEM / YMODEM : plus simple à implémenter, plus simple à debugger à l'analyseur logique, et suffisant pour le besoin.