C - Отправка циклического сообщения в менеджер вещания socketCAN - PullRequest
0 голосов
/ 10 мая 2019

Я пишу некоторые сообщения на шине CAN, используя менеджер вещания socketcan:

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 мс, но это не то, что я хочу,Я хочу отправить пять сообщений (от кадра [0] до кадра [4]) один раз, затем продолжить отправку только последнего кадра (кадра [4]) всегда с интервалом 100 мс.Таким образом, 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 и вручную изменить передачу BMC, как мне нужно?И только если в случае, как и где я могу обработать это сообщение TX_EXPIRED?Есть ли другой, более простой способ достичь моей цели?

1 Ответ

0 голосов
/ 13 мая 2019

Вы должны разделить ваш msg на два экземпляра до bcm_message.

В первом вы настраиваете свои кадры от 0 до 3. SETTIMER и STARTTIMER на самом деле не нужны, есливы хотите, чтобы эти сообщения отправлялись только один раз.

Во втором случае вы просто настраиваете то, что frame[4] в вашем коде.Затем вы можете установить iva2.tv_usec, который будет применяться только к этому кадру.

...