Hallo zusammen,
falls im falschen Forum gepostet, bitte verschieben.
es geht um eine aus 8 Bytes (Byte 0 bis 7) bestehende CAN Botschaft des
Datenbereich.
In einer Auswerteinheit muss neben der CAN-ID das Startbit, die Länge
und die Byte-Order (Intel oder Motorola) engegeben werden.
Es soll nun Byte 2 mit einer Länge von 16 Bit ausgewertet werden,
demnach belegt die Datenbotschaft zwei Bytes = 16 Bit Länge.
Meiner Meinung nach wäre
- bei Motorola (Big Endian) das Startbit (beginnend mit 0) das Bit Nr.
16
- bei Intel (little Endian) das Startbit (beginnend mit 0) das Bit Nr.
23
Liege ich richtig?
lg Frank
Du musst bei der Auswerte-Einheit konfigurieren, wo das Startbit ist?
Schaue in deren Dokumentation, wie sie diese Angabe interpretiert.
Wahrscheinlich ist beides mal Bit 0 das Startbit, weil eben die Bits ab
Position 0 ausgewertet werden, wenn auch in unterschiedlicher
Reihenfolge.
Aber Achtung, falls du mit Vector DBC-Dateien arbeitest - hier ist das
Startbit immer die Position des niederwertigsten Bits, und die ist bei
Big Endian mitten in den Daten, 8 Bits vor Ende... Das ist unüblich und
verwirrend und selbst der Vector-eigene CANdb++ Editor bekommt das nicht
richtig hin.
Wie die Datenbytes zugegriffen werden, steht im Manual des jeweiligen
CAN-Controllers. Sie sind in der Regel nicht als Word zugreifbar und
auch nicht bitweise.
Oft ist das Datenregister auch mit Autoincrement zugreifbar, d.h.
nacheinander werden von der selben Adresse Byte 0..7 gelesen.
Über die Interpretation des Startbits schweigt sich die Doku leider aus,
es kann 0 bis 63 angegeben werden und ja, Du hast den Finger drauf, es
handelt sich um einen Datensatz aus einer Vector DB, welche mal die
Bytes von 1 bis 8 und mal von 0 bis 7 benennt. Ähnlich bei den Bits.
Hier ist eben aufgefallen, dass der gelesene Wert abnormal springt, weil
es hätte heißen müssen Byte 1 und nicht Byte 2.
Also würde Big Endian (Motorola) dann Byte 0 und 1 wie folgt zählen:
7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8
dagegen Intel:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Zeig doch mal einen Ausschnitt aus der Doku, die Konfiguration und einen
Screenshot aus CANdb++ der fraglichen Signale... Man vertut sich bei
sowas zu schnell als dass man das vernünftig in Textform wiedergeben
könnte.
Ich durfte leider nur einen Blick in die DB werfen, da die offiziell
nicht existiert und habe mir die ID, das Byte, die Länge und dass es
Motorola / Big Endian ist herausgeschrieben, ebenfalls Offset und
Scalierung zu PHYS Wert.
Im datenstrom selbst ist mir dann aufgefallen, dass Byte 2 den Wert 0x00
hat und Byte 3 0xF0. Das kann aber nicht sein, denn dieses byte müßte
auch für diesen Zustand 0x00 sein, also beide Bytes zusammen 0 ergeben.
Das Byte 1 ist aber 0x00, darum habe ich das Startbit um 8 Stellen
verringert und siehe da, es geht, die Wert stimmen.
Jetzt hat mich persönlich interessiert, wie ich selbst für einen
Datenpunkt das Startbit errechnen kann. z.B. folgende CAN Datenbytes mit
der Konvention das Bits und Bytes von 0 an gezählt werden:
12 34 1F 00 00 34 76 22
Ich weiß, dass die die beiden Bytes 00 00 einen Wert beinhalten, der 16
Bit belegt, nämlich genau über diese zwei Bytes 3 und 4 geht.
In dem Auswerte Programm gebe ich als Länge 16 Bit ein.
Wenn nun die Byteorder bekannt ist, wie errechne ich dann das Startbit?
Frank K. schrieb:> Wenn nun die Byteorder bekannt ist, wie errechne ich dann das Startbit?
Hängt halt von der Konvention ab... In den meisten Fällen ist das
Startbit komplett unabhängig von der Byte-Reihenfolge immer das 0. Bit
welches verarbeitet wird, egal welchen Wert man ihm beimisst. Das wäre
hier dann immer 24, denn die Bytes 12 34 1F belegen 24 Bits, also ist
das Bit danach das 24. ... Welches der beiden 0-Bytes jetzt die
höherwertigen Bits enthält ist dabei unerheblich. Dies ist
wahrscheinlich bei deinem Gerät das, was du angeben musst.
Nur in den DBC-Dateien ist das so seltsam gemacht: Was dort
fälschlicherweise "Startbit" genannt wird ist gar nicht das Startbit,
sondern das niederwertigste Bit, also das Bit welches die 1er enthält.
Das ist bei Big Endian hier 32, bei Little Endian 24. Das lässt sich so
umrechnen:
Big Endian:
Niederwertigstes Bit = Startbit + Anzahl Bits - 8
Little Endian
Niederwertigstes Bit = Startbit
Die ganze Logik funktioniert natürlich nur, wenn man von ganzen Bytes
redet, und das Signal nicht 12 Bits oder so ist.
Beim Auslesen eines CAN-Objekts muß man auch immer die Länge beachten.
Wenn die Länge 3 ist, dann darf man auch nur 3 Bytes auslesen. Liest man
aber 8 Bytes aus, dann stammen eben die überzähligen 5 Bytes noch von
einer älteren Nachricht und das ergibt Unsinn.
Was nun die 0..8 Datenbytes im einzelnen bedeuten, legt das
übergeordnete Protokoll fest und nicht Motorola oder Intel. Da sich
einfach irgendne Order auszudenken, bis es passen könnte, ist er falsche
Ansatz. Man muß die Protokollbeschreibung lesen.
Peter D. schrieb:> Beim Auslesen eines CAN-Objekts muß man auch immer die Länge beachten.> Wenn die Länge 3 ist, dann darf man auch nur 3 Bytes auslesen. Liest man> aber 8 Bytes aus, dann stammen eben die überzähligen 5 Bytes noch von> einer älteren Nachricht und das ergibt Unsinn.>> Was nun die 0..8 Datenbytes im einzelnen bedeuten, legt das> übergeordnete Protokoll fest und nicht Motorola oder Intel.
Du hast noch nicht viel mit Automotive CAN gemacht, oder? Da gibt's für
den überwiegenden Teil der Botschaften kein übergeordnetes Protokoll,
sondern eine so genannte Datenbasis. Das ist eine Datei, in der für jede
Botschaft exakt drin steht, wo welcher Wert steht (und das ist fix - er
steht immer exakt in dieser Botschaft, exakt an dieser Stelle). Also so
in der Art: Temperatur ist in Botschaft 0x123 ab Bit-Position 14 und ist
11 Bits groß. Dazu wird auch eine Byteorder angegeben für Signale, die
sich über mehr als ein Byte der Botschaft erstrecken. Diese Byteordern
werden mit "Intel" und "Motorola" bezeichnet. Um also die Temperatur da
wieder rauszuextrahieren, muss man wissen, welche Bits da nun
dazugehören, und das hängt auch davon ab, ob Intel- oder
Motorola-Byteoder.
> Da sich einfach irgendne Order auszudenken, bis es passen könnte, ist er> falsche Ansatz. Man muß die Protokollbeschreibung lesen.
Das wäre in dem Fall:
Frank K. schrieb:> Ich durfte leider nur einen Blick in die DB werfen, da die offiziell> nicht existiert und habe mir die ID, das Byte, die Länge und dass es> Motorola / Big Endian ist herausgeschrieben, ebenfalls Offset und> Scalierung zu PHYS Wert.
Doch, ich mache sehr viel mit Automtive CAN, sogar mit KBA und ECE
Zulassung. Ist aber ein anderer Bereich, da es hier nicht um Automative
geht. CAN Bus ist aber CAN Bus und entsprechend spezifiziert.
Der Fall wurde im ersten Post dargestellt.
Das was Du geschrieben hast ist auch völlig klar.
Das Problem war, dass es nur die Info gab: Botschaft 0x123, DLC 8, Byte
zwei mit 16 Bit Länge, Motorola.
Was mich beschäftigte: Wie berechnet man das Startbit bei Motorola und
was wenn es Intel wäre?
Die Antwort hat Niclas G. gegeben:
Big Endian (Motorola)
Niederwertigstes Bit = Startbit + Anzahl Bits - 8
Little Endian (Intel)
Niederwertigstes Bit = Startbit
Was von beiden funktioniert, kann man durch zwei Versuche "probieren".
Hier kam aber erschwerend hinzu, dass die Angabe Byte 2 falsch war, da
man von Byte 1 bis 8 gezählt hat, demnach war Byte 1 richtig, wenn man
von 0 bis 7 zählt, was die Auswert Sofware auch macht.
lg Frank
Frank K. schrieb:> Doch, ich mache sehr viel mit Automtive CAN,
Meine Aussagen gingen nicht an dich, sondern an Peter.
Frank K. schrieb:> Das Problem war, dass es nur die Info gab: Botschaft 0x123, DLC 8, Byte> zwei mit 16 Bit Länge, Motorola.>> Was mich beschäftigte: Wie berechnet man das Startbit bei Motorola und> was wenn es Intel wäre?
Wenn du CANalyzer oder CANoe hast, ist da der CANdb++-Editor dabei. Geht
angeblich auch mit der Demo-Version. Da kannst du dir ein Signal
basteln, das diesen Werten entspricht und dir dann die Belegung der
Bytes ansehen.
Rolf M. schrieb:> Du hast noch nicht viel mit Automotive CAN gemacht
Stimmt. Aber warum kann man es nicht eindeutig und klar definieren.
Man kann doch ganz einfach sagen, z.B. Datenbyte 0 ist das LSB und
Datenbyte 1 das MSB des 16Bit Wertes. Warum muß man alles immer maximal
umständlich definieren?
Bei Intel und Motorola müßte ich erst nachschlagen, was damit gemeint
sein könnte. Protokolle sollten immer Architektur unabhängig sein, z.B.
Network Byte Order.
Wir sind bei unserem CAN-Protokoll dazu übergegangen, alles als String
zu übertragen. Das macht es maximal einfach zu debuggen und minimal
mißverständlich.
Peter D. schrieb:> Rolf M. schrieb:>> Du hast noch nicht viel mit Automotive CAN gemacht>> Stimmt. Aber warum kann man es nicht eindeutig und klar definieren.> Man kann doch ganz einfach sagen, z.B. Datenbyte 0 ist das LSB und> Datenbyte 1 das MSB des 16Bit Wertes.
Es kann nicht nur Vielfache von 8 geben. Im Prinzip kann der Wert an
beliebiger Stelle anfangen und beliebig lang sein.
> Warum muß man alles immer maximal umständlich definieren?
Weil es hier darum geht, dass die Botschaften auch von sehr kleinen µCs
gelesen werden, und das ggf. in großer Anzahl und Häufigkeit. Man will
es daher dort möglichst effizient haben und jede Umrechnung einsparen.
Das mag heute nicht mehr ganz so wichtig sein, aber zu Anfangszeiten des
CAN musste man sehr sparsam sein.
> Wir sind bei unserem CAN-Protokoll dazu übergegangen, alles als String> zu übertragen. Das macht es maximal einfach zu debuggen und minimal> mißverständlich.
Das wäre im Automotive-Bereich viel zu viel Overhead, sowohl im Bezug
auf die Datenmenge, als auch im Bezug auf den Code zum Auswerten der
Daten.
Peter D. schrieb:> Bei Intel und Motorola müßte ich erst nachschlagen, was damit gemeint> sein könnte.
... wer das nachschlagen muß, hat entweder keine Ahnung von
Computertechnik oder ist beneidenswert jung (und in dem Fall entlastet)
;)
Mit µSer ( https://github.com/Erlkoenig90/uSer ) kann man solche
CAN-Nachrichten portabel en/de-kodieren; um z.B. zwischen Big Endian und
Little Endian umzuschalten muss man nur das "BE" durch "LE" tauschen.
Die Definition des structs könnte man sich automatisch aus einer
DBC-Datei generieren lassen. So ist das leicht anpassbar ohne dass man
den Code ändern müsste.