elkloso
macht Rennlizenz
- Registriert
- 2 Juli 2017
- Wagen
- BMW Z4 e85 roadster 2,5i
Hi zusammen,
nach einigen Tagen Engineering und tatkräftiger Unterstützung durch @Moscha, habe ich das CVM IV aus dem E85 (und Mini R52) entschlüsselt bekommen. Somit kann man jetzt die Verdecköffnung während der Fahrt codieren.
Das CVM berechnet pro Block eine Checksumme (Check_Block_x). Diese muss am Ende wieder stimmen, dass er die Kodierung annimmt. Nun sind Checksummen aber nicht genormt, weshalb es dort nicht DAS Verfahren gibt, um sie zu berechnen. Wer mehr wissen möchte, hier entlang: Prüfsumme – Wikipedia
Also habe ich mir eine Excel Tabelle gebaut, die verschiedene valide Codierungen miteinander vergleicht. Manche sind schon bekannt gewesen (Hardtop vs Kein Hardtop, Mini vs. E85, C.01 vs. C.07) und andere habe ich heraus gefunden durch BruteForce (Geschwindigkeitsprüfung an vs. aus). Dann habe ich an der Tabelle alle möglichen Varianten probiert: Fletchers Checksum, stumpf die Data-Werte addieren, die Adresse mit einbeziehen,... Manche kamen schon nah heran, aber es gab immer wieder dann Summen, die meinen Ansatz widerlegt haben.
Schnell zeigte sich aber, dass die Masked Values etwas damit zu tun haben (dazu später mehr). Allerdings gingen sie manchmal hoch und manchmal runter, haben sich also nicht linear verhalten. Nachdem ich mich dann nochmal tiefer mit Memory-Management und allem was mit Binär-Daten zu tun hat, beschäftigt habe, bin ich auf das eigentlich bekannte Verfahren der Bitwise Operations gekommen. Also noch etwas herumprobiert und herausgefunden, dass Bitwise XOR verwendet wird.
NCS basiert auf sog. DATEN-Dateien, die wiederum übersetzen von eurem Fließtext in 0 und 1 (Bits & Bytes). Bei "nicht_aktiv" wird meist das Bit auf 0 gesetzt, bei "aktiv" auf 1.
Nun kann das Bit aber Werte von 00 bis FF (0 bis 255) annehmen. Somit können bei vielen Werten z.B. mehrere Optionen codiert werden. Tippblinken kann man z.B. auf "wert_01" = 1x, "wert_02" = 3x, usw. codieren. Was hier eigentlich passiert ist, dass in den DATEN gesagt wird: Wenn in der .MAN Datei "wert_02" steht, dann soll am Byte XY der Wert auf 03 gesetzt werden. Dadurch kann man den DATEN Dateien auch neue Werte beibringen (z.B. Tippblinken 7x), weil man einfach nur der DATEN Datei sagen muss, welchen Wert sie im Bit setzen soll.
Soweit, so einfach.
Jetzt sind unsere Steuergeräte aber recht alt und wir reden von einer Zeit als ganze Videospiele noch auf 1MB Kassetten für den Gameboy gepasst haben. Deswegen musste effizient programmiert und der Speicher genutzt werden. Also wurde Bit-Masking verwendet. Kurz gesagt teilen sich hier mehrere Codierungen ein Byte. Mithilfe der Maske werden sie miteinander verknüpft um somit schneller zu rechnen und Speicherplatz zu sparen. Da kommen jetzt auch wieder unser Bitwise Operations ins Spiel. Wen das so richtig interessiert, hier gehts lang: Bitfeld – Wikipedia
Somit hat z.B. bei "aktiv" der Eintrag den Wert 01, aber gesetzt wird eigentlich 08. Das ist wichtig zu wissen.
XOR bedeutet, dass die zweite Zahl besagt, ob die 0 oder 1 an der gleichen Stelle der ersten Zahl invertiert werden soll.
Als Beispiel: 0101 XOR 1001:
Position 1: 0 XOR 1 -> Die 0 wird invertiert
Position 2: 1 XOR 0 -> Die 1 wird nicht invertiert
Position 3: 0 XOR 0 -> Die 0 wird nicht invertiert
Position 4: 1 XOR 1 -> Die 1 wird invertiert
Das ist jetzt sehr vereinfacht und Bits liest man eigentlich von rechts nach links, aber ich hoffe das Prinzip wurde klar.
Wir müssen jeweils für einen Block die Masked Values per XOR verrechnen. Wie macht man das also?
Als praktisches Beispiel seht ihr hier den relevanten Block für die Geschwindigkeitsabfrage des Verdeck:
GESCHW_PRUEFUNG
wert_02
GESCHW_VERDECK_AKTIV
wert_02 -> 30km/h
wert_03 -> 50km/h
CHECK_BLOCK_04
wert_02
wert_03
wert_04
Die Datei bei C:/NCSEXPER/DATEN/E85 einfügen, vorher eure CVM_IV.C01 als Backup speichern.
Danach könnt ihr ganz normal über die MAN codieren.
Codieroptionen:
1. Gar keine Geschwindigkeitsprüfung (nicht empfohlen):
GESCHW_VERDECK_AKTIV
wert_01
GESCHW_PRUEFUNG
wert_01
CHECK_BLOCK_04
wert_02
2. Verdecköffnung bis 30km/h (empfohlen):
GESCHW_VERDECK_AKTIV
wert_02
GESCHW_PRUEFUNG
wert_02
CHECK_BLOCK_04
wert_03
3. Verdecköffnung bis 50km/h (empfohlen):
GESCHW_VERDECK_AKTIV
wert_03
GESCHW_PRUEFUNG
wert_02
CHECK_BLOCK_04
wert_04
nach einigen Tagen Engineering und tatkräftiger Unterstützung durch @Moscha, habe ich das CVM IV aus dem E85 (und Mini R52) entschlüsselt bekommen. Somit kann man jetzt die Verdecköffnung während der Fahrt codieren.
Wo lag die Schwierigkeit?
Das CVM nimmt normalerweise keine Werte an. Ändert man mit NCS einfach die Werte, wie z.B. im GM5 oder LSZ, dann bekommt man folgenden Fehler: "COAPI-2060: Codierung Fehlerhaft (allgemein)". Warum passiert das?Das CVM berechnet pro Block eine Checksumme (Check_Block_x). Diese muss am Ende wieder stimmen, dass er die Kodierung annimmt. Nun sind Checksummen aber nicht genormt, weshalb es dort nicht DAS Verfahren gibt, um sie zu berechnen. Wer mehr wissen möchte, hier entlang: Prüfsumme – Wikipedia
Lösungsansätze
Was kann man jetzt tun? Man kann die Checksumme bruteforcen, also alle Werte ausprobieren, was bei 255 Werten recht stressig werden kann, wenn man es bei jeder neuen Codierung machen muss.Also habe ich mir eine Excel Tabelle gebaut, die verschiedene valide Codierungen miteinander vergleicht. Manche sind schon bekannt gewesen (Hardtop vs Kein Hardtop, Mini vs. E85, C.01 vs. C.07) und andere habe ich heraus gefunden durch BruteForce (Geschwindigkeitsprüfung an vs. aus). Dann habe ich an der Tabelle alle möglichen Varianten probiert: Fletchers Checksum, stumpf die Data-Werte addieren, die Adresse mit einbeziehen,... Manche kamen schon nah heran, aber es gab immer wieder dann Summen, die meinen Ansatz widerlegt haben.
Schnell zeigte sich aber, dass die Masked Values etwas damit zu tun haben (dazu später mehr). Allerdings gingen sie manchmal hoch und manchmal runter, haben sich also nicht linear verhalten. Nachdem ich mich dann nochmal tiefer mit Memory-Management und allem was mit Binär-Daten zu tun hat, beschäftigt habe, bin ich auf das eigentlich bekannte Verfahren der Bitwise Operations gekommen. Also noch etwas herumprobiert und herausgefunden, dass Bitwise XOR verwendet wird.
NCS Grundlagen
Um das tiefer zu verstehen, muss man sich mit NCS etwas mehr auseinander setzen. Die meisten kennen die Möglichkeit mit Text zu codieren. Also z.B. "SIEDEMARKER_US_MIT_FRA_V" von "nicht_aktiv" auf "aktiv" setzen. Aber was passiert da eigentlich?NCS basiert auf sog. DATEN-Dateien, die wiederum übersetzen von eurem Fließtext in 0 und 1 (Bits & Bytes). Bei "nicht_aktiv" wird meist das Bit auf 0 gesetzt, bei "aktiv" auf 1.
Nun kann das Bit aber Werte von 00 bis FF (0 bis 255) annehmen. Somit können bei vielen Werten z.B. mehrere Optionen codiert werden. Tippblinken kann man z.B. auf "wert_01" = 1x, "wert_02" = 3x, usw. codieren. Was hier eigentlich passiert ist, dass in den DATEN gesagt wird: Wenn in der .MAN Datei "wert_02" steht, dann soll am Byte XY der Wert auf 03 gesetzt werden. Dadurch kann man den DATEN Dateien auch neue Werte beibringen (z.B. Tippblinken 7x), weil man einfach nur der DATEN Datei sagen muss, welchen Wert sie im Bit setzen soll.
Soweit, so einfach.
Jetzt sind unsere Steuergeräte aber recht alt und wir reden von einer Zeit als ganze Videospiele noch auf 1MB Kassetten für den Gameboy gepasst haben. Deswegen musste effizient programmiert und der Speicher genutzt werden. Also wurde Bit-Masking verwendet. Kurz gesagt teilen sich hier mehrere Codierungen ein Byte. Mithilfe der Maske werden sie miteinander verknüpft um somit schneller zu rechnen und Speicherplatz zu sparen. Da kommen jetzt auch wieder unser Bitwise Operations ins Spiel. Wen das so richtig interessiert, hier gehts lang: Bitfeld – Wikipedia
Somit hat z.B. bei "aktiv" der Eintrag den Wert 01, aber gesetzt wird eigentlich 08. Das ist wichtig zu wissen.
Bitwise WAS?
Kurz gesagt ist das ein bisschen wie Schriftliche Addition. Eine Folge von 0 und 1 werden miteinander kombiniert, um eine neue Folge zu erhalten. Dabei kann man Booleans wie AND, OR oder auch XOR verwenden.XOR bedeutet, dass die zweite Zahl besagt, ob die 0 oder 1 an der gleichen Stelle der ersten Zahl invertiert werden soll.
Als Beispiel: 0101 XOR 1001:
Position 1: 0 XOR 1 -> Die 0 wird invertiert
Position 2: 1 XOR 0 -> Die 1 wird nicht invertiert
Position 3: 0 XOR 0 -> Die 0 wird nicht invertiert
Position 4: 1 XOR 1 -> Die 1 wird invertiert
Das ist jetzt sehr vereinfacht und Bits liest man eigentlich von rechts nach links, aber ich hoffe das Prinzip wurde klar.
Zurück zur Checksumme
Das war jetzt ein großer Ausflug in die Informatik. Wie hilft uns das beim Steuergerät?Wir müssen jeweils für einen Block die Masked Values per XOR verrechnen. Wie macht man das also?
- Zunächst schauen wir uns in NCSDummy (NCS Dummy - Taking the expert out of NCS Expert) die Masked Values an. Dazu gehen wählen wir Baureihe und Modul aus, dann unten auf Module Functions und auf Export und speichern es als Text-Datei.
- Nun sehen wir mehrere Spalten. Interessant ist für uns "Function Keyword", "Data", "Masked". Hier wissen wir welche Funktion wir haben wollen, welchen Wert wir brauchen und wie er maskiert ist. z.B. "GESCHW_VERDECK_AKTIV wert_01" | "0A" | "0A". Also wissen wir, dass dieser Wert einen Masked Value von "0A" hat.
- Das übertragen wir uns alles in eine Tabelle und rechnen die jeweiligen Masked Values per XOR zusammen und zuletzt nochmal invertieren (XOR FF). Dann müssten wir auf den Check_Block Wert kommen.
- Nun können wir einen Wert ändern z.B. von "0A" auf "32" (10 auf 50). Wir müssen schauen, wie der Masked Value sich ändert. Entweder hat man es im Gefühl oder man fügt den Parameter bei NCS ein (1. Tab, Rechtklick, Add Parameter, Export -> Update Module) und exportiert wieder die Functions und schaut sich dann Wert wieder in der TXT an. Als Faustregel kann man sagen, wenn der Wert die Länge FF hat, dann ist Masked Value = Data Value
- Jetzt können wir uns wieder die Checksumme, wie in Schritt 3, berechnen und erhalten einen Wert.
- Diesen Wert fügen wir wieder in NCS Dummy als Parameter ein. Die Anleitung dazu findet ihr hier unter Punkt 3.1.4: NCS Dummy - Taking the expert out of NCS Expert
- Nun kann man die neu hinzugefügten Werte ganz normal per .MAN Datei in NCS kodieren
Als praktisches Beispiel seht ihr hier den relevanten Block für die Geschwindigkeitsabfrage des Verdeck:
Zu schwierig?
Im Anhang sind DATEN für das CVM.01. Auf Anfrage kann ich auch für die weiteren CVMs die DATEN bearbeiten. Diese haben neue Codierwerte erhalten.GESCHW_PRUEFUNG
wert_02
GESCHW_VERDECK_AKTIV
wert_02 -> 30km/h
wert_03 -> 50km/h
CHECK_BLOCK_04
wert_02
wert_03
wert_04
Die Datei bei C:/NCSEXPER/DATEN/E85 einfügen, vorher eure CVM_IV.C01 als Backup speichern.
Danach könnt ihr ganz normal über die MAN codieren.
Codieroptionen:
1. Gar keine Geschwindigkeitsprüfung (nicht empfohlen):
GESCHW_VERDECK_AKTIV
wert_01
GESCHW_PRUEFUNG
wert_01
CHECK_BLOCK_04
wert_02
2. Verdecköffnung bis 30km/h (empfohlen):
GESCHW_VERDECK_AKTIV
wert_02
GESCHW_PRUEFUNG
wert_02
CHECK_BLOCK_04
wert_03
3. Verdecköffnung bis 50km/h (empfohlen):
GESCHW_VERDECK_AKTIV
wert_03
GESCHW_PRUEFUNG
wert_02
CHECK_BLOCK_04
wert_04
Anhänge
Zuletzt bearbeitet: