IoT-Link · LevelStream · Bring-up matériel

Mise à jour OTA bloquée sur les prototypes M10

Analyse du bootloader, de la défaillance qui bloque la mise à jour OTA, de ses causes probables et des pistes de durcissement — appuyée sur le code source et la documentation u-blox.

Modem : u-blox SARA-R422M10S (FW 01.24) Bootloader : v0.1.9 MCU : STM32L412 Mis à jour : 25 juin 2026

En résumé

  • Le bootloader se connecte au webservice de mise à jour à chaque démarrage pour vérifier — et, si besoin, télécharger — une nouvelle version de firmware.
  • Cette connexion échoue par intermittence, toujours au même endroit : juste après le message Starting PDP, au moment d'ouvrir la connexion de données (+CME ERROR: no network service ou operation not allowed).
  • Conséquence : l'OTA peut échouer (de façon intermittente, ~2 fois sur 3) — aussi bien la mise à jour d'une sonde en service (qui tourne alors en boucle, log du 19/06) que le premier chargement du firmware sur une carte neuve. L'enjeu est donc la fiabilité, pas une panne systématique.
  • Cause de fond (confirmée par les logs terrain) : le bootloader force AT+CGACT=1,1 — commande nécessaire en 2G mais refusée en LTE-M (le contexte de données y est déjà monté). Le BL passe quand le modem accroche en 2G, échoue le plus souvent en LTE-M — d'où l'intermittence.
  • Aggravant : quand la sonde a déjà un firmware valide, un échec de connexion ne déclenche aucun nouvel essai automatique — le bootloader démarre l'application et remet la mise à jour au prochain redémarrage. Sur une sonde montée, la seule relance possible est un reset long à l'aimant : il rejoue bien l'OTA, mais échoue lui-même ~2 fois sur 3 → la mise à jour peut nécessiter plusieurs tentatives, voire rester bloquée.

1 Contexte & portée

La mise à jour à distance (OTA) échoue par intermittence sur les prototypes M10 (modem u-blox SARA-R422M10S) : le bootloader n'arrive pas toujours à joindre le webservice — que ce soit pour mettre à jour une sonde en service ou pour charger le firmware sur une carte neuve.

Ce document le décrit, propose un diagnostic appuyé sur la lecture du code et la documentation u-blox, distingue ce qui est vérifié de ce qui reste hypothèse, et liste les mesures et les tests à mener.

Méthode & honnêteté

L'analyse est statique : lecture du code source du bootloader (branche à jour, v0.1.9) et de la documentation u-blox. Elle n'a pas encore été confrontée à une trace réseau réelle ni à une mesure électrique. Les conclusions sont donc graduées (vérifié / probable / à tester), et la section Tests est conçue précisément pour lever les incertitudes avant de figer un correctif.

2 Le mécanisme OTA, étape par étape

À chaque démarrage, le bootloader exécute toujours la même séquence avant de passer la main à l'application.

  1. Allumage du modem Mise sous tension et séquence de power-on.
  2. Initialisation & attente d'enregistrement réseau Le modem doit être enregistré sur le réseau avant d'aller plus loin.
  3. Lecture de l'IMEI Identifiant unique utilisé pour interroger le serveur.
  4. Ouverture du contexte de données — « Starting PDP » C'est ici qu'échoue la connexion. (La trace « Starting PDP » n'apparaît qu'en build verbeux APP_VERBOSE.)
  5. Connexion au serveur & comparaison de checksum Le bootloader compare le checksum du serveur au firmware flashé et, si une mise à jour est en attente, la télécharge. S'il ne peut pas se connecter (étape 4), la mise à jour échoue.

La séquence est lisible telle quelle dans la boucle principale du bootloader :

application.cApplication_Loop — lignes 416-470 (abrégé)
// 1. Power on SARA_R422
ret = SARA_R422_Power_On(&appdata->SARA_R422);
// 2. Initialize SARA_R422  (inclut l'attente d'enregistrement réseau)
ret = SARA_R422_Init(&appdata->SARA_R422);
// 3. Read and store IMEI
ret = SARA_R422_Get_IMEI(&appdata->SARA_R422, appdata->IMEI, ...);
debug_print("[DEBUG]Starting PDP...\r\n");
// 4. SARA R422 PDP activate  <-- POINT DE PANNE
ret = SARA_R422_PDP_Connect(&appdata->SARA_R422, APN);
// 5. Enable HTTP, puis GET du checksum, comparaison, upgrade...

