C 中基于信号的 CAN 总线帧操作

问题描述 投票:0回答:1

我正在尝试使用 C(带有 PCAN 路由器接口)来操纵 CAN 信号。

程序所做的是等待 CAN 特定帧,如 0x1F0,然后修改一些位。我要修改的位基于 DBC 文件。因此,我试图通过使用 cantools 生成源代码来使其更动态地生成基于 DBC 文件的 .h 和 .c 文件,这是一个示例 motohawk.hmotohawk.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);
...
python c arm can-bus
1个回答
0
投票

使用 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
函数用于将信号从其物理表示转换为原始表示并返回。

© www.soinside.com 2019 - 2024. All rights reserved.