Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
读取串行数据而不占用大量CPU 我想通过Linux下的简单的C或C++程序,通过FTDI(串行)接口读取从ARDUINO发送的消息。Arduino发送一个两个字符的“header”,一个命令字节,后跟取决于命令的几个字节的数据_Linux_Serial Port - Fatal编程技术网

读取串行数据而不占用大量CPU 我想通过Linux下的简单的C或C++程序,通过FTDI(串行)接口读取从ARDUINO发送的消息。Arduino发送一个两个字符的“header”,一个命令字节,后跟取决于命令的几个字节的数据

读取串行数据而不占用大量CPU 我想通过Linux下的简单的C或C++程序,通过FTDI(串行)接口读取从ARDUINO发送的消息。Arduino发送一个两个字符的“header”,一个命令字节,后跟取决于命令的几个字节的数据,linux,serial-port,Linux,Serial Port,我的第一次尝试是使用open()和read()简单地轮询数据,但这样做会导致大约12%的CPU使用。这似乎不是正确的做事方式 其次,我了解了libevent上实现的一个事件循环,该循环在文件描述符上存在数据时触发事件。我的cpu使用率几乎为零,但在调用另一个事件之前,我无法读取整个消息。当接收到整个消息时,但只要文件描述符上有任何/某些数据可用,就不会触发事件。更仔细地看,很明显,这并不是我想要的方式。这是我的活动代码: 第三,我用libevent实现了一个缓冲事件。它似乎工作得更好一些,但仍然

我的第一次尝试是使用open()和read()简单地轮询数据,但这样做会导致大约12%的CPU使用。这似乎不是正确的做事方式

其次,我了解了libevent上实现的一个事件循环,该循环在文件描述符上存在数据时触发事件。我的cpu使用率几乎为零,但在调用另一个事件之前,我无法读取整个消息。当接收到整个消息时,但只要文件描述符上有任何/某些数据可用,就不会触发事件。更仔细地看,很明显,这并不是我想要的方式。这是我的活动代码:

第三,我用libevent实现了一个缓冲事件。它似乎工作得更好一些,但仍然将一些消息分割开来。我的活动代码是:

第四,我抛弃了libevent并试用了Boost的ASIO类。我举的例子是。它似乎工作正常,但“事件循环”是一个“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 */
        }
    }
}    
#包括
结构pollfd fds[1];
fds[0].fd=串行_fd;
fds[0]。事件=POLLIN;
int pollrc=轮询(fds,11000);
if(pollrc<0)
{
佩罗(“投票”);
}
else if(pollrc>0)
{
if(fds[0]。revents和POLLIN)
{
字符buff[1024];
ssize_t rc=读取(串行fd、buff、sizeof(buff));
如果(rc>0)
{
/*你有rc角色。用buff做点什么*/
}
}
}    

确保串行端口在非阻塞模式下打开,因为poll()有时会在没有字符等待时返回。

您使用的是非阻塞
read()
?阻塞
read()
对您无效吗?调用
read
是一个阻塞调用。你能证明调用
read
导致了12%的CPU使用,或者你只是在看一个系统监视器吗?如果它真的是CPU密集型的,那么试着通过
gprof
运行它,看看瓶颈在哪里。我通常在大多数情况下使用Qt库,但对于这个小任务来说它似乎有点重。另外,我喜欢学习API的“较低”级别。我的第一次尝试使用了阻塞读取(),而我的libevent尝试使用了非阻塞读取()。明天我将检查gprof并使用一个简单的blocking read(),然后报告我的发现。在Windows上,您可以使用低级FTDI SDK库,它完全绕过系统串行端口驱动程序。不确定它是否可以在linux上使用,但如果可以的话,你可以试一试。