L'ouverture du contexte (étape 4) repose sur ces deux commandes :

SARA_R422.cSARA_R422_PDP_Connect — lignes 809-842 (abrégé)
// Configure PDP Context
sprintf(buf, "AT+CGDCONT=1,\"IP\",\"%s\"\r\n", Apn);   // APN = "tsiot"
ret = SARA_R422_Execute_Cmd(SARA_R422, buf);
...
// Enable PDP Context
ret = SARA_R422_Execute_Cmd(SARA_R422, "AT+CGACT=1,1\r\n");   // <-- commande qui échoue

3 Le symptôme et les deux opérations touchées

La défaillance est toujours la même — l'ouverture de la connexion de données échoue juste après Starting PDP, et le bootloader ne peut plus joindre le webservice. Mais elle frappe dans deux opérations OTA bien réelles : la mise à jour d'une sonde en service, et le premier chargement du firmware sur une carte neuve.

L'impact réel — la boucle de mise à jour

C'est le cas qui a déclenché l'analyse (log du 19/06). Le firmware reçoit une nouvelle version cible et redémarre dans le bootloader pour la télécharger — mais le bootloader échoue à se connecter (no network service), repart sur l'ancien firmware, que l'application redemande aussitôt de mettre à jour : la mise à jour tourne en boucle.

Log_20260619_206_FWUpdate.logdémarrage déclenché par la demande de mise à jour (extrait)
...rebooting to bootloader to get the new firmware
NVM Firmware checksum                    : c4c2…e2dd0   // firmware actuel
Configuration message Firmware checksum  : 5c9c…91e42   // nouvelle cible reçue par l'app
...
[DEBUG]Starting PDP...
[ERROR]CME ERROR Received : +CME ERROR: no network service   // <-- la connexion échoue
[ERROR]Can not connect to TCP
[DEBUG]Jumping on App...                                // repart sur l'ancien firmware -> boucle

Les deux opérations touchées, avec deux codes d'erreur distincts mais au même endroit du code :

Opération A — mise à jour (sonde en service)

