【问题标题】:High cpu load when reading from /dev/ttyACM0从 /dev/ttyACM0 读取时 CPU 负载高
【发布时间】:2014-08-18 09:42:20
【问题描述】:

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

我的设置

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

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

[321.998462] USB 2-2:USB 断开,设备号 3 [327.541414]usb 2-2:使用 ohci_hcd 的新全速 USB 设备编号 5 [327.998963]usb 2-2:找到新的 USB 设备,idVendor=0471,idProduct=0889 [327.998983]usb 2-2:新的 USB 设备字符串:Mfr=1,Product=2,SerialNumber=3 [327.998997] USB 2-2:产品:WTS [327.999011] USB 2-2:制造商:Weiss Robotics [327.999024]usb 2-2:序列号:0001 [328.035356] cdc_acm 2-2:1.0:此设备无法自行调用。它不是调制解调器。 [328.035424]cdc_acm 2-2:1.0:ttyACM0:USB ACM设备

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

完整的测试代码

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

【问题讨论】:

  • 我想在这里看到更多像这样的初学者问题。

标签: c++ linux kernel driver


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-23
    • 2012-05-14
    相关资源
    最近更新 更多