Project

General

Profile

Actions

Feature #27

closed

canbus-binding: add support for per-signal endianness (was: Little endian encoded uint16 are not properly decoded by canbus-binding)

Added by Emmanuel Jubera [SAFT] over 2 years ago. Updated almost 2 years ago.

Status:
Closed
Priority:
High
Assignee:
Target version:
Start date:
08/16/2022
Due date:
% Done:

0%

Estimated time:
Hardware platform:
Desktop SDK (openSUSE Leap 15.3)
OS Affects Version/s:
arz-1.0
OS Fix Version/s:
arz-1.0.1
Labels:

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.

Actions #1

Updated by Stephane Desneux [IoT.bzh] over 2 years ago

  • Assignee changed from Vincent Rubiolo to Stephane Desneux [IoT.bzh]
Actions #2

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?

Actions #3

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.

Actions #4

Updated by Stephane Desneux [IoT.bzh] over 2 years ago

  • Status changed from New to In Progress
Actions #5

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)
Actions #6

Updated by Stephane Desneux [IoT.bzh] over 2 years ago

  • Assignee changed from Stephane Desneux [IoT.bzh] to Salma RAISS
Actions #7

Updated by Sebastien Douheret [IoT.bzh] about 2 years ago

  • Assignee changed from Salma RAISS to José Bollo
Actions #8

Updated by José Bollo about 2 years ago

  • Status changed from In Progress to Resolved
Actions #9

Updated by Sebastien Douheret [IoT.bzh] about 2 years ago

  • OS Affects Version/s arz-1.0.0 added
Actions #10

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
Actions #11

Updated by Sebastien Douheret [IoT.bzh] almost 2 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF