我有一条CAN总线消息,它由3部分组成。 解码的最佳方法是什么?
我的想法是在对第一部分进行解压缩时使用3个FIFO,将其存储在FIFO中,而对其他2个部分相同。
然后我将这3个Fifos组合成一条消息。
总消息长度为64字节PDU长度
我正在使用以下功能来获取总线数据
HAL_CAN_GetRxMessage
答案 0 :(得分:0)
考虑到标准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] = '\0';
答案 1 :(得分:0)
使用来自here的上一个问题的答案,您可以将该位字段与纯uint8_t [64]
结合使用。例如
typedef struct
{
uint8_t data[64];
can_received_t received;
} msg_t;
在接收到数据时将其填满,将其写入相应的数据字节,然后将该位置1以指示已部分接收到该消息。在您收到所有部分之前,该结构才被认为是完整的。
队列/ 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
}
这是相当快速的代码,无需排队。