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 serviceouoperation not allowed). - Conséquence : la mise à jour OTA n'aboutit pas. Quand une version est en attente, le firmware redémarre dans le bootloader pour la chercher, celui-ci n'arrive pas à se connecter, repart sur l'ancien firmware… et recommence : c'est la boucle observée dans le log du 19/06.
- Cause de fond : le bootloader engage la phase de données avant que la pile réseau du modem ne soit prête, et force
AT+CGACT=1,1— redondant en LTE-M où le contexte s'active à l'attachement. - Aggravant : le bootloader sait refaire un cycle propre, mais il ne réessaie pas la connexion quand le firmware est jugé cohérent — d'où le power-off manuel, impossible sur une sonde monté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 de mise à jour.
Ce document les 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.
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.
- Allumage du modem Mise sous tension et séquence de power-on.
- Initialisation & attente d'enregistrement réseau Le modem doit être enregistré sur le réseau avant d'aller plus loin.
- Lecture de l'IMEI Identifiant unique utilisé pour interroger le serveur.
- 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.) - 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 :
// 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 :
// 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 ses contextes
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 de mise à jour. Elle s'est manifestée dans trois situations — la plus importante étant la mise à jour elle-même.
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.
...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
Pour caractériser cette instabilité, la même défaillance a été reproduite dans deux conditions de démarrage, avec deux codes d'erreur distincts mais au même endroit :
Sonde en service (reboot aimant)
+CME ERROR: no network service CME 30- Déclencheur
- Redémarrage par l'aimant.
- Fréquence
- Intermittent, ~2 fois sur 3.
- Contournement
- Un power-off complet puis redémarrage fonctionne.
- Enjeu terrain
- Une sonde montée ne peut plus être éteinte — seul l'aimant reste disponible.
Carte neuve (1er allumage)
+CME ERROR: operation not allowed CME 3- Déclencheur
- Tout premier allumage d'une carte jamais utilisée.
- Fréquence
- ~2 fois sur 3 ; le BL « ne va pas plus loin ».
- Contournement
- Power-off + redémarrage aimant fonctionne à tous les coups.
Le cas « operation not allowed » (carte neuve) s'explique très probablement par un provisioning de première fois du modem : au tout premier allumage, le module doit initialiser la SIM/eSIM, faire sa première sélection d'opérateur et son premier attachement réseau. Tant que ce n'est pas terminé, une commande de données est refusée. Le deuxième démarrage réussit parce que le premier a amorcé ce provisioning — pas parce que la coupure d'alimentation aurait « nettoyé » quoi que ce soit. Le manuel AT définit d'ailleurs le code 3 comme « the MT is in a state which does not allow performing the entered command » (p. 48) — soit exactement « pas prêt pour cette commande ».
4 La racine commune
Dans tous les cas, le bootloader engage la phase de données alors que la pile réseau du modem n'est pas encore totalement prête — sans mécanisme robuste d'attente ou de nouvel essai à cet endroit.
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 :
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), chap. 13 « PDP contexts » p. 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 ».
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 :
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_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.
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 :
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.
Sur une sonde déjà montée, le power-off manuel est impossible. Sans nouvel essai interne de la phase de données, la mise à jour OTA peut donc tout simplement ne jamais aboutir, même si le réseau redevient disponible quelques secondes plus tard.
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 manuels | Implication 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). |
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.
① Remplacer l'activation forcée par une vérification d'IP priorité haute
Au lieu de AT+CGACT=1,1 (la commande qui échoue), interroger AT+CGPADDR en boucle jusqu'à obtenir une adresse IP valide (≠ 0.0.0.0), avec un délai généreux. C'est une lecture non destructive, conforme au LTE-M, et valable quelle que soit la cause. → Le meilleur correctif unique si on ne devait en faire qu'un.
// AVANT (à retirer) : // AT+CGACT=1,1 -> "+CME ERROR: ..." si l'attachement n'est pas prêt // APRÈS : attendre que le réseau ait attribué une IP (le contexte s'active seul en Cat-M1) do { SARA_R422_Execute_Cmd(SARA_R422, "AT+CGPADDR=1\r\n"); // lire "+CGPADDR: 1,<ip>" -> succès si ip != 0.0.0.0 } while (ip_invalide && !timeout);
② Ajouter un nouvel essai de la phase de données, indépendant de FwIsConsistent priorité haute
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. C'est l'automatisation du power-off manuel — la mesure la plus importante pour le terrain (sondes montées).
③ 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.
④ Reprendre la main sur la sélection d'opérateur au démarrage cas carte neuve
Pour le cas de la carte neuve, démarrer en mode « déconnecté » puis déclencher l'enregistrement de façon explicite évite que le bootloader ne tire des commandes de données pendant que le modem fait encore son provisioning de première fois.
⑤ Renforcer le power-on — seulement si les tests le prouvent dernier recours
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 :
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 : comme le bootloader fait déjà un power-off complet au nouvel essai (§5), ce renforcement n'apporterait, au mieux, qu'un gain de temps au premier démarrage — et rien du tout si la cause réelle est ailleurs (radio, couverture, provisioning). À ne coder que si l'instrumentation prouve que le premier démarrage incomplet est bien en cause.
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°…) :
| À capturer | Ce 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+CSQ | Qualité du signal (99 = pas de signal → piste radio) |
AT+CGPADDR | Une IP est-elle déjà attribuée ? |
Faire au moins 10 à 15 redémarrages aimant et regarder si l'échec persiste au deuxième passage automatique (après les 5 minutes de veille) :
- S'il disparaît tout seul au second passage → c'est bien un problème de premier démarrage / décharge.
- S'il persiste malgré un cycle complet → la cause est ailleurs (radio, couverture, eSIM) — inutile de toucher à l'alimentation.
Table de décision
| Observation | Cause probable | Correctif visé |
|---|---|---|
CSQ bon + CEREG 1/5 mais CGACT KO | Contexte data / commande inadaptée | ① CGPADDR |
CSQ=99 ou CEREG 0/2 persistant | Radio / couverture / eSIM | ④ COPS, pas l'alim |
| Échec disparaît au 2e passage | Premier démarrage incomplet | ⑤ power-on (et ② retry) |
Erreur dès CGDCONT sur carte neuve | Provisioning non terminé | ② retry + ④ COPS |
Checklist
- Activer
AT+CMEE=2et recompiler en mode verbeux. - Instrumenter le log (code CME, commande fautive, 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 pour confirmer la piste provisioning.
- Décider, table en main, quels correctifs figer.
10 Niveaux de confiance
| Affirmation | Confiance |
|---|---|
| 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 |
AT+CGACT=1,1 est le mauvais levier en Cat-M1 | Élevée — code + doc u-blox |
| Carte neuve = course de provisioning au premier boot (SIM/eSIM) | Modérée — cohérent, à confirmer par l'instrumentation |
| « CGPADDR au lieu de CGACT » comme correctif | Modérée — la vérif IP est solide, le remplacement reste à valider au banc |
| Le renforcement du power-on changerait quelque chose | À tester — dépend du test décisif |
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ément | Fichier — lignes |
|---|---|
| Boucle principale + logique de nouvel essai | main.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 |
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.