我正在尝试使用 C(带有 PCAN 路由器接口)来操纵 CAN 信号。
程序所做的是等待 CAN 特定帧,如 0x1F0,然后修改一些位。我要修改的位基于 DBC 文件。因此,我试图通过使用 cantools 生成源代码来使其更动态地生成基于 DBC 文件的 .h 和 .c 文件,这是一个示例 motohawk.h 和 motohawk.c.
链接到 motor DBC 文件.
我希望能够像这样以某种方式操纵信号。
所以问题是我如何使用源来操纵信号信号?例如温度信号?也许我看错了,不可能做我想做的事。
来自 DBC 的框架:
BO_ 496 ExampleMessage: 8 PCM1
SG_ Temperature : 0|12@0- (0.01,250) [229.52|270.47] "degK" PCM1,FOO
SG_ AverageRadius : 6|6@0+ (0.1,0) [0|5] "m" Vector__XXX
SG_ Enable : 7|1@0+ (1,0) [0|0] "-" Vector__XXX
我想做的是有一个类似这样的结构:
struct motohawk_example_message_t {
/**
* Range: -
* Scale: 1
* Offset: 0
*/
uint8_t enable;
/**
* Range: 0..50 (0..5 m)
* Scale: 0.1
* Offset: 0
*/
uint8_t average_radius;
/**
* Range: -2048..2047 (229.52..270.47 degK)
* Scale: 0.01
* Offset: 250
*/
int16_t temperature;
};
但我想有可能使用类似的东西:
frame_1F0 = motohawk_example_message_t();
frame_1F0.temperature.value = 255.01;
frame_1F0.temperature.value 将在帧中填充正确的位/字节(在 PCAN 中类似于 TxMsg.Data16[index] = 一些十六进制值)。有人做过吗?或者你知道是否可以使用 cantools 包生成的源代码来做到这一点?
这是PCAN代码
frame_1F0 = motohawk_example_message_t();
while (1)
{
CANMsg_t RxMsg, TxMsg;
// process messages from CAN1
if ( CAN_UserRead ( CAN_BUS1, &RxMsg) != 0)
{
// message received from CAN1
// catch ID 1F0h from CAN1 to modify data
if ( RxMsg.Id == 0x1F0)
{
RxMsg.Id = 0x1E4;
RxMsg.Type = CAN_MSG_STANDARD;
}
// copy message
TxMsg.Id = RxMsg.Id;
TxMsg.Type = RxMsg.Type;
TxMsg.Len = RxMsg.Len;
frame_1F0.temperature.value = 255.01; // this should be TxMsg.Data[xxx] = 255.01. THIS is the hard part :/
// send
CAN_UserWrite ( CAN_BUS2, &TxMsg);
...
使用 cantools 生成的代码可用于 convert 二进制数据到可以访问信号的结构,反之亦然。
在你的情况下,这样的事情应该有效
...
CANMsg_t RxMsg, TxMsg;
struct motohawk_example_message_t frame_1F0;
motohawk_example_message_unpack(&frame_1F0, RxMsg.Data.Data8, RxMsg.Len);
int16_t encoded_temperature = motohawk_example_message_temperature_encode(255.01);
frame_1F0.temperature.value = encoded_temperature;
motohawk_example_message_pack(TxMsg.Data.Data8, &frame_1F0, TxMsg.Len);
...
在我的头顶打字。该代码可能无法开箱即用,但我希望它有助于理解这个想法。
在生成的源代码中,
_pack
和 _unpack
函数可用于将 _message
结构转换为二进制数据并返回。
_encode
和 _decode
函数用于将信号从其物理表示转换为原始表示并返回。