Feature #27
closedcanbus-binding: add support for per-signal endianness (was: Little endian encoded uint16 are not properly decoded by canbus-binding)
0%
Description
Canplayer was used to send message 0x601 = 0x010203 to canbus-binding (can0 601 [3] 01 02 03).
Here's the definition of message 0x601 (3 bytes in total, 1 uint8 followed by a uint16):
"0x601": {
"name": "EMOJY.SysInfo.ConvertersDC",
"bus": "hs",
"length": 3,
"is_fd": false,
"is_j1939": false,
"is_extended": false,
"byte_frame_is_big_endian": false,
"bit_position_reversed": false,
"signals": {
"idConvertersDC": {
"name": "EMOJY.SysInfo.ConvertersDC.idConvertersDC",
"bit_position": 0,
"bit_size": 8,
"factor": 1,
"offset": 1,
"writable": false,
"unit": "N/A",
"min_value": 1,
"max_value": 2
},
"softwareVersion": {
"name": "EMOJY.SysInfo.ConvertersDC.softwareVersion",
"bit_position": 8,
"bit_size": 16,
"factor": 1,
"offset": 0,
"writable": false,
"unit": "N/A",
"min_value": 0,
"max_value": 65535
}
}
}
The expected values are:
- for EMOJY.SysInfo.ConvertersDC.idConvertersDC: 2, because the value sent is 0x01, the factor is 1 and the offset is 1.
- for EMOJY.SysInfo.ConvertersDC.softwareVersion: 770, because the value sent is 0x0203 in little endian, the factor is 1 and the offset 0.
Here're canbus-binding logs:
<sup>[[95mDEBUG<sup>[[0m:</sup></sup> <sup>[[1m[API</sup> canbus]<sup>[[0m</sup> Data available: 16 bytes read. BCM head, opcode: 12, can_id: 1537, nframes: 1
<sup>[[95mDEBUG<sup>[[0m:</sup></sup> <sup>[[1m[API</sup> canbus]<sup>[[0m</sup> Got a legacy CAN frame
<sup>[[95mDEBUG<sup>[[0m:</sup></sup> <sup>[[1m[API</sup> canbus]<sup>[[0m</sup> Found id: 601, format: 0, length: 3, data 0102030000000000
<sup>[[95mDEBUG<sup>[[0m:</sup></sup> <sup>[[1m[API</sup> canbus]<sup>[[0m</sup> Here is the next can message : id 1537 length 3, data 12300000
<sup>[[95mDEBUG<sup>[[0m:</sup></sup> <sup>[[1m[API</sup> canbus]<sup>[[0m</sup> Decoded message from parse_signal_bitfield: 515.000000
<sup>[[95mDEBUG<sup>[[0m:</sup></sup> <sup>[[1m[API</sup> canbus]<sup>[[0m</sup> Emojy_v1.5/ CAN signals processed.
EMOJY.SysInfo.ConvertersDC.softwareVersion is decoded as 515 (0x0203) instead of 770 (0x0302).
<sup>[[95mDEBUG<sup>[[0m:</sup></sup> <sup>[[1m[API</sup> canbus]<sup>[[0m</sup> Here is the next can message : id 1537 length 3, data 12300000
<sup>[[95mDEBUG<sup>[[0m:</sup></sup> <sup>[[1m[API</sup> canbus]<sup>[[0m</sup> Decoded message from parse_signal_bitfield: 2.000000
<sup>[[95mDEBUG<sup>[[0m:</sup></sup> <sup>[[1m[API</sup> canbus]<sup>[[0m</sup> Emojy_v1.5/EMOJY.SysInfo.ConvertersDC.idConvertersDC CAN signals processed.
EMOJY.SysInfo.ConvertersDC.idConvertersDC is decoded as 2 as expected.
Updated by Stephane Desneux [IoT.bzh] over 2 years ago
- Assignee changed from Vincent Rubiolo to Stephane Desneux [IoT.bzh]
Updated by Stephane Desneux [IoT.bzh] over 2 years ago
After reading the code, I found a solution :)
In fact, the multibyte integers are always decoded in big endian mode (whatever the runtime platform is) and there may be a misunderstanding on what byte_frame_is_big_endian
means and involves in the code.
If byte_frame_is_big_endian
is true, the bytes of the full frame are simply reversed before decoding the signals. Maybe we should rename this field to 'byte_position_reversed' to remove any ambiguity. IMO, endianness should be a signal field, not a message field.
Anyway: a solution to solve the problem is to reverse the frame then change the start positions of the decoded fields.
RAW frame data: 0x0102030000000000
after revert: 0x0000000000030201
as bytes: 00 00 00 00 00 03 02 01
positions: 0 8 16 24 32 40 48 56
so idConvertersDC is the last byte (position 56) and softwareVersionDC is on bytes 6 and 7 (16 bits starting at position 40). When decoded in big endian mode, this should provide the expected result.
This leads to the following config:
"0x601": {
"name": "EMOJY.SysInfo.ConvertersDC",
"bus": "hs",
"length": 3,
"is_fd": false,
"is_j1939": false,
"is_extended": false,
"byte_frame_is_big_endian": true,
"bit_position_reversed": false,
"signals": {
"idConvertersDC": {
"name": "EMOJY.SysInfo.ConvertersDC.idConvertersDC",
"bit_position": 56,
"bit_size": 8,
"factor": 1,
"offset": 1,
"writable": false,
"unit": "N/A",
"min_value": 1,
"max_value": 2
},
"softwareVersion": {
"name": "EMOJY.SysInfo.ConvertersDC.softwareVersion",
"bit_position": 40,
"bit_size": 16,
"factor": 1,
"offset": 0,
"writable": false,
"unit": "N/A",
"min_value": 0,
"max_value": 65535
}
}
}
Of course, if multiple integers with different endianness are located in the same message, this solution wouldn't work. The only solution in this case is to use a custom decoding function.
@Emmanuel Jubera [SAFT] , can you test the previous config and confirm if it works for you?
Updated by Emmanuel Jubera [SAFT] over 2 years ago
Thx Stéphane, I have no doubt your workaround would work but unfortunately we would need to change the bit positions in the dbc and we can't. The dbc is a cross-team specification we receive from other people and little endianess is allowed so we have to cope with it. I'm going to check if we can have big endian encoding for multi-bytes integers, that would solve the problem I guess...
I agree endianess should be managed on a per signal basis and I think it is mandatory to have both endianess supported by canbus-binding on a per signal basis as this is what the CAN spec allows.
Updated by Stephane Desneux [IoT.bzh] over 2 years ago
- Status changed from New to In Progress
Updated by Stephane Desneux [IoT.bzh] over 2 years ago
- Tracker changed from Bug to Feature
- Subject changed from Little endian encoded uint16 are not properly decoded by canbus-binding to canbus-binding: add support for per-signal endianness (was: Little endian encoded uint16 are not properly decoded by canbus-binding)
Updated by Stephane Desneux [IoT.bzh] over 2 years ago
- Assignee changed from Stephane Desneux [IoT.bzh] to Salma RAISS
Updated by Sebastien Douheret [IoT.bzh] about 2 years ago
- Assignee changed from Salma RAISS to José Bollo
Updated by José Bollo about 2 years ago
- Status changed from In Progress to Resolved
Updated by Sebastien Douheret [IoT.bzh] about 2 years ago
- OS Affects Version/s arz-1.0.0 added
Updated by Sebastien Douheret [IoT.bzh] almost 2 years ago
- Target version changed from arz-1.0-update to arz-1.0.1
- OS Affects Version/s arz-1.0 added
- OS Affects Version/s deleted (
arz-1.0.0) - OS Fix Version/s arz-1.0.1 added
Updated by Sebastien Douheret [IoT.bzh] almost 2 years ago
- Status changed from Resolved to Closed