c++ - 从/dev/ttyACM0 读取时 CPU 负载高

标签 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

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.

My program should read and process the frame from the serial device as soon as the complete frame is available.

The Problem: high cpu load

This is what my code basically does:

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 的轮询。 CPU 负载相同:每个传感器 15%。
  • 我将设备置于非阻塞模式并使用 select from unistd.h。与投票结果相同。
  • 我将设备置于非阻塞模式并不断调用 read(fd); sleep (1);直到我得到一些数据。这使用 50% 的 CPU,但与传感器的数量无关。

完整的测试代码

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

最佳答案

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

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

关于c++ - 从/dev/ttyACM0 读取时 CPU 负载高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24449124/

相关文章:

c++ - MXE Qt5 应用程序在 Docker 容器中构建失败

c++ - 是否有任何功能可以知道键盘上的某个键是否被按下?

java - 如何在构建时在Gradle中运行控制台命令?

linux - 写入/dev/tty

c - 原子调度

c++ - 是否可以在 C++ 中定义匿名成员函数

C++ 迭代一个istream

c++ - 在 Linux 上构建静态 C++ 库 - 我需要链接到其他库吗?

c - 当我们转换 Descriptor+Descriptor->SerialNumberOffset 时序列号枚举失败

c - 获取当前运行程序在内核中的绝对路径