从/ dev / ttyACM0读取时的CPU负载很高

时间:2014-06-27 10:02:31

标签: c++ linux kernel driver

我正在尝试实现一个从触觉传感器读取数据的程序,但我遇到了高CPU负载问题。我需要帮助来减少CPU负载。

我的设置

我正在读取几个(最多16个)tacilte传感器的数据。传感器通过USB连接到我的电脑。在Linux中,这些设备创建虚拟串行端口:/ dev / ttyACM0,/ dev / ttyACM1,/ dev / ttyACM2 ......

这就是dmesg告诉我的,当我插入传感器(一个传感器的输出)时:


    [  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

我使用termios.h中的termios来打开串行设备。由于传感器具有二进制协议,因此我将设备设置为非规范并使用原始输出。传感器提供周期性采样功能,每秒发送大约270帧数据。

一旦完整的帧可用,我的程序应该从串行设备读取并处理帧。

问题:高CPU负载

这是我的代码基本上做的:

int fd = open("/dev/ttyACM0");
struct termios settings;
settings.xxx = ... // see full code for details
tcflush( fd, TCIFLUSH );
tcsetattr( fd, TCSANOW, &settings );

while(1)
{
    Frame f = readCompleteFrame(fd);
    processFrame(f);
}

当我将设备置于阻塞读取模式并执行我的循环时,cpu负载变为大约15%。我为每个传感器都有一个单独的线程。由于我有多个传感器,每个线程将占用一个cpu核心的15%。

我使用time命令对程序进行了分析:几乎所有的cpu时间都花在了内核中。用户时间接近于零。

我试图修复它

  • 我将设备置于非阻塞模式,并使用来自sys / poll.h的poll。 cpu负载相同:每个传感器15%。
  • 我将设备置于非阻塞模式,并使用unistd.h中的select。与民意调查结果相同。
  • 我将设备置于非阻塞模式并继续调用read(fd); usleep(1);直到我得到一些数据。这使用50%的cpu,但与传感器的数量无关。

完成测试代码

我可以在此处找到用于测试的完整代码:http://pastebin.com/7dv0U2nN

1 个答案:

答案 0 :(得分:0)

检查完代码后,您可以在应用程序中修复此问题。

负载可能是由内核驱动程序中的问题或USB设备与PC通信的方式引起的。