CAN总线多报文解码方法

Decoding multiple message of CAN bus method

我有一个由 3 部分组成的 CAN 总线消息。 最好的解码方法是什么?

我的想法是,第一部分分解的时候用3个FIFO,我把它存到FIFO里,其他2个部分也一样。

然后我将这 3 个 Fifos 组合成一条消息。

总消息长度为 64 字节 PDU 长度

我正在使用以下函数获取 can 总线数据

HAL_CAN_GetRxMessage

can bus

考虑到标准 CAN 消息的大小为 8 字节长度,您可以将消息声明为 uin64_t 并使用 |.

将各个信号组合成消息

示例:

uint64_t message = 0;
uint8_t incomingBytes[8] = {0};

for(int i=0; i<8; i++)
{
    message = message <<8;
    message |= incomingBytes[i];
}

如果您想将 VIN 数据解释为 string 那么,

 char vindata [9];
 memcpy(vindata, incomingBytes, 8);
 vindata[8] = '[=11=]';

使用 对您上一个问题的回答,您可以将该位域与普通 uint8_t [64] 结合使用。例如

typedef struct
{
  uint8_t data[64];
  can_received_t received;
} msg_t;

在收到数据时填充数据,将其写入相应的数据字节,然后设置该位以指示已部分接收到消息。在您收到所有部分之前,该结构不被视为完整。

一个queue/FIFO只满足一个目的,那就是延迟执行某事,直到有更多时间的时候。没有理由在这里这样做。您的 CAN 消息解码可能类似于:

msg_t msg;

switch(received_can_id)
{
  ...
  case CANID_FOO:  
    memcpy(&msg.data[FOO_INDEX], rec_data, FOO_SIZE);
    msg.received |= RECEIVED_FOO;
    break;

  case CANID_BAR:
    memcpy(&msg.data[BAR_INDEX], rec_data, BAR_SIZE);
    msg.received |= RECEIVED_BAR;
    break;
  ...
}

if(msg.received == RECEIVED_ALL)
{
  use(&msg); // do something
  memset(&msg, 0, sizeof msg); // reset everything
}

这是相当快速的代码,无需排队。