En ligne ou hors ligne
Chez Energetika-VDS, le flashage firmware se fait sur notre ligne via des fixtures de programmation dédiées. Quand le plan de test client appelle un test fonctionnel, l'unité poursuit chez un partenaire de test avec le firmware déjà chargé. L'AOI est réalisée en interne sur chaque carte ; le FCT est sourcé.
Certains fabricants intègrent le flashage dans la même fixture que le test fonctionnel : la carte est posée une seule fois, la programmation s'exécute d'abord, puis le test. Cela fonctionne quand les deux étapes vivent dans le même bâtiment. Dans notre configuration, flashage et FCT sont physiquement séparés : nous exécutons le flashage en ligne, et le partenaire de test exécute la séquence fonctionnelle sur le firmware fraîchement programmé.
Pour les produits sans test fonctionnel au périmètre, la carte flashée est expédiée après l'AOI sans porte de test supplémentaire.
Interfaces de programmation
L'interface avec la puce varie selon la famille de puces :
- SWD : ARM Cortex-M, faible nombre de broches, rapide
- JTAG : ARM ancien, FPGA, aussi debug pour de nombreuses puces
- UART : programmation par bootloader, plus lente mais sans broches supplémentaires
- USB-DFU : puces compatibles USB, la carte se présente comme périphérique USB pendant la programmation
- I2C, SPI : moins courants, utilisés pour certaines EEPROM et éléments sécurisés
La plupart des flashages en production utilisent SWD pour les composants ARM Cortex-M et JTAG pour les pièces plus anciennes ou à plus grand nombre de broches.
Programmation multi-image
Un appareil connecté possède généralement plus d'une image firmware :
- Bootloader : petit, signé, immuable après production
- Application : firmware principal, actualisable par OTA
- Système de fichiers : configuration, ressources web, magasin de certificats
- Partition d'usine : étalonnage par unité, identité, données d'usine
Côté production, la programmation écrit chaque image en séquence, dans la bonne partition, avec la bonne signature le cas échéant.
Chaînes de bootloader signées
Un bootloader signé vérifie la signature de l'application avant de la démarrer. Le bootloader lui-même est signé par le mécanisme de secure boot de la puce (hash stocké en eFuse, vérification en ROM).
Résultat : un attaquant ne peut pas remplacer l'application par du code arbitraire, car le bootloader refusera de la démarrer. Un attaquant ne peut pas remplacer le bootloader, car la puce refusera de démarrer un bootloader non signé.
Côté production, cela implique :
- Clé de signature du bootloader générée et stockée dans un HSM
- Clé de signature de l'application générée et stockée dans un HSM
- La ligne de production accède à la signature via une API, sans jamais détenir la clé privée
- eFuse brûlée pour figer la signature du bootloader
Tolérance à la coupure d'alimentation
Les séquences de programmation doivent tolérer une coupure d'alimentation en cours de flashage. Schéma courant : écrire d'abord le bootloader à un emplacement fixe, écrire l'application dans une zone distincte, ne positionner un drapeau "valide" en NVS qu'après vérification. Si l'alimentation tombe pendant l'écriture, le bootloader voit l'absence du drapeau valide et revient au firmware connu bon (ou refuse de démarrer, selon la politique).
Vérification
Après écriture, relire l'image flashée et calculer son hash. Comparer au hash attendu. Si différent, marquer l'unité comme échec de flashage et l'aiguiller en retouche.
Cela attrape le cas rare où l'écriture a réussi mais la puce a écrit n'importe quoi.
Journalisation par unité
Après un flashage réussi, journaliser :
- Version firmware
- Hash firmware
- Référence de clé de signature
- Horodatage de programmation
- Numéro de série de l'unité
Ces données vivent dans la base de traçabilité de production. L'acheteur pourra interroger plus tard : "quel firmware a été expédié sur le numéro de série XXX, signé par quelle clé".