From 21cacf8c5455810fd98222bb22ae1bbe9dc6a1e4 Mon Sep 17 00:00:00 2001 From: rusefillc Date: Wed, 6 Nov 2024 21:54:49 -0500 Subject: [PATCH] Overview Motorola vs. Intel-Format in Can-Frame Some explanations of CAN byte order and bit numbering: openxcplatform-bitnumbering Mathworks-Side CAN frame data is either in big endian or little endian byte format. The bits are numbered by the file format either using MSB first (MSB0) or LSB first (LSB0). With "consistent" format/numbering, bit numbering follows the byte format. MSB0 for big endian, LSB0 for little endian. ietf-endianess Usually the start bit referenced by the file formats reference the start of the signal data within the message independent of the endianess of the signal. With some formats (DBF), the startbit may always reference the LSB of the signal data. Common formats: KCD, SYM (consistent bit numbering) little,LSB0 big,MSB0 DBC, ARXML (OSEK bit numbering) little,LSB0 big,LSB0 (inconsistent) DBF (startBit=LSB, startByte and startBit specified separately) little,LSB0 big,LSB0,startBit=LSB (inconsistent) Legacy canmatrix (yaml, json) (Note: internally canmatrix now uses consistent bit numbering) little,LSB0 big,LSB0,startBit=LSB (inconsistent) ###First Example: Frame with two 32-bit signals in motorola one can-frame 7 6 5 4 3 2 1 0 0>msb----- 1 signal1 2 3 ----lsb> 4>msb----- 5 signal2 6 7 ----lsb> DBC: BO_ 291 newFrameMotorola: 8 Vector__XXX SG_ signal1 : 7|32@0- (1,0) [0|0] "" Vector__XXX (most significant bit) SG_ signal2 : 39|32@0- (1,0) [0|0] "" Vector__XXX (most significant bit) candb++ views: signal1: 24 (least significant bit?) signal2: 56 (least significant bit?) Dbf: byte 4 bit 0 byte 8 bit 0 ###Second Example: 7 6 5 4 3 2 1 0 0 >msb--- 1---------lsb> 2 3 4 5 6 7 DBC: startbit 3 length 11 candb++ views: Startbit 9 (least significant bit?) dbf: length 11 byte 2 (counting starts with byte 1) bit 1 ##found docs about kcd "Least significant bit offset of the signal relative to the least significant bit of the messages data payload." least significant bit? estimation about dbf least significant bit? new formulars from dmahurin Note the basic operations used. convert from lsb0 bit numbering to msb0 bit numbering (or msb0 to lsb0) b = b - (b % 8) + 7 - (b % 8) convert from lsbit of signal data to msbit of signal data, when bit numbering is msb0 b = b + 1 - length convert from msbit of signal data to lsbit of signal data, when bit numbering is msb0 b = b + length - 1 So conversion from msbit in lsb0 bit numbering to msbit in lsb0 bit numbering is: b = b - (b % 8) + 7 - (b % 8) b = b + length - 1 b = b - (b % 8) + 7 - (b % 8) byte order names little endian == Intel == MOST-SIGNIFICANT-BYTE-LAST big endian == Motorola == MOST-SIGNIFICANT-BYTE-FIRST --- .../com/rusefi/can/reader/dbc/DbcFile.java | 2 +- .../rusefi/can/reader/dbc/DbcFieldTest.java | 28 +++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/reader/src/main/java/com/rusefi/can/reader/dbc/DbcFile.java b/reader/src/main/java/com/rusefi/can/reader/dbc/DbcFile.java index bbae7e7..9c59162 100644 --- a/reader/src/main/java/com/rusefi/can/reader/dbc/DbcFile.java +++ b/reader/src/main/java/com/rusefi/can/reader/dbc/DbcFile.java @@ -13,7 +13,7 @@ public class DbcFile { public final LinkedHashMap packets = new LinkedHashMap<>(); public static final boolean debugEnabled = false; - public static boolean applyOrderForStartOffset; + public static boolean applyOrderForStartOffset = true; private List list; diff --git a/reader/src/test/java/com/rusefi/can/reader/dbc/DbcFieldTest.java b/reader/src/test/java/com/rusefi/can/reader/dbc/DbcFieldTest.java index 47c6fea..5ca9d6d 100644 --- a/reader/src/test/java/com/rusefi/can/reader/dbc/DbcFieldTest.java +++ b/reader/src/test/java/com/rusefi/can/reader/dbc/DbcFieldTest.java @@ -2,22 +2,38 @@ package com.rusefi.can.reader.dbc; import org.junit.Test; +import static com.rusefi.can.reader.dbc.DbcFile.applyOrderForStartOffset; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class DbcFieldTest { @Test public void testBigEndian() { - DbcField field = new DbcField("", 8, 16, 1, 0, null, true); - assertTrue(field.coversByte(0)); - assertTrue(field.coversByte(1)); - assertFalse(field.coversByte(2)); - assertFalse(field.coversByte(3)); + { + applyOrderForStartOffset = true; + DbcField field = create(true); + assertFalse(field.coversByte(1)); + assertFalse(field.coversByte(2)); + assertTrue(field.coversByte(3)); + assertFalse(field.coversByte(0)); + } + { + applyOrderForStartOffset = false; + DbcField field = create(true); + assertTrue(field.coversByte(0)); + assertTrue(field.coversByte(1)); + assertFalse(field.coversByte(3)); + } + applyOrderForStartOffset = true; + } + + private static DbcField create(boolean isBigEndian) { + return new DbcField("", 8, 16, 1, 0, null, isBigEndian); } @Test public void testLittleEndian() { - DbcField field = new DbcField("", 8, 16, 1, 0, null, false); + DbcField field = create(false); assertFalse(field.coversByte(0)); assertTrue(field.coversByte(1)); assertTrue(field.coversByte(2));