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.

How to lookup in numbered list

Hello All,

In this instance related to CANbus messages, but fundamentally a general C question:

I have only few discrete CAN messages to send/receive, so would like to preset the messageID during init, and send/receive messages based on calling the MBOX number (0..31). How to construct this in a proper-coding way?

I prefer to use 'send message(CAN_ID 0x321)' and not 'send message(MBOX 2)'  (and need to check a separate list that links the CANSID to MBOXnumber, with possibility of error).

This has a bit of a table-lookup feel to it, but I don't want to waste cycles and/or memory. So I am trying to find a compile time method. Enum list is a quick option to typecast messageID to the actual MBOX number. But how to use this same list to init the actual enum-listed value into the MSGID register?

Thanks for any ideas!

  • More preferred, it would be nice to have a define/list formatted including a description of the message, along the lines of '0, SendHeartBeat, 0x321' that is coded/split up to put 0x321 into MBOX0_MSGID, and the function call would be 'SendMessage(SendHeartBeat)'.
  • Hi Harry,

    Which CAN module are you using? eCAN or DCAN?

    It may be helpful to show the specific steps that you need to send the message so we can brainstorm how to format them.

  • Hello Devin,

    This is eCAN (on a F28069F), but this is not really relevant to my core question. CAN message TX+RX works fine, but I'm now trying to get from basic functon to proper structure/parameter format in the function. It is more about data structure and not have a repeat entry of the same information in multiple places.

    Already made progress in this direction: Current setup is two defines using the mbox number as link/base (this only for TX using 16 messages/MBOXes; similar for RX using MBOX[16...31]) :

    const short CAN_TX_id[16] = { 0x321, 0x331, 0x332, ......, 0x355 };

    that is loaded into MBOX[0...15]->STDMSGID in CAN_init()

    and:

    typedef enum { TXheartbeat = 0, TXinfo_1, TXinfo_2, ...., TXinfo_15 } enum_CANtx;

    that allows:

    enum_CANTX TXmessage;
    char CANdata[8];
    .....
    CAN_TX_message(ecanHandle, (char)TXmessage, CANdata)
    ....

    So that is already a nice human-friendly setup, linking 'CAN_message_name' -> mbox_number -> CAN_MSGID.

    This is working okay. But it has two lists/defines using the MBOX_number as the intermediate / linking step between the 'message description' and the CAN_MSGID. So mostly out of curiosity / can this be done / could it be more perfect: Define one single list "TXheartbeat = 0x321, TXinfo_1 = 0x331, ..., TX_info_15 = 0x355 };
    and let the compiler figure out both the MBOX[0..15]_MSGID filling and the 'message_name'->MBOX_number conversion.

    I guess this could be an enum define, *if* (big IF) there is a method to get the information in the first row of an enum list. 'Get_Enum_list_value[0]' which would return the value '0x321', and a way to typecast 'TXheartbeat' to value '0'. I'm no expert, so again, mostly out of curiosity, is there a way to create this?

    Harry
  • Harry,

    I don't think there's a cleaner way to do it. There's no simple relationship between the mailbox numbers and message IDs. The only option I can think of would be to define a two-element struct:

    struct CAN_TX_DATA
    {
    uint16_t id;
    uint16_t mbox;
    };

    struct CAN_TX_DATA TXheartbeat = {0x321, 0}, TXinfo_1 = {0x331, 1} ...

    but that doesn't seem to improve things.