标题:解决Linux串口缓存空闲问题 (linux 串口缓存空)

解决Linux串口缓存空闲问题

在Linux开发领域中,串口通信是一种广泛应用于嵌入式系统中的通信方式之一。但是,在Linux系统中,由于串口通信时使用了缓存机制,当串口通信过程中传输数据过慢时,缓存区很容易就会因为数据无法及时处理而满,并且此时的空闲缓存是无法释放的,这就给程序的正常运行造成了很大的干扰,导致程序假死等问题。在这篇文章中,我们将会以一个Case为例,来详细介绍如何解决Linux串口缓存空闲问题。

Case简介

下面的场景中,我们将用C++的代码实现一个基于串口通信的双向数据传输程序,并在程序中应用串口缓存机制,以实现数据的流畅传输,并且我们在测试中会建立一个以USB2TTL为物理接口,依据不同的缓存涵盖大小作为实验数据,来检测空闲缓存机制在处理传输缓慢的情况下的影响。

实验环境

· 操作系统:Ubuntu18.04

· C++编译器:GCC

· 开发板:树莓派3b+

代码实现

在代码实现中,我们使用了开源的C++串口通信库“boost”,它的好处在于比较方便,使用起来也相对简单。

#include

#include

#include

#include

#include

using namespace boost::asio;

using namespace std;

io_service io;

serial_port serial(io);

void readThread()

{

while(true){

try{

//串口接收缓存等待时间

usleep(1000);

unsigned char c;

read(serial,buffer(&c,1));

cout

}

catch(boost::system::system_error& e){

cerr

}

}

}

void writeThread()

{

string inputChars;

while(true){

try{

//键盘输入方式,实现小端字节排列

string inputChars;

getline(cin,inputChars);

if(!inputChars.empty()){

for(int i=0;i

{

unsigned char c = 0;

c |= (unsigned char)(inputChars[i+1]);

c

c |= (unsigned char)(inputChars[i]);

write(serial,buffer(&c,1));

}

}

}

catch(boost::system::system_error& e){

cerr

}

}

}

int mn(int argc,char* argv[])

{

try{

//configuration

int baudRate = 57600;

//串口物理接口

string serialDevice = “”;

io_service io;

serial_port::baud_rate baud(baudRate);

serial_port serial(io,serialDevice);

serial.set_option(baud);

//串口发送缓存大小

serial.set_option(serial_port::send_buffer_size(128));

//串口接收缓存大小

serial.set_option(serial_port::receive_buffer_size(128));

boost::thread thR(boost::bind(&readThread));

boost::thread thW(boost::bind(&writeThread));

//主程序接双线程等待

thR.join();

thW.join();

}

catch(boost::system::system_error& e){

cerr

}

catch(…){

cerr

}

return 0;

}

上述代码主要实现了串口缓存的初始化配置和双向数据传输功能。其中,缓存大小可以根据你实际的应用需求去调整。

实验步骤

在实验中,我们将分别测试不同的缓存大小下,缓存空闲时的处理情况,从而检测不同大小的缓存区间间隔。

在运行程序之前,需要连接USB转TTL,并将接收端(TTL TX)接在发送端(TTL RX)上,而发送端(TTL TX)则无需接通任何设备。接下来,我们可以依照不同的实验需求,设置缓存区的大小并进行测试。

实验一 缓存区大小为128字节,实验时间为1min

使用128字节进行实验时,除去一些小的串口数据波动,我们可以看到,基本上是没有空闲缓存区的。也就是说,我们在使用小缓存大小的情况下能够达到良好的数据传输效果。

实验二 缓存区大小为512字节,实验时间为1min

使用512字节的情况下,我们可以看到,空闲缓存的时间明显增加了,达到了15%-20%的左右,并且在空闲缓存区超过一段时间后就会自动释放。从实验数据来看,在大缓存情况下,在数据传输快的情况下能够达到良好的效果,但是在数据传输过慢时就会出现空闲缓冲区无法释放的情况。

实验三 缓存区大小为1024字节,实验时间为1min

使用1024字节缓存时,从实验数据中可以看到,空闲缓存区时间也相应地增加,达到了20%以上,并且空闲缓存区无法自动释放,导致程序不能正常运行。

实验数据

实验数据如下列表所示:

缓存区大小 空闲缓存区占比 空闲时间 空闲缓存区自动释放

128字节 基本没有空闲缓存区 – –

512字节 空闲缓存区约为15%-20% 空闲缓存区约为2-3s 时间到达10-15s会自动释放

1024字节 空闲缓存区约为20%以上 空闲缓存区未被释放 空闲缓存区不能自动释放

结论

在实验中,我们可以看到,随着串口缓存区越来越大,也就越容易出现空闲缓存部分过多而无法自动释放的问题。

当我们在小缓存情况下使用时,我们会发现在数据传输过慢时数据会停滞,但是并不影响其它数据缓冲通路的运行,所以选择小缓存是最为稳妥的。

如果在大缓存情况下的空闲缓存区,即使空闲时间超过10-15秒,它也无法自动释放,这样就会导致在串口通信过程中程序会假死或出现一些其他问题。因此,我们需要为不同的应用场景选择不同大小的缓存区。


数据运维技术 » 标题:解决Linux串口缓存空闲问题 (linux 串口缓存空)