Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SocketCAN continuous reading and writing

I'm writing a program that continuously sends "Hello" to a CAN-bus and reads data from the bus via SocketCAN. I want those two steps to be independent. That means even if there is no data on the bus, the program will still send "Hello". But with usual CAN reading it is impossible, because this function stops program run and waits for data.

Is there a way how to make it non-blocking or waiting for data only for a few milliseconds?

like image 732
PaulPonomarev Avatar asked Oct 27 '25 12:10

PaulPonomarev


2 Answers

You can use following constellation (this is not the complete solution, but just algorithm):

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
    }
}

See man select for more information and how to handle return value.

like image 136
yegorich Avatar answered Oct 29 '25 03:10

yegorich


Another way I found - threads. Just make CAN reading work in thread and it won't stop main cycle. For Linux systems it looks like this:

 #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;
    }
like image 28
PaulPonomarev Avatar answered Oct 29 '25 02:10

PaulPonomarev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!