This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F280039C: CAN message data bytes interpretation to uint16_t looks confusing

Part Number: TMS320F280039C

Hi folks. I have a question regarding to the CAN message data, more specifically, how the 8-byte message data gets interpreted into different types.

I am using standard CAN message, which has 8 bytes for the data field.

I defined the rxMsgBuf as follows:

union RxMsgBuf {
    uint16_t rxMsgDataInt[4];
    unsigned char rxMsgData[8];
    uint64_t rxWhole;
}rxMsgBuf;

Using union here for myself to better understand how the data bytes being accessed.  My understanding is, this union takes 8 bytes in total, and can be interpreted as

 -- 4 16bit-integers (uint16_t rxMsgDataInt[4]), or

-- 8 1-byte character (unsigned char rxMsgData[8), or

-- a long 64-bit long int (uint64_t rxWhole), depending on how my application treats the data sent.

The message received will be transferred into this rxMsgBuf in interrupt, by

CAN_readMessage(CANA_BASE, MSG_OBJ_ID_RECEIVE, &rxMsgBuf);

And after that I set up the CAN receive object, and sent standard format data from external (a linux host), e.g.  cansend 156#01.AF.00.20.00.00.00.F2.

By watching the varible of the rxMsgBuf, here's what I got

The values shown in rxMsgData (unsigned char, or 0 - 255 if look as numbers) and the rxWhole (uint64_t) seems reasonable to me.

But I don't understand why the rxMsgDataInt has 4 entries which is same as the first 4 of the rxMsgData. I was expecting it interprets each 2 bytes together, and get 4 integers from the 8 bytes data, which should be different values compared to the way rxMsgData interprets. Their address in memory also make me confused since it looks like the address gap among the array members of uint16_t rxMsgDataInt[4] is the same as that of unsinged char rxMsgData[8] (increment is 1 for both cases).

Could you share you advice that what I missed? Thanks.

Regards,

Wei

  • Hi Wei,

    I think the issue here is that unsigned char may actually be 16-bits on C28x core. Can you try using uint8_t instead of unsigned char?

    C28x has a minimum memory size of 16-bit, because it's 16-bit addressable unlike ARM which is 8-bit addressable.

    Regards,

    Vince

  • Hi Vince,

    Thanks for the reply. I tried with uint8_t, which now the rxMsgBuf definition is:

    union RxMsgBuf {
        uint16_t rxMsgDataInt[4];
        uint8_t rxMsgData[8];
        uint64_t rxWhole;
    }rxMsgBuf;

    And keeping everything else same above. After the transmittion of CAN message data 01.AF.00.20.00.00.00.F2

    Below is what it looks like now

    Again, the uint16_t array's entries shows same value as the first 4 elements of uint8_t array. And their 'Type' both shows as 'unsigned_int'. The address of the corresponding entries of the 2 array are also the same. This leads me to the assumption / understanding:

    1. internally, the uint16_t and uint8_t are actually same type which is "unsigned int"

    2. According to your comments, since C28x is 16-bit system, so the "unsignd int" takes 16 bits, that is why when looking at the address of the entries of the uint16_t and uint8_t array, they both simply increment each by 1 i.e. 16 bits.

    Please let me know whether my assumptions or understanding are correct.

      

  • 1. internally, the uint16_t and uint8_t are actually same type which is "unsigned int"

    Correct.

    . According to your comments, since C28x is 16-bit system, so the "unsignd int" takes 16 bits, that is why when looking at the address of the entries of the uint16_t and uint8_t array, they both simply increment each by 1 i.e. 16 bits.

    Correct again.

    The only benefit to using "uint8_t" type (in my view) is to convey to a code reviewer that you only intend to use only the lower 8 bits of the possible 16 bits. It has no effect on the program compilation itself.