0

我正在使用 socketcan 的广播管理器在 CAN 总线上写一些消息:

struct bcm_message{
    struct bcm_msg_head msg_head;
    struct can_frame frame[5];
};

int main(){
    int s;
    struct sockaddr_can addr;
    struct ifreq ifr;
    struct bcm_message msg;     
    s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
    strcpy(ifr.ifr_name, "can1");
    ioctl(s, SIOCGIFINDEX, &ifr);
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    connect(s, (struct sockaddr *)&addr, sizeof(addr));

    msg.msg_head.opcode  = TX_SETUP;
    msg.msg_head.can_id  = 0x180;
    msg.msg_head.flags   = SETTIMER|STARTTIMER|TX_CP_CAN_ID;
    msg.msg_head.nframes = 5;
    msg.msg_head.count = 5;
    msg.msg_head.ival1.tv_sec = 0;
    msg.msg_head.ival1.tv_usec = 100000;
    msg.msg_head.ival2.tv_sec = 0;
    msg.msg_head.ival2.tv_usec = 0;
    msg.frame[0].can_dlc=8;
    memcpy(msg.frame[0].data,(__u8[]){0x00,0x28,0xFF,0x00,0x00,0x01,0xFF,0x00},8);
    msg.frame[1].can_dlc=8;
    memcpy(msg.frame[1].data,(__u8[]){0x00,0x32,0xFF,0x00,0x00,0x01,0xFF,0x00},8);
    msg.frame[2].can_dlc=8;
    memcpy(msg.frame[2].data,(__u8[]){0x00,0x3C,0xFF,0x00,0x00,0x01,0xFF,0x00},8);
    msg.frame[3].can_dlc=8;
    memcpy(msg.frame[3].data,(__u8[]){0x00,0x46,0xFF,0x00,0x00,0x01,0xFF,0x00},8);
    msg.frame[4].can_dlc=8;
    memcpy(msg.frame[4].data,(__u8[]){0x00,0x50,0xFF,0x00,0x00,0x01,0xFF,0x00},8);

    write(s, &msg, sizeof(msg));
    while(1){}
return 0;
}

此代码工作正常,只需以 100 毫秒的间隔发送 5 条消息,但这不是我想要的。我想发送五个消息(从帧 [0] 到帧 [4])一次,然后以 100 毫秒的间隔继续仅发送最后一帧(帧 [4])。所以 bcm 应该发送:

frame[0]
frame[1] 
frame[2] 
frame[3] 
frame[4] 
frame[4] 
frame[4] 
frame[4] 
....
....

如果我将 iva2.tv_usec 设置为 100000,它将继续发送所有帧,而我只想发送最后一个帧。我怎么能这样做?我读过添加 TX_COUNTEVT 标志,当计数达到零时,bcm 将生成 TX_EXPIRED 消息。也许我可以处理这个 TX_EXPIRED 消息并根据需要手动修改 bcm 传输?如果以防万一,我可以如何以及在哪里处理这个 TX_EXPIRED 消息?还有其他更简单的方法可以达到我的目标吗?

4

2 回答 2

0

您必须将您msg分成两个实例才能bcm_message.

在第一个中,您将帧配置为 0 到 3。如果您希望这些消息只发送一次SETTIMER,则实际上没有必要。STARTTIMER

在第二种情况下,您只需配置frame[4]代码中的内容。然后您可以设置iva2.tv_usec仅适用于该框架。

于 2019-05-13T11:17:53.413 回答
0

您首先需要发送一条 BCM 消息,其中包含帧 0 到 3 的内容。在此消息中,您需要配置 SETTIMER、STARTTIMER 和 TX_COUNTEVT。当您收到 TX_EXPIRED 消息时,只需发送另一个 BCM 消息,其中只有第 4 帧,并且只设置了 SETTIMER 标志(以及相同的时序配置)。这不会重新启动计时器,并将继续发送新数据。

于 2020-05-08T09:58:28.397 回答