title: Fast CAN communication using sockets in C++
body: <p>I'm trying to use C/C++ to communicate with a CAN bus. I'm using sockets to read and write on the bus. I've created a write thread and a read thread. The read thread is constantly trying to read and the socket, and when a write request arrives, the write thread take control of the socket using a mutex and do the write.</p>
  <p>I'm having a big issue with speed using this method, as a write request can sometimes take 500 ms to be completed (which is completely unfeasible for my application). I've tried to put a timeout on the read command to make it non-blocking when nothing comes on the bus, but if the timeout is too short, I have reliability issues with the read. On the other hand, if I make it too long, the speed increase is insufficient.</p>
  <p>It's my first time working with CAN. Would you have some advices on implementation of fast, two-way CAN communication node in C/C++ ? Which library should I use to interface with the bus itself ? Which architecture would yield the lowest read and write latency ?</p>
  <p>To give a few metrics for the application, the bus bitrate is 1MBits/sec, I'm using CAN-Open with 64 bits data packets (each message contains 32 bits for indexes and 32 bits of data). I would like a write frequency from 300 to 500hz, same for the read frequency.</p>
  <p>Thanks a lot for your help !</p>
  <p>EDIT :</p>
  <p>Thanks a lot for all your comments. Here are some clarifications on my application and problems.</p>
  <p>I'm working on a mobile robot project, and I'm using CAN-Open to communicate with motor drivers and sensors. The code will run on a Raspberry Pi CM4 running Raspbian OS mounted on a custom IO board integrating a MCP2515 CAN controller. I want to implement fast communication interface between the ROS architecture and the CAN bus. The language used could be either C or C++.</p>
  <p>I'm currently using a homemade interface build around standard C sockets, but the speed is very low, and is a big bottleneck to the robot's performance. So I'm looking for a better solution, either:</p>
  <ul>
  <li>An open-source library build for this purpose</li>
  <li>Architecture suggestion to implement such a program</li>
  <li>A combination of both</li>
  </ul>
  <p>Here are the socket creation, the read and the write functions I use. Read and write being each called in a while loop in different threads (I'm using pthread):</p>
  <pre><code>bool connectCanBus(int* socketIDOut, std::string canInterfaceName){
    // Socket and can variables
    struct sockaddr_can addr;
    struct ifreq ifr;
  
    // Openning the socket to send commands over the can bus
    if ((*socketIDOut = socket(PF_CAN, SOCK_RAW, CAN_RAW)) &lt; 0) {
      perror(&quot;[Can Controler] Unable to create socket.&quot;);
      return false;
    }
  
    strcpy(ifr.ifr_name, canInterfaceName.c_str());
    ioctl(*socketIDOut, SIOCGIFINDEX, &amp;ifr);
    memset(&amp;addr, 0, sizeof(addr));
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
  
    // Setting option to gte errors as frames
    can_err_mask_t err_mask = 0xFFFFFFFF;
    setsockopt(*socketIDOut, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &amp;err_mask, sizeof(err_mask));
  
    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 10000;
    setsockopt(*socketIDOut, SOL_SOCKET, SO_RCVTIMEO, (const char*)&amp;tv, sizeof tv);
  
    // Binding Socket
    if (bind(*socketIDOut, (struct sockaddr *)&amp;addr, sizeof(addr)) &lt; 0)       
  {
      perror(&quot;[Can Controler] Unable to bind socket.&quot;);
      close(*socketIDOut);
      return false;
    }
  
    ROS_INFO(&quot;CAN bus connected.&quot;);
    return true;
  }
  
  int sendCommand(const char* id, const char* message, int socket, std::mutex&amp; mutex)
  {
    struct canfd_frame frame;
    int err = parseFrame(id, message, &amp;frame);
    if(err == 0){
      ROS_ERROR_STREAM(&quot;[Can Utils] Unable to parse frame : &quot; &lt;&lt; id &lt;&lt; &quot;, &quot; &lt;&lt;  message);
          return 0;
    }
  
      mutex.lock();
      int res = write(socket, &amp;frame, sizeof(struct can_frame));
      mutex.unlock();
    if (res != sizeof(struct can_frame)) {
      perror(&quot;[Can Utils] CAN bus Write error&quot;);
      return 0;
    }
    return 1;
  }
  
  int readBus(CanFrame *outFrame, int socketID, std::mutex&amp; mutex)
  {
      struct can_frame frame;
  
      // Reading on bus
      mutex.lock();
      int nbytes = read(socketID, &amp;frame, sizeof(struct can_frame));
      mutex.unlock();
      if (nbytes &lt; 0) {
          perror(&quot;[Can Utils] CAN bus Read error&quot;);
          return 0;
      }
  
    // Converting frame to strings
    sprint_canframe(outFrame, &amp;frame);
    return nbytes;
  }
  </code></pre>
  <p>I hope this make the question clearer and better focused.</p>