+CME ERROR: no network service CME 30
Déclencheur
Nouvelle version poussée par le serveur (ou redémarrage à l'aimant, qui relance la vérification OTA).
Fréquence
Échoue ~2 fois sur 3 au reboot-aimant ; un power-off complet, lui, réussit.
Contournement
Power-off complet puis redémarrage (impossible sur sonde montée).
Enjeu terrain
Une sonde montée ne peut plus être éteinte ; seul le reset long à l'aimant relance l'OTA — mais ~1 fois sur 3 seulement.

Opération B — premier chargement (carte neuve)

+CME ERROR: operation not allowed CME 3
Déclencheur
Tout premier allumage d'une carte vierge — l'installation initiale du firmware (production).
Fréquence
~2 fois sur 3 ; le BL « ne va pas plus loin ».
Contournement
Power-off + redémarrage aimant fonctionne à tous les coups.
Corrélation terrain décisive — la techno réseau (RAT)

Sur les 30 cartes (logs à l'appui) : le bootloader passe quand le modem accroche en 2G et échoue le plus souvent en 4G (LTE-M). C'est cohérent avec la nature de AT+CGACT=1,1 : en 2G le contexte doit être activé à la main (commande utile → OK) ; en LTE-M le bearer est déjà monté (commande refusée → « operation not allowed »). L'intermittence ≈ la proportion de fois où le modem choisit LTE-M (sa techno préférée, URAT=7,9 = LTE-M + 2G). Corrélation forte mais non absolue — il arrive que ça passe aussi en LTE-M (selon le timing de l'attachement).

Les deux opérations échouent donc pour la même raison : le modem accroche en LTE-M et y voit CGACT refusé. (Sur une carte neuve, l'attachement de première fois — init SIM/eSIM, première sélection d'opérateur — peut s'ajouter ; le manuel AT décrit le code 3 comme « the MT is in a state which does not allow performing the entered command », p. 48. Mais cette piste « provisioning » reste secondaire face à la corrélation RAT.)

4 La racine commune

Dans tous les cas, le bootloader force AT+CGACT=1,1 — l'activation manuelle du contexte de données. Or, selon la techno sur laquelle le modem accroche, cette commande est soit nécessaire (2G), soit refusée (LTE-M, où le contexte est déjà monté).

Le levier choisi pour ouvrir la connexion est AT+CGACT=1,1, une commande standard (3GPP TS 27.007) d'activation explicite du contexte PDP, héritée du modèle GPRS où le contexte devait être activé à la main. Or :

Documentation u-blox — contexte PDP en LTE-M

Le manuel des commandes AT le pose noir sur blanc : « The initial EPS bearer established during LTE attach procedure is actually a default EPS bearer. » Le contexte de données par défaut (cid 1) est donc monté par l'attachement réseau lui-même. Forcer ensuite AT+CGACT=1,1 est redondant — et c'est la première commande de données émise, celle qui échoue dès que l'attachement n'est pas tout à fait terminé.

Réf. : LEXI-R4 / SARA-R4 series — AT commands manual (UBX-18068860, R31), §13.1.1 « PDP contexts » p. 189-190 ; +CGACT §13.7 p. 201, +CGPADDR §13.9 p. 205.

Autrement dit, le code force une étape que le réseau fait déjà de lui-même, et l'émet au moment le plus fragile. Les deux codes d'erreur (« no network service » et « operation not allowed ») ne sont que deux façons, pour le modem, de dire « je ne suis pas prêt pour ça maintenant ».

Niveau de preuve : le mécanisme (CGACT refusé en LTE-M) est confirmé par la corrélation RAT de terrain (forte, non absolue). Ce qui reste à préciser : pourquoi un démarrage donné accroche en LTE-M plutôt qu'en 2G, et une éventuelle composante serveur (test curl §9). La piste « alimentation / rail batterie » est, elle, largement supplantée.

5 Une fausse piste, écartée en toute transparence

Une première intuition — « le redémarrage aimant rallume le modem trop vite, il faut forcer un cycle d'alimentation plus propre » — ne résiste pas à la lecture du code.

Le bootloader force déjà un power-off complet à chaque échec. En fin de boucle, il coupe proprement le modem puis met la carte en veille profonde 5 minutes, alimentation modem coupée :

main.cboucle principale — lignes 112-123
while (1)
{
  ret = Application_Loop(&appdata);
  Modem_Reset(&appdata);                      // coupe proprement le modem (voir ci-dessous)
  // If an error occured, sleep to retry
  if (ret < 0 && appdata.FwIsConsistent != 1)
      Sleep(SLEEP_DURATION_SEC);             // 300 s = 5 min, alim modem coupée
  else
      Jump_To_App(&appdata);                 // démarre l'application
}
SARA_R422.cSARA_R422_Power_Off — lignes 422-458 (abrégé)
SARA_R422_Execute_Cmd(SARA_R422, "AT+CPWROFF\r\n");      // extinction logicielle
...
ret = SARA_R422_Wait_Powered(SARA_R422_AT_SUPPLY_OFF_DELAY, GPIO_PIN_RESET); // attend que VINT retombe — modem réellement OFF (2000 ms)
...
HAL_GPIO_WritePin(SARA_R422_POWER_SUPPLY, GPIO_PIN_RESET);  // coupe l'alimentation

Le firmware refait donc déjà, tout seul, l'essentiel de ce qu'un power-off manuel accomplit : coupure de l'alimentation modem + rail coupé 5 minutes + redémarrage à froid. « Forcer un cycle propre » est donc largement redondant — ce n'est pas là qu'est la solution. Cette correction est assumée : mieux vaut écarter une fausse piste que de coder un faux remède.

Confirmé par les tests terrain (22/06)

Quatre essais ont montré : power-off complet = OK, mais reboot-aimant = KO ~2/3. Cela infirme l'opposition « démarrage à froid vs reset logiciel » : l'intermittence est liée au cycle d'alimentation, pas au type de reset. Conséquence : inutile de recoder un « forçage de démarrage à froid » — c'est déjà ce que fait le nouvel essai, et ça ne suffit pas toujours.

6 Le vrai trou : un nouvel essai conditionné au mauvais critère

Si le bootloader sait refaire un cycle propre, pourquoi faut-il quand même une intervention humaine ?

Parce que ce nouvel essai automatique ne se déclenche que si le firmware interne est jugé « non cohérent ». La condition exacte (revoir l'extrait section 5) est :

Ce qui ne va pas

if (ret < 0 && FwIsConsistent != 1) → Sleep(300s) ; else → Jump_To_App

Si le firmware en place est cohérent (FwIsConsistent == 1), un échec de connexion ne déclenche aucun nouvel essai : le bootloader démarre l'application et la tentative OTA est silencieusement abandonnée jusqu'au prochain redémarrage. C'est précisément ce qui oblige aujourd'hui à un power-off manuel.

Conséquence terrain — critique

Sur une sonde déjà montée, on ne peut pas faire de power-off ; la seule relance est un reset long à l'aimant, qui rejoue bien l'OTA mais échoue lui-même ~2 fois sur 3 (le modem repart probablement « tiède », rail batterie pas vraiment à zéro). Résultat : sans nouvel essai interne, la mise à jour dépend de la chance — il faut parfois répéter le geste, et elle peut rester bloquée — alors qu'un simple retry logiciel la fiabiliserait.

Le correctif en découle directement : il faut un nouvel essai de la phase de données, indépendant de la cohérence du firmware — c'est l'automatisation du geste manuel « power-off + redémarrage » constaté sur le terrain.

7 Ce que dit la documentation u-blox

Plusieurs recommandations du fabricant convergent vers le même constat : la séquence actuelle est conçue « à l'ancienne » et mérite d'être alignée sur les bonnes pratiques Cat-M1.

Ce que disent les manuelsImplication pour le bootloader
Le bearer EPS par défaut est établi par la procédure d'attachement LTE (manuel AT, p. 190).Forcer AT+CGACT=1,1 est redondant en Cat-M1 — le contexte est déjà monté par l'attachement.
AT+CGPADDR lit l'adresse IP attribuée au contexte (manuel AT, §13.9, p. 205).Vérifier l'obtention d'une IP (lecture non destructive) plutôt qu'activer le contexte de force.
+CEREG et son URC (AT+CEREG=2, avec TAC/cell-id) sont documentés pour le SARA-R422M10S (manuel AT, §13.14, p. 214-216).Suivre l'enregistrement par URC est plus fiable et plus sobre que le polling actuel toutes les 500 ms.
« VCC supply can be removed only after V_INT goes low » — sinon « unrecoverable faulty state » (System Integration Manual, p. 32).Déjà respecté à l'extinction ; en revanche le power-on ne confirme pas l'extinction avant de réalimenter (voir §8).
Sources

Références vérifiées dans les deux documents u-blox de référence : le LEXI-R4 / SARA-R4 series — AT commands manual (UBX-18068860, R31) et le SARA-R4 series — System Integration Manual (UBX-16029218, R32). Les pages sont citées au fil du texte.

8 Points à améliorer (par ordre de priorité)

Ce sont des spécifications. Elles vont du correctif direct du symptôme aux durcissements de fond.

① Ne plus faire de « operation not allowed » un échec — valider sur l'IP priorité haute — correctif racine

Le problème n'est pas AT+CGACT=1,1 en soi (elle reste nécessaire en 2G), mais le fait d'en faire un échec quand elle est refusée. En LTE-M, « operation not allowed » veut juste dire « contexte déjà monté ». Le correctif : émettre CGACT, ne pas bloquer sur sa réponse, et valider sur l'obtention d'une IP (AT+CGPADDR). Marche en 2G comme en LTE-M — et donc après le retrait de la 2G. → Le correctif de fond, ciblé sur la cause prouvée (corrélation RAT).

SARA_R422.cSARA_R422_PDP_Connect — proposition (autour de la ligne 831)
// CGACT reste nécessaire en 2G — mais on NE bloque PLUS sur sa réponse :
SARA_R422_Execute_Cmd(SARA_R422, "AT+CGACT=1,1\r\n");
//  "OK"                                -> 2G : contexte activé
//  "+CME ERROR: operation not allowed" -> LTE-M : déjà actif   => les DEUX sont OK

// La vraie validation : a-t-on une IP ?
do {
    SARA_R422_Execute_Cmd(SARA_R422, "AT+CGPADDR=1\r\n");
    // "+CGPADDR: 1,<ip>"  -> succès si ip != 0.0.0.0
} while (ip_invalide && !timeout);
if (ip_invalide) return -1;   // là seulement, vrai échec

② Nouvel essai de la phase de données, indépendant de FwIsConsistent robustesse

Autour de l'appel à SARA_R422_PDP_Connect (application.c, lignes 462-470), prévoir 2 à 3 tentatives qui rejouent un cycle radio propre avant d'abandonner : AT+CFUN=0 puis AT+CFUN=1 force un nouvel attachement sans redémarrage complet. Avec le correctif ①, la connexion réussit dès la 1ʳᵉ tentative quelle que soit la techno : ce retry n'est donc plus le correctif central, mais un bon filet contre les vrais creux réseau (pas de couverture à l'instant T) — et il évite de dépendre d'un redémarrage externe.

③ Attendre la disponibilité réelle de la donnée avant de l'utiliser durcissement

L'attente actuelle valide l'enregistrement réseau, mais rien ne garantit ensuite que le service paquet est prêt avant d'émettre la première commande de données. Vérifier explicitement l'attachement paquet (AT+CGATT? = 1) — et idéalement passer l'enregistrement en notification URC (AT+CEREG=2) — comble cet écart. ⚠️ Si on passe en URC, il faut tokeniser le champ <stat> : le strncmp actuel sur « +CEREG: 0,1 » casse avec l'URC « +CEREG: 1,1 ».

④ Reprendre la main sur la sélection d'opérateur au démarrage cas carte neuve

Reprendre la main sur la séquence d'enregistrement (démarrer en mode « déconnecté » puis déclencher l'enregistrement explicitement) permet de maîtriser le choix de techno et le timing au démarrage — utile notamment au premier allumage d'une carte neuve. Secondaire une fois ① en place.

⑤ Renforcer le power-on probablement supplanté

Au power-on, la décharge avant réalimentation repose sur de simples temporisations aveugles (1 s avant réalimentation, 1 s après), sans jamais vérifier que le modem est réellement éteint :

SARA_R422.cSARA_R422_Power_On — lignes 394-420 (extrait abrégé)
HAL_GPIO_WritePin(SARA_R422_PWR_ON, GPIO_PIN_RESET);        // (L399)
HAL_GPIO_WritePin(SARA_R422_POWER_SUPPLY, GPIO_PIN_RESET);  // coupe l'alim (L400)
// Wait capacitors to discharge
HAL_Delay(SARA_R422_SUPPLY_ON_DELAY);                       // 1000 ms AVEUGLE, pas de contrôle VINT (L403)
HAL_GPIO_WritePin(SARA_R422_POWER_SUPPLY, GPIO_PIN_SET);    // réalimente (L406)
HAL_Delay(SARA_R422_SUPPLY_ON_DELAY);                       // encore 1000 ms aveugle (L407)

On pourrait attendre le passage à l'état bas de VINT (la primitive existe déjà) et allonger la marge de décharge — la règle u-blox « couper VCC seulement après VINT bas » figure au System Integration Manual, p. 32. Mais la corrélation RAT supplante très probablement cette piste : ce qui décide de l'échec, c'est la techno d'accroche (LTE-M), pas la propreté du cycle d'alim — un power-cycle plus propre ne ferait, au mieux, que biaiser le choix de techno. À ne considérer que si ① ne suffisait pas.

⚠️ La 2G masque le bug — séquencement critique

Aujourd'hui, le seul chemin fiable est le repli 2G (où CGACT est utile et passe). Or le retrait de la 2G est décidé pour la certif RED : URAT=7,9URAT=7,8 (LTE-M + NB-IoT, 0 % 2G), cohérence bootloader ↔ application. En LTE-M/NB-IoT seuls, l'OTA reposerait sur le chemin qui ne passe qu'occasionnellement → elle deviendrait largement non fiable. Le correctif ① est donc un pré-requis pratique au retrait de la 2G (à faire d'abord). Risque très élevé — pas une garantie de panne totale.

