Ich experimentiere gerade etwas mit einem SLCAN-Fähigen CAN-Bus
Interface und einem PAM-Modul (Einparkhilfe) aus einem Ford herum. Das
Interface ist über einen VCP-Treiber als serielle Schnittstelle am PC
verfügbar. Das SLCAN-Protokoll bediene ich über ein Python3 script.
Nun habe ich versucht eine einfache UDS-Abfrage durchzuführen. Dabei
möchte ich die HW-Versionen des Moduls auslesen. Laut UDS-Standard (ISO
14229-1) verwende ich dazu den Service Identifier (SID) 0x22 alias "Read
Data By Identifier") und darin den Parameter 0xF191 alias "Vehicle
Manufacturer ECU Hardware Number Data Identifier".
Das von meinem als Tester (Client) fungierenden Interface zu sendente
Datenpaket sieht dann so aus (alle Werte in Hex):
1
CAN-ID LEN D0 D1 D2 D3 D4 D5 D6 D7
2
----------------------------------
3
736 8 03 22 F1 91 00 00 00 00
Laut UDS-Protokoll ist in D0 sowohl der Frame-Type (oberes Nibble) als
auch die Frame-Länge (unteres Nibble) kodiert. In dem Fall steht 0b0000
beim Frame-Type für "Single Frame (SF)" und 0b0011 für 3 Byte Länge. Der
Rest der Botschaft ist selbsterklärend.
Nun erhalte ich vom Modul (Server) folgende Antwort:
1
CAN-ID LEN D0 D1 D2 D3 D4 D5 D6 D7
2
----------------------------------
3
73E 8 10 1B 62 F1 91 36 47 39
Auch die verstehe ich noch so wie in UDS definiert. In D0 enthält das
obere Nibble (0b0001) dem Frame-Type "First Frame (FF)", was bedeutet
das die gesamte Antwort nicht in einen Frame passt und somit noch
weitere folgen werden. Das untere Nibble sowie D1, also in Summe 12
Bits, enthalten die Gesamtlänge der Antwort, in diesem Fall 0x1B (27)
Bytes. In D2 ist die positive Antwort auf meine UDS-Anfrage enthalten
(0x40 + SID) und D3+D4 spiegeln meine Anfrageparameter wieder. Ab D4
kommt dann der Nutzdatenteil der Antwort.
Soweit, sogut. Nun müsste ich laut UDS-Protokoll ein "Flow Control (FC)"
Frame senden um dem Server mitzuteilen das und wie ich die weiteren
Datenframes erwarte. Dieses könnte laut Protokoll folgenden Aufbau
haben:
1
CAN-ID LEN D0 D1 D2 D3 D4 D5 D6 D7
2
----------------------------------
3
736 8 03 30 10 0A 00 00 00 00
D0 = Länge der Nachricht
D1 = 0x30 = oberes Nibble (0b011) = Frametype FC, unteres Nibble
(0b0000) = Clear-to-send
D2 = Blocksize (anzahl der max. nacheinander zu sendenen
CF-Nutzdatenframes), hier habe ich einfach mal 0x10 genommen
D3 = Min separation time (mindestabstand zwischen zwei CF-Frames in
Millisekunden)
Schicke ich diese Antwort, passiert nichts weiter :-(
Dann habe ich mir das mal auf einem Log von einer anderen Software
angeschaut und da sehe ich nur diesen FC-Frame aufbau:
1
CAN-ID LEN D0 D1 D2 D3 D4 D5 D6 D7
2
----------------------------------
3
736 8 30 00 00 00 00 00 00 00
Und damit sendet das Modul die erwarteten CF-Frames.
Wie ist das zu erklären? Wo habe ich die Norm falsch interpretiert?
Du mischt UDS mit ISO-TP.
UDS macht das Frage-Antwort-Spiel logisch und ISO-TP regelt dann wie man
die Anfragen und Antworgen mit den Byte pro Botschaft bei CAN sauber
übermittelt.
Der FC-Frame geht nach ISO-TP Spec mit 0x30 los, keine Anzahl der
übermittelten Bytes davor. Dein Steuergerät erkennt mit 0x03 kei FC und
bricht ab.
Ok, also mit "ISO-TP" meinst Du "ISO 15765-2" ?
Das ist ja im Grund das Transportprotokoll ähnlich wie TCP, sprich zur
Segmentierung von Botschaften größer eines CAN-Frames.
In Wikipedia (https://de.wikipedia.org/wiki/ISO_15765-2) steht: "Die
typische Anwendung ist die Übertragung von Diagnosebotschaften aus
KWP2000 und UDS, ist aber nicht darauf beschränkt."
Ah, also ist in dem Moment wo ich eine UDS-Botschaft erhalte die
andeutet das nun ISO-TP Frames folgen, also ein First-Frame (FF)
übermittelt wird für den Tester (Client) klar das danach mit ISO-TP
gearbeitet wird weil nur eine einfache Datenübermittlung folgt und keine
UDS-Steuerinformationen, richtig?!
Weiterhin steht in Wikipedia zur Blocksize: "Moderne Steuergeräte
unterstützen auch Block Size 0 (= aus), d. h. es dürfen beliebig viele
aufeinander folgende Consecutive Frames von Sender gesendet werden."
Also ist die 0x00 an D1 des FC-Frames gleichbedeutend mit: "jetzt können
soviele CF-Frames folgend wie es braucht alles zu übermitteln". Für den
Client bedeutet das ja in erster Linie das er genügend Buffer zur
Verfügung stellen muss. Laut Norm hat jeder nun folgende CF-Frame im
ersten Byte einen 4-Bit Folgezähler im unteren Nibble, welcher bei
0b1111 einfach zu 0b0000 überläuft. Das ganze Spiel wiederholt sich dann
bis alle im UDS-FF-Frame genannten Bytes übertragen sind.
Der Client müsste nur dann ein erneutes FC senden, wenn ich anstelle
0x00 z.B. 0x10 einsetze, dann wäre nach 16 Paketen erstmal schluß, bis
wieder ein FC kommt.
0x30 00 00
FC BS Time
FC
Blocksize 0x00 = igno., sende bis Ende.
Time 0x00 = sende so schnell als möglich.
UDS zu Fuß ist etwa müßig - viel Glück :)
Sen. Diag. Expert
Lexa schrieb:> UDS zu Fuß ist etwa müßig - viel Glück :)> Sen. Diag. Expert
Ja, gebe ich Dir recht, aber das ist noch ein Lernprojekt für mich und
da finde ich es gut genau zu wissen was abgeht.
Später kann ich mir vorstellen das über APIs und fertige Bibliotheken zu
ersetzen...
Olli Z. schrieb:> Ok, also mit "ISO-TP" meinst Du "ISO 15765-2" ?> Das ist ja im Grund das Transportprotokoll ähnlich wie TCP, sprich zur> Segmentierung von Botschaften größer eines CAN-Frames.>> In Wikipedia (https://de.wikipedia.org/wiki/ISO_15765-2) steht: "Die> typische Anwendung ist die Übertragung von Diagnosebotschaften aus> KWP2000 und UDS, ist aber nicht darauf beschränkt.">> Ah, also ist in dem Moment wo ich eine UDS-Botschaft erhalte die> andeutet das nun ISO-TP Frames folgen, also ein First-Frame (FF)> übermittelt wird für den Tester (Client) klar das danach mit ISO-TP> gearbeitet wird weil nur eine einfache Datenübermittlung folgt und keine> UDS-Steuerinformationen, richtig?!
Der Tester weiß wie es genau läuft weil es in den Diagnosebeschreibungen
der Hersteller (odx/pdx) entsprechend drinsteht.
Für CAN ist UDS über ISO-TP hald der Standard. Die Tester trennen da in
ihrem Core gerne, high level UDS und drunter nochmal eine Schicht die
die Kommunikation auf den Bussystemen dann macht. Auf Flexray, LIN oder
Ethernet schaut UDS genauso aus, aber das Transportprotokoll kann anders
ausschauen.
Mann muss also UDS und ISO-TP getrennt voneinander betrachten damit das
alles einen Sinn ergibt. Alles was wirklich Diagnoseinformationen
enthält ist HighLevel nach UDS zu decodieren nachdem man die Bytefolge
aus dem ISO-TP zusammengepuzzelt und alle ISO-TP Steuerbytes entfernt
hat. Wirkliche Nutzbytes für UDS sind die ja nicht.
0x30 00 00 als FC-Frame ist heute normal, die Zeiten in denen die
Steuergeräte zu wenig Puffer oder CPU Power hatten um da was anders
machen zu müssen sind Gott sei Dank schon länger vorbei :-)
Der Tester muss soweit ich weiß alles ohne Pausen empfangen können.
Vielleicht zickt das Steuergerät deshalb.
Ansonsten bist du denke ich auf dem richtigen Weg.
Auch Karl, ein anderer schrieb:> Der Tester muss soweit ich weiß alles ohne Pausen empfangen können.> Vielleicht zickt das Steuergerät deshalb.> Ansonsten bist du denke ich auf dem richtigen Weg.
nein muss er nicht, aber er muss den FlowControl-Frame nach Empfang des
FirstFrames schicken sonst verstößt er gegen das ISO-TP Protokoll und
das Steuergerät bricht ab ( für UDS über ISO-TP auf CAN)
RCC schrieb:> Auch Karl, ein anderer schrieb:>> Der Tester muss soweit ich weiß alles ohne Pausen empfangen können.>> Vielleicht zickt das Steuergerät deshalb.>> Ansonsten bist du denke ich auf dem richtigen Weg.>> nein muss er nicht, aber er muss den FlowControl-Frame nach Empfang des> FirstFrames schicken sonst verstößt er gegen das ISO-TP Protokoll und> das Steuergerät bricht ab ( für UDS über ISO-TP auf CAN)
Ganz genau und das auch innerhalb einer kurzen Zeit, sonst erwartet der
Server dieses nicht mehr und bricht intern den Flow ab.
Du kannst mal zur Übung SID 22 und DID F189 abfragen, das ist die
SW-Version. Die ist üblicherweise nur 4 Byte und passt damit als
komplette UDS Antwort in eine CAN Botschaft.
Damit SingeFrame und kein Flow-Control und keine CF.
RCC schrieb:> Du kannst mal zur Übung SID 22 und DID F189 abfragen, das ist die> SW-Version. Die ist üblicherweise nur 4 Byte und passt damit als> komplette UDS Antwort in eine CAN Botschaft.> Damit SingeFrame und kein Flow-Control und keine CF.
Mag das PAM leider nicht, ich bekomme ein
73E 8 03 7F 22 31 00 00 00 00
zurück, also 7F = Fehler-SID, 22 = Ursprünglich angefragte SID, 31 = ???
Irgendeine Fehlerursache vermutlich...
Die ISO-Norm beschreibt in der SID 0x22 ja nur die Parameter
0xF180..0xF19F und die habe ich alle durchprobiert. Nur ein paar davon
geben eine Antwort und die ist überall Multiframe:
* F180 Multiframe
* F188 Multiframe
* F18C Multiframe
* F190 Multiframe
* F191 Multiframe
Interessant ist, das auch ausserhalb dieses Normbereichs liegende
Parameter eine Antwort geben, beispielsweise:
* F1A0 Multiframe
* F1A1 Multiframe
Ich schreibe mal ein Skript welches die Bruteforcemäßig mal alle
durchackert und bei jedem Rückgabewert != 0x7F in D1 ausspuckt, da
scheint es wohl einiges Vendorspezifische zu geben :-)
RCC schrieb:> Du kannst mal zur Übung SID 22 und DID F189 abfragen, das ist die> SW-Version. Die ist üblicherweise nur 4 Byte und passt damit als> komplette UDS Antwort in eine CAN Botschaft.> Damit SingeFrame und kein Flow-Control und keine CF.
Viele UDS Botschaften haben nur einen Frame. Für den Anfang würde ich
auch mal ne komplette Diagnose Sitzung mit Fehler lesen und löschen und
zumindest einem Messwert aufzeichnen, die Kommunikation lässt sich unter
ISO-TP noch recht schön betrachten, als Lektüre kann ich dir das Buch
„Bussysteme in der Fahrzeugtechnik“ von W. Zimmermann und R. Schmidgall
empfehlen, dort ist das ISO TP recht schön beschrieben. Eine reine von
mir vorgeschlagene Diagnosesitzung unter UDS könnte zum Beispiel so
ähnlich aussehen*:
Diagnostic Session Control 10
Positive Response 50
Read DTC 19
Positive Response 59
Clear DTC 14
Positive Response 54
Read Data by Identifier 22
Positive Response 62
*3E Tester Present um die Diagnosesitzung aufrecht zu erhalten habe ich
ausgelassen.
Natürlich ist es schön wenn du Zugriff auf die Normen hast, mit
entsprechender Lektüre und realen Beispielen aus Aufzeichnungen ist die
Lernkurve allerdings deutlich steiler.
Ich kann Freitag mal den Rechner anschmeissen und einen Trace posten,
dauert bloß etwas weil ich überwiegend KWP2000 auf K-Line gemacht habe,
muss daher etwas suchen, KWP2000 und UDS auf CAN habe ich aber auch
gemacht, auch wenn nicht so häufig. KWP2000 auf CAN (ISO-TP) könnte aber
als Beispiel für ISO-TP sogar besser als UDS sein weil häufiger
Botschaften verwendet werden die zu groß für einen einzelnen CAN Frame
sind. Bei KWP2000 enthält eine Botschaft häufig mehrere Messwerte an
unterschiedlichen Byte Positionen. KWP2000 ist trotzdem relativ ähnlich
zu UDS.
René F. schrieb:> ead DTC 19> Positive Response 59>> Read Data by Identifier 22> Positive Response 62
Wenn Du so anfragst kommt beides mal ein 7F zurück weil die Anfragen so
nach Norm nicht vollständig sind.
Beim SID 19 fehlt DTC Mask und was er genau ausgeben soll, beim SID 22
der DID.
Tester Present brauchtst Du nur wenn du aus der Default Session in eine
andere wechselst damit das Steuergerät da auch drin bleibt. Was in
welcher Session geht ist herstellerspezifisch
Du könntest die DID 0xF163 ausprobieren, das ist bei Ford wohl
"Diagnostic Specification Version" und sollte nur ein Byte lang sein
(bei der PAM vermutlich 0x03, da ich kein PAM habe kann ich es nicht
ausprobieren).
Für UDS über ISO-TP gibt es aber eine Menge Source Code wo man sich
ansehen kann wie das genau abläuft (ISO-TP ist jetzt auch nicht so
kompliziert).
RCC schrieb:> Wenn Du so anfragst kommt beides mal ein 7F zurück weil die Anfragen so> nach Norm nicht vollständig sind.> Beim SID 19 fehlt DTC Mask und was er genau ausgeben soll, beim SID 22> der DID.
Korrekt, ich habe nur die Service IDs angegeben weil abgesehen von OBD
nichts genormt ist und ich jetzt kein Beispiel nennen wollte welches mit
hoher Wahrscheinlichkeit nicht funktioniert hätte. Ich wollte damit das
Frage-Antwort-Spiel von UDS demonstrieren, und dabei einmal das
Transportprotokoll ausblenden.
RCC schrieb:> Tester Present brauchtst Du nur wenn du aus der Default Session in eine> andere wechselst damit das Steuergerät da auch drin bleibt. Was in> welcher Session geht ist herstellerspezifisch
Ja, wenn der TO aber versucht eine Diagnose Kommunikation zu erzeugen
sollte er sich sicher sein das die Funktion in der Diagnosesitzung
unterstützt wird und dies kann er in dem er mit der gleichen Session
arbeitet wie der Hersteller. Damit aber nicht plötzlich nach kurzer
Pause aufeinmal eine NegResponse kommt weil das Steuergerät in die
Default Session wechselt wo die Funktion nicht unterstützt wird sollte
er versuchen die Session mittels Tester Present aufrecht zu erhalten.
Das ist alles "manuell" erzeugt, der Flow-Control Frame wurde über den
vorausgehenden Frame getriggert. Bei der PAM sollte das genauso
funktionieren (mit entsprechend angepassten CAN IDs).
Dieter schrieb:> Du könntest die DID 0xF163 ausprobieren, das ist bei Ford wohl> "Diagnostic Specification Version" und sollte nur ein Byte lang sein> (bei der PAM vermutlich 0x03, da ich kein PAM habe kann ich es nicht> ausprobieren).
Es ist 0x02 :-)
73E 8 04 62 F1 63 02 00 00 00
> Für UDS über ISO-TP gibt es aber eine Menge Source Code wo man sich> ansehen kann wie das genau abläuft (ISO-TP ist jetzt auch nicht so> kompliziert).
Ja, da sehe ich fast den Wald vor lauter Bäumen nicht...
Olli Z. schrieb:> RCC schrieb:>> Du kannst mal zur Übung SID 22 und DID F189 abfragen, das ist die>> SW-Version. Die ist üblicherweise nur 4 Byte und passt damit als>> komplette UDS Antwort in eine CAN Botschaft.>> Damit SingeFrame und kein Flow-Control und keine CF.>> Mag das PAM leider nicht,
DID F1 86 "ReadActiveDiagnosticSession" vielleicht?
Den hab' ich bisher fast überall gesehen. Sollte auch in jeder Session
gehen...
mfg mf
Ich habe mir jetzt mal dieses Buch vom Zimmermann gekauft, in der
aktuellen Auflage. War als E-Book mit knapp 30€ durchaus erschwinglich.
Es stehen da jetzt bislang keine wirklichen Geheimnisse drin, aber es
ist ganz gut zu lesen...