Cet article traite du fonctionnement logiciel du MS41. Je ne vais que gratter la surface.
J’ai analysé une grosse partie du logiciel MS41 ID41. Tout n’est pas parfait et il y a encore des inconnues. mais j’explique ici de manière simplifié le fonctionnement de certaines partie de ce que j’ai pu comprendre du logiciel.
Des fautes peuvent êtres présentes ou même des approximations.
J’essayerai d’ajouter dans le futur les modifications des autres version logicielles.
Plages d’adresses et octets par fonction:
Le MS41 est composé de 256Ko de mémoire flash, cependant cette mémoire est sur le même bus que la ram. donc toute une partie n’est pas adressable.
| Catégorie | Octets identifiés |
| Moteur | 20 166 |
| Sécurité | 11 622 |
| K-line | 9054 |
| Système | 8270 |
| Cliquetis | 7324 |
| Adaptations | 6470 |
| Injection | 6404 |
| Allumage | 5766 |
| EEPROM | 5470 |
| EWS | 2858 |
31,8 % du fichier full read est du code identifié pendant que 64,3 % est de la flash vierge
| Catégorie | addresses full read (début →fin) |
| ADAPTATIONS | 0x2974E–0x2A754 ; 0x2B610–0x2B70C ; 0x2DB14–0x2E358 |
| ALLUMAGE | 0x00E78–0x01E80 ; 0x2BB42–0x2BCC8 ; 0x35FAA–0x362F0 ; 0x36606–0x36816 |
| CLIQUETIS | 0x236D4–0x24000 ; 0x28BE2–0x28F84 ; 0x2C000–0x2CD8E ; 0x2EF1C–0x2F15C |
| EEPROM | 0x05718–0x05BCC ; 0x20096–0x202D6 ; 0x202D6–0x21140 |
| EWS | 0x0473C–0x0496C ; 0x04A24–0x04D28 ; 0x2268E–0x227B2 ; 0x2BFB8–0x2BFFE ; 0x2F840–0x2F9EC ; 0x362F0–0x365D2 |
| INJECTION | 0x0006C–0x001BC ; 0x008EE–0x00E78 ; 0x21434–0x214F2 ; 0x22E16–0x236D4 ; 0x288F4–0x28BE2 ; 0x2A754–0x2A8A4 ; 0x2E358–0x2E780 ; 0x36614–0x3665C |
| KLINE | 0x0496C–0x0498A ; 0x04D28–0x05438 ; 0x0552E–0x05718 ; 0x20000–0x20096 ; 0x26428–0x27118 ; 0x27688–0x27C62 ; 0x27D70–0x28000 ; 0x2BD10–0x2BF7A ; 0x2F37C–0x2F568 |
| MOTEUR | 0x06D90–0x071B8 ; 0x2234E–0x224C4 ; 0x24000–0x25404 ; 0x25FB6–0x26428 ; 0x286B4–0x288F4 ; 0x28F84–0x2974E ; 0x2B48C–0x2B610 ; 0x2B91E–0x2BB42 ; 0x2CD8E–0x2D700 ; 0x2E780–0x2EB06 ; 0x2F15C–0x2F37C ; 0x34BD8–0x35FAA ; 0x366BE–0x366D4 |
| SECURITE | 0x05BCC–0x05C14 ; 0x21140–0x21434 ; 0x219E6–0x221A8 ; 0x224C4–0x2268E ; 0x227B2–0x22E16 ; 0x25404–0x25FB6 ; 0x27118–0x27688 ; 0x27C62–0x27D70 ; 0x2B70C–0x2B91E ; 0x2BCC8–0x2BD10 ; 0x2BF7A–0x2BFB8 ; 0x2F568–0x2F840 ; 0x2F9EC–0x2FC52 ; 0x365D2–0x36606 |
| SYSTEME | 0x00000–0x000DE ; 0x04000–0x04730 ; 0x05438–0x0552E ; 0x06270–0x06400 ; 0x071B8–0x076AE ; 0x221A8–0x2234E ; 0x280F2–0x28438 ; 0x34000–0x34BD8 |
EWS:
1- A la mise sous tension du calculateur moteur, le CPU initialise son port série.(ASC1)
2- Le Calculateur moteur attend ensuite les trois lettres « BMW » envoyé sur le fil par l’EWS. Sans ca rien ne se passe.
3- Le DME présente un chalenge composé du code ISN ainsi que sa date de fabrication.
4- Le DME Calcule la réponse attendue de la par l’EWS. le résultat est une série de 4 octets
5- le DME compare le résultat avec celui de l’EWS.
Si ça correspond: Le calculateur autorise le fonctionnement normal du moteur
Si ça ne correspond pas: le calculateur retente 2 fois en incrémentant un compteur avant d’abandonner et de reste en immobilisation active.
Possiblement le même mécanisme que le Kline sécurisé.
Accès KLINE sécurisé:
Il existe dans le calculateur un second jeu, non documenté et non utilisé dans INPA ou autres logiciels dispo de BMW, un mode de diagnostique avancé caché derrière un mot de passe.
L’accès sécurisé permet, entre autres, de:
- Réécrire des zones mémoires
- Tester pour trouver les premières zones non vides de mémoire
- Lecture de la mémoire
- Selftest de l’EEPROM (pas la flash ni la ram)
Le moyen d’y accéder se fait par une commande suivit d’un mot de passe.
Cette commande défini un flag qui permet ensuite d’utiliser un set de commande caché
0x25, 0x21, 0x31 et d’autres. Je prendrait le soin de tout documenter dans la section ADS/ MS41du Wiki.
Le paquet magique de déverrouillage est le suivant:
12 08 90 42 4D 57 0E DC
Bien que connu, puisque utilisé par des logiciels qui permettent de flasher les MS41, celui ci été resté secret. (pas de secret avec moi)
Oui, c’est bien le mot « BMW » écrit en toutes lettres dans la trame….
Le calculateur répond avec un bloc de 46 octets (le « seed »). exemple de réponse:
12 2E A0 FF FF FF FF FF FF FF 31 31 30 31 FF FF FF FF 30 39 30 32 30 30 30 30 31 31 35 38 35 32 FF FF FF FF 30 32 30 32 31 31 36 30 33 56
On doit transformer le seed en clé grâce à une formule et l’envoyer au calculateur.
la formule est la suivante:
Octet 0 de la clé :
seed[11] + seed[38] + seed[15]
= FF (255) + 31 (49) + 30 (48)
= 255 + 49 + 48 = 352
352 – 256 = 96 = 0x60
Octet 1 de la clé :
seed[12] + seed[39] + seed[16]
= FF (255) + 36 (54) + 39 (57)
= 255 + 54 + 57 = 366
366 – 256 = 110 = 0x6E
Octet 2 de la clé :
seed[13] + seed[40] + seed[17]
= FF (255) + 30 (48) + 30 (48)
= 255 + 48 + 48 = 351
351 – 256 = 95 = 0x5F
Octet 3 de la clé :
seed[14] + seed[41] + seed[18]
= FF (255) + 33 (51) + 32 (50)
= 255 + 51 + 50 = 356
356 – 256 = 100 = 0x64
La clé calculée est 60 6E 5F 64
On reconstruit une trame avec le même format que la requête « BMW », mais avec la clé à la place de « BMW » .
12 08 90 60 6E 5F 64 BF
Le calculateur confirme avec A0. Si il répond avec A1 c’est qu’il est occupé et qu’il faut r’envoyer la clef. A2 il faut redémarrer l’ECU. on s’est fait jeté.
Bits de controle ID41:
Ces octets contiennent le codage du calculateur, Le même calculateur pouvant être monté avec le même logiciel dans différents châssis il faut pouvoir le configurer.
Ces octets sont présents dans le full read au adresses 0x10004 à 0x10008.
Octet 4:
| Bit | Rôle | Description |
| 0-4 (au moins un actif) | Temporisation du volet d’échappement | Active une fonction qui gère le minuteur du volet d’échappement — sans lien direct avec le fait de l’ouvrir/fermer, plutôt sa cadence. |
| 4 (seul) | Probablement lié à la clim | Désactive un ajustement automatique du ralenti |
| 5 | Interrupteur maître du VANOS | Le plus important de cet octet. Si absent, le VANOS ne s’active jamais, peu importe le régime ou la charge — la fonction s’arrête à la première instruction. |
| 6 | Inconnu | Positionné en mémoire mais jamais lu ailleurs — probablement sans effet sur ce logiciel précis. |
| 7 | Sans effet isolé | Ne correspond à aucun cas testé individuellement dans le code. |
Octet 5:
| Bit | Rôle | Description |
| 0x2B | Active un contrôle de panne calibré | Arme une vérification spécifique liée aux conditions moteur. |
| 0x2C | Déclenche un traitement de commande externe | Appelle directement une fonction de validation — un pont entre une requête K-line et une action interne. |
| 6 | Active un balayage de la liste des pannes | Vérifie si une panne stockée a un statut précis, et le signale ailleurs. |
| 7 | Gate le calcul cible carburant + sauvegarde EEPROM | Impact large : sans ce bit, deux fonctions majeures de calcul carburant et la sauvegarde des cellules d’apprentissage ne tournent pas. |
Octet 6:
| Bit | Rôle | Description |
| 0-1 | Probablement jamais lus | Absents du chemin de décodage |
| 0x18 | 1 canal de sonde O2 | Un seul capteur lambda physique |
| 0x1C | 2 canaux de sonde O2 | Deux capteurs, un par banc de cylindres |
| 5-7 | Inutile | Jamais lu nulle part dans le firmware. |
Octet 7:
| Bit | Rôle | Description |
| 0-2 | Masque de permission | Autorise ou verrouille certains comportements dynamiques ailleurs (word_FD18) — un mécanisme réel, sans nom de fonctionnalité précis. |
| 3 | Redirige l’apprentissage de cliquetis | Ce bit fait pointer le système d’adaptation (AdaptiveCorrection) directement vers les données de détection cliquetis. |
| 4-6 | Inutile | Inutile |
Octet 8:
| Bit | Rôle | Description |
| 0-1 | Inutile | Lu, puis le résultat est immédiatement écrasé sans jamais être utilisé |
| 2 | Contrôle de panne piloté par l’EWS | Active un des 21 états de notre plus grosse fonction de surveillance de pannes — probablement lié au contrôle du ralenti (IACV), mais pas certain à 100%. |
| 3 | Active ExhaustFlap_Control | Sans ce bit, la fonction entière de gestion du volet d’échappement ne fait rien. |
| 4-6 | Mort, avec un lien croisé | Sans consommateur propre, mais teste des sous-bits seulement si le bit cliquetis de Byte_7 est actif. |
| 7 | EWS Delete | Contourne le calcul modifie un statut partagé par presque tout le firmware. Un seul bit peut désactiver le lien avec l’immobilisateur. |
Adaptations:
Adaptations carburant:
On a 64 cellules stocké dans une zone en RAM de 368octets. Chaque cellule correspond a une combinaison Régime/Charge.
Chaque cellule contient 6 valeurs individuelles qui sont moyennées avant d’être utilisé.
Une cellule neutre contient 0x80.
Au fil des trajets, chaque cellule dérivé vers ce que le moteur à besoin.
Adaptation longue durée:
C’est un système séparé qui suit une tendance globale générale qui dérive vers une valeur stable.
Un bit de codage permet de faire pointer ce mécanisme ‘apprentissage directement vers les données de détection cliquetis.
Zero papillon:
Le calculateur apprend la position du papillon en se recalant a chaque fois qu’il détecte une lecture cohérente au ralenti.
Cliquetis:
Enregistre le seuil de bruit de fond normal de chaque capteur pour savoir a partir de quel seuil un signal doit être considéré comme un vrai cliquetis
Stockage:
Le tout est stocké a deux endroits.
Pendant que le moteur tourne, tout est en ram.
pour survivre a l’arrêt du calculateur, tout est copié de manière périodique dans la puce d’eeprom. (petite à 8 pins) avec laquelle le CPU communique en big-bang I2C.
| Zone EEPROM | Taille | Contenu |
| 0xE | 68 o | Grille des 64 cellules carburant |
| 0x52 | 4 o | Correction adaptative longue durée |
| 0x56 | 6 o | Etat du système de fenêtre adaptative |
| 0x5C | 4 o | Zéro papillon (TPS) |
| 0x60 | 8 o | Groupe de 5 valeurs d’adaptation annexes |
| 0x68 | 12 o | Bornes de fenêtre de détection cliquetis |
| 0xEA | 12 o | Trois « zones » d’adaptation supplémentaires |
Sécurité:
On ne peu jamais faire confiance a des données brutes. au redémarrage, chaque bloc est relu depuis l’eeprom puis passe par un checksum (vérification de corruption) puis un teste de plausibilité, pour savoir si la valeur est dans une plage raisonnable.
Si l’un des test échoue la valeur n’est pas utilisé et le calculateur repart sur une valeur neutre.
Boot de l’ECU
Le CPU, avant même de démarrer le moteur passe par une série d’étape lui permettant d’être opérationnel.
Le code configure immédiatement le contrôleur CAN externe et démarre la liaison série avec le microcontroleur externe qui gère le clapet d’échappement et le relais de clim ainsi que d’autres sorties.
Ensuite le CPU configure le watchdog, le Stack et verrouille les réglages systèmes.
Le calculateur fait ensuite une vérification d’intégrité, il écris un motif de test dans sa mémoire et le relis pour voir si elle réagit correctement.
Ensuite il passe par une vérification de démarrage a froid ou un démarrage rapide. Pour se faire il compare 3 copies redondantes d’un meme octet en mémoire. Si les trois se recoupent, il considère que la RAM est encore valide et prend un chemin de démarrage rapide en sortant certaines réinitialisations.
Vient ensuite la mise en place de ces périphériques internes.Les broces entées sorties, les ports de communications EWS, et si ce n’est un démarrage rapide, la configuration de son port série pour le Kline.
Ensuite vient le Coding. c’est la que le calculateur va se configurer pour le châssis..
Il commence déjà par vérifier une signature (non identifiée et non rempli), si vide, c’est le cas sur les ID41, le calculateur cal prendre le chemin de la configuration complète.
Il décode les 5 octets de configuration, il apprend a ce moment la configuration véhicule.
Puis il restaure en RAM les adaptations depuis l’eeprom, après avoir fait les vérifications expliquée dans le paragraphe sur les adaptations.
Il réinitialise ensuite soutes les valeurs du cycle précédent au cas ou une valeur aurai résisté a un redémarrage pour ne pas polluer un nouveau démarrage.
A partir d’ici le calculateur rentre dans sa boucle principale permettant au moteur de démarrer et de tourner.
DTC:
Le calculateur vérifie les valeurs de capteurs en permanence. Il contient des fonctions défiées a tous les capteurs principaux. Papillon des gazq, débit d’air et d’autres.
Le principe est plutôt simple. chaque lecture de capteur est vérifié avec des bornes raisonnables, propres a chaque capteur.
En cas de dépassement d’un capteur en dessous et a! dessus des limites raisonnables, le capteur est ignoré et le calculateur passe sur des valeurs refuges.
Anti rebond:
Le coeur du système repose sur une fonction permettant d’éviter le rebond des capteurs si il yy a une valeur parasite ou ponctuelle. Cette valeur est ignorée pour pas qu’a elle seule elle déclenche un défaut.
Chaque contrôle de valeur a son compteur de confirmation. La condition doit se répéter un certain nombre de fois pour que le défaut soit considéré.
Enregistrement:
une fois un défaut confirmée il y a plusieurs choses qui en découle.
Un instantané figé est capturé, 4 capteurs sont prélevés au moment de la confirmation. Une sorte de boite noire.
L’index de default est ajouté a une liste (2 en parallèle)
Chaque capteur a sa fiche descriptive indiquant au calculateur quel capteur ajouter a la freezer frame et quels sont les seuils du capteur.
Auto effacement:
si le féfault est passager: un mécanisme d’expiration fait vieillir le default stocké. Si il ne se reproduitt pas dans une certaine fenêtre il est automatiquement effacé.
Si le défaut fait partie d’une liste déclarée permanent. celui ci échappe au vieillissement automatique et est recopié dans l’EEPROM Externe pour survivre a la coupure du contact. Un vrai défaut enregistré dans cette EEPROM survit a un retrait de batterie. Il ne doit pas disparaitre puisque réel.
Diagnostique:
Il y a deux commandes qui permette de récupérer la liste des défaut.
La première 0x04 peu envoyé un résumé du nombre de default présent. soit le détail complet avec la freezer frame.
La seconde 0x05 permet d’effacer les default ainsi que les freeze-frames.