9 Tests à mener (avant de figer un correctif)

L'analyse est statique. Une instrumentation légère tranchera entre les causes possibles et confirmera (ou non) chaque hypothèse.

Instrumentation à ajouter

Faire enregistrer par le bootloader, juste avant l'ouverture du contexte de données et en numérotant le passage (1er démarrage / nouvel essai n°…) :

À capturerCe que ça révèle
AT+CMEE=2 (absent du code — à activer)Affiche le numéro d'erreur exact (3 vs 30)
Quelle commande échoue : CGDCONT (L814) ou CGACT (L831)Localise précisément le point de rupture
AT+CEREG?Enregistré / en recherche / refusé
AT+CGATT?Service paquet attaché ou non
AT+CSQQualité du signal (99 = pas de signal → piste radio)
AT+CGPADDRUne IP est-elle déjà attribuée ?
La techno (RAT) — champ <AcT> de AT+CEREG? ou AT+COPS?2G vs LTE-M — le discriminant clé (le BL ne la logge pas aujourd'hui)
Le test décisif — la techno (RAT)

La preuve est déjà largement là (corrélation de Serge sur 30 cartes) : noter la RAT à chaque essai et la croiser avec le résultat doit confirmer « échec ⟺ LTE-M / succès ⟺ 2G ». Et surtout : vérifier qu'avec le correctif ① une accroche LTE-M passe.

Test secondaire (ancienne piste alimentation, désormais peu probable) : sur plusieurs reboots-aimant, voir si l'échec persiste au 2ᵉ passage automatique (après les 5 min de veille). S'il disparaît → composante premier-démarrage ; s'il persiste → ce n'est pas l'alim.

Test serveur (en parallèle)

La boucle pourrait avoir une composante serveur non encore écartée. Vérifier ce que renvoie le webservice pour l'IMEI concerné : curl …/otafwupgrade/checksum?imei=<IMEI> → renvoie-t-il la nouvelle cible (5C9C…) ou encore l'ancien checksum (C4C2…) ? Tant que ce point n'est pas vérifié, on ne peut pas affirmer que la boucle est un échec purement réseau.

Table de décision

ObservationCause probableCorrectif visé
CGACT KO + modem en LTE-M (bon CSQ, CEREG 1/5)Contexte déjà monté (cause confirmée)① tolérer + CGPADDR
CSQ=99 ou CEREG 0/2 persistantRadio / couverture / eSIM④ COPS, pas l'alim
Échec disparaît au 2e passage (rare)Composante premier-démarrage② retry (⑤ supplanté)
Carte neuve, operation not allowed au CGACTAccroche LTE-M (même cause)① tolérer + CGPADDR

Checklist

  • Activer AT+CMEE=2 et recompiler en mode verbeux.
  • Instrumenter le log (code CME, commande fautive, RAT (2G/LTE-M), CEREG/CGATT/CSQ/CGPADDR, n° de passage).
  • Série de ≥10 redémarrages aimant — noter persistance ou non au 2e passage.
  • Idem sur carte neuve : vérifier qu'elle accroche aussi en LTE-M.
  • Décider, table en main, quels correctifs figer.

10 Niveaux de confiance

AffirmationConfiance
La phase post-« Starting PDP » est fragile, sans nouvel essai indépendant de la cohérence firmwareÉlevée — vérifié dans le code
Le BL fait déjà un power-off complet de 5 min au nouvel essaiÉlevée — vérifié dans le code
CGACT=1,1 refusé en LTE-M (contexte déjà monté), nécessaire en 2GÉlevéeconfirmé par la corrélation RAT terrain (échec ⟺ LTE-M, succès ⟺ 2G) ; forte mais non absolue
Carte neuve : échoue pour la même cause RAT (accroche LTE-M)Élevée ; la part « provisioning eSIM » spécifique reste Modérée
Correctif ① (tolérer « operation not allowed » + valider sur CGPADDR)Élevée — adresse la cause prouvée, couvre 2G + LTE-M ; à valider au banc
Le renforcement du power-on changerait quelque choseProbablement supplanté — la RAT explique le symptôme, pas le cycle d'alim
Cadrage

Le sujet est le durcissement de la fiabilité OTA — déterminant pour le déploiement terrain, où une sonde montée ne peut être relancée qu'à l'aimant. C'est un travail de robustesse, à confirmer par l'instrumentation avant tout correctif.

11 Carte du code (repères)

ÉlémentFichier — lignes
Boucle principale + logique de nouvel essaimain.c — 112-123
Séquence de la boucle applicative (étapes 1-5)application.c — 416-470
Critère de cohérence firmware (FwIsConsistent)application.c — 388, 400, 530, 615-616
Ouverture du contexte de données (point de panne)SARA_R422.c — 809-859
Attente d'enregistrement réseau (CREG + CEREG)SARA_R422.c — 190-241
Power-on (décharge aveugle, 2 × 1 s)SARA_R422.c — 394-420
Power-off (CPWROFF + attente VINT + coupure alim ; early-return si alim déjà coupée)SARA_R422.c — 422-458
Base de référence

Analyse réalisée sur le bootloader v0.1.9, branche rapatriée à jour. Les extraits ci-dessus sont des spécifications, pas des modifications appliquées.