我想在 Linux 下用简单的 C 或 C++ 程序读取通过 FTDI(串行)接口从 Arduino 发送的消息。 Arduino 发送两个字符的“标头”、一个命令字节,后跟几个字节的数据(具体取决于命令)。
我的第一次尝试是简单地使用 open() 和 read() 轮询数据,但这样做会导致大约 12% 的 CPU 使用率。这似乎不是正确的做事方式。
其次,我阅读了 libevent,实现了一个事件循环,当文件描述符上存在数据时,该循环会触发一个事件。我的 CPU 使用率几乎为零,但在调用另一个事件之前我无法读取整个消息。当收到整个消息时,事件不会触发,而是在文件描述符上有任何/某些数据可用时触发。仔细观察一下,很明显这不会按照我想要的方式工作。这是我的活动代码:http://pastebin.com/b9W0jHjb http://pastebin.com/b9W0jHjb
第三,我用 libevent 实现了一个缓冲事件。它似乎工作得更好一些,但仍然分割了一些消息。我的活动代码是:http://pastebin.com/PQNriUCN http://pastebin.com/PQNriUCN
第四,我放弃了 libevent 并尝试了 Boost 的 ASIO 类。我遵循的例子是http://www.webalice.it/fede.tft/serial_port/serial_port.html http://www.webalice.it/fede.tft/serial_port/serial_port.html。它似乎工作正常,但“事件循环”是一个“while(1) {}”,导致 CPU 使用率再次上升。该循环仅检查错误状态,而串行读取发生在不同线程的回调中。我在 while 循环中添加了 usleep(1) ,它使我的 CPU 使用率达到 2%,这还可以,但对于这样一个轻量级的程序来说仍然显得很重。
libevent 的大多数示例甚至底层的 epoll 都使用 TCP 套接字,这似乎与串行端口数据的行为不太一样。
所以我的主要问题是:有什么好的轻量级方法可以从串行端口读取消息而无需大量轮询? (在linux中,使用C或C++)
OP可能早就解决了这个问题,但为了任何通过谷歌到达这里的人:
#include <sys/poll.h>
struct pollfd fds[1];
fds[0].fd = serial_fd;
fds[0].events = POLLIN ;
int pollrc = poll( fds, 1, 1000);
if (pollrc < 0)
{
perror("poll");
}
else if( pollrc > 0)
{
if( fds[0].revents & POLLIN )
{
char buff[1024];
ssize_t rc = read(serial_fd, buff, sizeof(buff) );
if (rc > 0)
{
/* You've got rc characters. do something with buff */
}
}
}
确保串行端口以非阻塞模式打开,因为 poll() 有时会在没有字符等待时返回。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)