title: High cpu load when reading from /dev/ttyACM0
body: <p>I'm trying to implement a program to read data from tactile sensors, but I have problems with high cpu load. I need help to reduce the cpu load.</p>
  
  <h2>My Setup</h2>
  
  <p>I'm reading data from several (up to 16) tacilte sensors. The sensors are connected via usb to my pc. In Linux these devices create virtual serial ports: /dev/ttyACM0, /dev/ttyACM1, /dev/ttyACM2 ...</p>
  
  <p>This is what dmesg tells me, when I plug in the sensors (output for one sensor):</p>
  
  <pre>
  
      [  321.998462] usb 2-2: USB disconnect, device number 3
      [  327.541414] usb 2-2: new full-speed USB device number 5 using ohci_hcd
      [  327.998963] usb 2-2: New USB device found, idVendor=0471, idProduct=0889
      [  327.998983] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
      [  327.998997] usb 2-2: Product: WTS
      [  327.999011] usb 2-2: Manufacturer: Weiss Robotics
      [  327.999024] usb 2-2: SerialNumber: 0001
      [  328.035356] cdc_acm 2-2:1.0: This device cannot do calls on its own. It is not a modem.
      [  328.035424] cdc_acm 2-2:1.0: ttyACM0: USB ACM device
  
  </pre>
  
  <p>I use termios from termios.h to open the serial device. As the sensors have a binary protocol I set the device to non-canonical and use raw output. The sensors provide a periodic sampling feature which will send about 270 frames of data per second.</p>
  
  <p>My program should read and process the frame from the serial device as soon as the complete frame is available.</p>
  
  <h2>The Problem: high cpu load</h2>
  
  <p>This is what my code basically does:</p>
  
  <pre><code>int fd = open("/dev/ttyACM0");
  struct termios settings;
  settings.xxx = ... // see full code for details
  tcflush( fd, TCIFLUSH );
  tcsetattr( fd, TCSANOW, &amp;settings );
  
  while(1)
  {
      Frame f = readCompleteFrame(fd);
      processFrame(f);
  }
  </code></pre>
  
  <p>When I put the device into blocking read mode and execute my loop, the cpu load goes to about 15%. I have a separate thread for each sensor. As I have multiple sensors each thread will consume 15% of one cpu core.</p>
  
  <p>I profiled the program using the time command: Nearly all of the cpu time is spent in the kernel. The user time is next to zero.</p>
  
  <h2>What I tried to fix it</h2>
  
  <ul>
  <li>I put the device into non-blocking mode and used poll from sys/poll.h. The cpu load is the same: 15% per sensor.</li>
  <li>I put the device into non-blocking mode and used select from unistd.h. Same result as poll.</li>
  <li>I put the device into non-blocking mode and kept calling read(fd); usleep(1); until i got some data. This uses 50% cpu, but is independant of the number of sensors.</li>
  </ul>
  
  <h2>Complete test Code</h2>
  
  <p>The complete code I used for testing can be found here: <a href="http://pastebin.com/7dv0U2nN" rel="nofollow">http://pastebin.com/7dv0U2nN</a></p>