SocketCAN可以连续读写

SocketCAN可以连续读写,c,embedded,nonblocking,can-bus,socketcan,C,Embedded,Nonblocking,Can Bus,Socketcan,我正在编写一个程序,它不断地向CAN总线发送Hello,并通过SocketCAN从总线读取数据。我希望这两个步骤是独立的。这意味着即使总线上没有数据,程序仍然会发送Hello。但对于通常的CAN读取,这是不可能的,因为此函数停止程序运行并等待数据 有没有办法使其不阻塞或只等待几毫秒的数据?您可以使用以下星座图这不是完整的解决方案,只是算法: while(1) { FD_ZERO(&rdfs); FD_SET(s, &rdfs); tv.tv_sec =

我正在编写一个程序,它不断地向CAN总线发送Hello,并通过SocketCAN从总线读取数据。我希望这两个步骤是独立的。这意味着即使总线上没有数据,程序仍然会发送Hello。但对于通常的CAN读取,这是不可能的,因为此函数停止程序运行并等待数据


有没有办法使其不阻塞或只等待几毫秒的数据?

您可以使用以下星座图这不是完整的解决方案,只是算法:

while(1) {
    FD_ZERO(&rdfs);
    FD_SET(s, &rdfs);

    tv.tv_sec = 0;
    tv.tv_usec = 10000; // microseconds

    rc = select(s + 1, &rdfs, NULL, NULL, &tv);

    // rc == 0 - timeout
    if (!rc) {
         // write your CAN frame
    }

    if (FD_ISSET(s, &rdfs)) {
         // read CAN frames
    }
}

有关更多信息以及如何处理返回值,请参阅。

我找到的另一种方法-线程。只要让读卡器在线程中工作,它就不会停止主循环。对于Linux系统,它如下所示:

 #include <pthread.h>

    void *thread(int cansock) {
       struct can_frame rxmsg;      
       while (1) {   
            read(cansock, &rxmsg, sizeof(rxmsg));
            printf("message received\n");                     
        }
    }

    int main(){
// initialize CAN socket and message to send
    pthread_t pth;
    pthread_create(&pth, NULL, thread, cansock);
    while(1){
      write(cansock, &txmsg, sizeof(txmsg));
      printf("message sent\n");
      }
    return 0;
    }

请小心使用此解决方案:

void *thread(int cansock) {
       struct can_frame rxmsg;      
       while (1) {   
            read(cansock, &rxmsg, sizeof(rxmsg));
            printf("message received\n");                     
        }
    }

因为如果read开始返回一个没有阻塞的错误,并且这个错误在字段中,并且没有人查看printf的结果,那么您将进入一个繁忙的循环。

我通过在初始化时添加以下代码来解决它

蒂梅瓦尔电视; tv.tv_sec=0; tv.tv_usec=10000; setsockoptskt、SOL、SOU、RCVTIMEO和tv、sizeoftv;
并在另一个线程中添加循环读取。

您不必使用select for SocketCAN,尽管这样做一点问题都没有;您还可以使用setsockoptsock、SOL_SOCKET、SO_RCVTIMEO和tv、sizeoftv,其中tv是接收超时的时间值。那么,如果超时过期,EAGAIN的read将失败。@Jason C:我喜欢你的建议,但对我不起作用:我像上面一样尝试过,也用setsockoptskt、SOL_CAN_RAW、SO_RCVTIMEO、,。。。因为这似乎更有可能,但在这两种情况下,读取调用都会被永远阻止,直到帧到达时没有超时。哎呀,我的错误。。。来自linux socket手册:如果超时设置为默认值零,那么操作将永远不会超时。我使用了0的超时,希望在没有要读取的帧时立即返回。顺便说一下,您可以使用setsockoptsock、SOL_SOCKET、SO_RCVTIMEO、&tv、sizeoftv,其中tv是timeval来设置读取超时。然后,如果超时过期,EAGAIN的读取将失败。您还可以使用来减少处理开销,只过滤您感兴趣的帧;而不是答案本身。我知道你还不能发表评论-请看一些关于你在此期间可以做什么的细节。