La séquence de flash UDS, service par service
Écrire un calculateur par la couche UDS (ISO 14229) n'est pas « envoyer un fichier ». C'est une suite d'étapes nommées, chacune correspondant à un service identifié par un octet, exécutées dans un ordre imposé. En connaître le déroulé, c'est pouvoir lire une trace et dire où et pourquoi une écriture a échoué. La fiche Les sessions de diagnostic traite de l'enchaînement des sessions ; celle-ci suit la séquence complète d'un flash, service par service.
Avant tout : les préconditions
La programmation ne se lance pas dans n'importe quel état. En session diagnostique étendue (service 0x10, sous-fonction extendedDiagnosticSession), l'outil vérifie d'abord les préconditions : véhicule à l'arrêt, tension stable. Deux services préparent le terrain :
- 0x28 CommunicationControl met en pause le trafic normal de messages, pour qu'un nœud puisse devenir silencieux sans perturber le reste ;
- 0x85 ControlDTCSetting désactive l'enregistrement des codes défaut, afin que les autres calculateurs ne journalisent pas de défauts pendant l'opération.
La tension mérite une insistance particulière : une écriture efface puis réécrit la mémoire, et une chute en cours de route laisse un état partiel. Voir la chute de tension et le maintien de charge.
La séquence proprement dite
| # | Service | Nom | Ce qui se passe |
|---|---|---|---|
| 1 | 0x10 | DiagnosticSessionControl → programmingSession | l'exécution bascule typiquement au bootloader |
| 2 | 0x27 | SecurityAccess | l'échange seed & key déverrouille le chemin d'écriture |
| 3 | 0x31 | RoutineControl → routine d'effacement | efface le bloc logique cible |
| 4 | 0x34 | RequestDownload | déclare adresse, taille et format des données |
| 5 | 0x36 | TransferData | transfère l'image bloc par bloc, derrière un compteur de séquence |
| 6 | 0x37 | RequestTransferExit | clôt le transfert et déclenche le contrôle d'intégrité |
| 7 | 0x31 | RoutineControl → vérification | contrôle d'intégrité + contrôle de dépendances |
| 8 | 0x11 | ECUReset | démarre la nouvelle application |
Une réponse positive vaut SID + 0x40 : le calculateur répond 0x74 à un 0x34, 0x71 à un 0x31, et ainsi de suite. Le service 0x3E TesterPresent est émis en arrière-plan pour maintenir la session ouverte pendant les temps longs.
Pourquoi cet ordre, et pas un autre
La session d'abord (0x10). Passer en programmingSession fait généralement basculer l'exécution vers le bootloader, le seul composant capable d'écrire la flash. C'est une couche à part, avec ses propres droits.
La sécurité ensuite (0x27). Le seed & key ouvre le chemin d'écriture. Dans son principe : l'outil demande une graine, le calculateur renvoie une valeur, l'outil calcule et renvoie une clé, le calculateur recalcule de son côté la clé attendue et compare. Concordance : accès accordé. L'algorithme est défini par le constructeur ; aucun calcul de clé n'est décrit ici.
L'effacement avant l'écriture (0x31). Une flash doit être effacée — remise à l'état logique « tout à un » — avant d'être reprogrammée. La routine d'effacement vide le bloc logique cible. C'est un point que beaucoup ignorent : on n'« écrase » pas une flash, on l'efface puis on la réécrit.
Déclarer, puis transférer (0x34 → 0x36). Le RequestDownload annonce où (adresse), combien (taille) et sous quelle forme (format, éventuelle compression). Ensuite seulement le TransferData envoie l'image, découpée en blocs numérotés par un compteur de séquence. Ce compteur permet la reprise : renvoyer un TransferData avec un compteur identique doit être accepté — c'est le mécanisme de retry prévu par la norme. Détail souvent ignoré : dans beaucoup de calculateurs, le pilote d'écriture flash n'est pas résident ; il est téléchargé en mémoire vive au début de la session et disparaît au reset. En fonctionnement normal, il n'existe donc aucun chemin d'écriture permanent vers la flash — une sécurité en soi.
Clore et vérifier (0x37 → 0x31). Le RequestTransferExit ferme le transfert et déclenche le contrôle d'intégrité. Puis une routine de vérification fait deux choses : un contrôle d'intégrité (type CRC ou empreinte) sur ce qui a été écrit — voir qu'est-ce qu'un checksum —, et un contrôle de dépendances : la combinaison de blocs présente en flash a-t-elle le droit de tourner ensemble ? C'est ce qui explique qu'une calibration refuse de fonctionner sur une application incompatible.
Redémarrer (0x11). L'ECUReset relance le calculateur, qui démarre la nouvelle application — à condition que la vérification ait réussi. Et parce que le bootloader résident ne s'efface jamais lui-même et revalide l'application à chaque démarrage, une écriture interrompue laisse le plus souvent le calculateur en mode programmation, récupérable, plutôt que mort.
La traçabilité laissée derrière
Une programmation propre ne laisse pas le calculateur anonyme : la norme prévoit d'y inscrire qui a écrit et quand. Le code de l'atelier ou de l'outil (identifiant F198) et la date de programmation (F199) sont écrits pendant l'opération, aux côtés des empreintes de mise à jour (F183 à F185). C'est ce qui permet, plus tard, de savoir qu'un calculateur a été reprogrammé, et par quel canal. Cette traçabilité se recoupe avec le CAL ID et le CVN, qui, eux, attestent du contenu de la calibration.
Lire un échec
L'intérêt de connaître cette chorégraphie est diagnostique. Une écriture qui échoue le fait à une étape précise, signalée par une réponse négative (0x7F). Savoir à quel service le refus est tombé oriente immédiatement : sécurité, effacement, transfert ou vérification. C'est l'objet de la fiche lire un refus UDS. Et si le calculateur reste muet après coup, voir calculateur muet après écriture et écrire un fichier sans prendre de risque.
Voir aussi les sessions de diagnostic, seed & key et lire un refus UDS.
Sur ANP Engineering — file service de reprogrammation moteur pour professionnels : file service ECU, correction de checksum, calculateurs pris en charge, tarifs.
