解决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系统缓存
# echo 1 > /proc/sys/vm/drop_caches
注:1>. /proc是一个虚拟消梁搜文件系统,可以通过对它的读写操作作为与kernel实体间进行通信的一种手段。也就是说可以通过修改/proc中的文件,来对当前kernel的行为做出调整。也就是说我们可以通过调整/proc/sys/vm/drop_caches来释放内存。
0 – 不释放
1 – 释放页缓存
2 – 释放文渣胡件节点缓存和目录项缓存
3 – 释放所有缓存
# sysctl -p
#查看拿历剩余内存
# free -m
totalusedfree shared buffers cached
Mem:
-/+ buffers/cache:
Swap:
#清理Linux系统缓存
# echo 1 > /proc/sys/vm/drop_caches
注:1>. /proc是一个虚拟文件系统,可以通过对它的读写操作作为与kernel实体间进行通信的一镇腊种手段。也就是说可以通过修改/proc中的文件,来对当前kernel的行为做出调整。也就是说我们可以通过调整/proc/sys/vm/drop_caches来释放内存。
0 – 不释放
1 – 释放页缓存搏旅枯
2 – 释放文件节点缓存和目录项缓存
3 – 释放所有缓存基洞
# sysctl -p
#查看剩余内存
# free -m
totalusedfree shared buffers cached
Mem:
-/+ buffers/cache:
Swap:
缓冲镇瞎区与特定的块设备相肆锋关联,包括文件系统元数据的缓存以及页面跟踪。缓存只御雹空包含已停放的文件数据。
也就是说,缓冲区记住目录中的内容、文件权限是什么,并跟踪从某个块设备中写入或读取到哪些内存。
缓存只包含文件本身的内容。
在Linux系统下,我们一般不需要去释放内存,因为系统已经将内存管理的很好。但是凡事也有例拿枝烂外,有的时候内存会被缓存占用掉,导致系统使用SWAP空间影响性能,此时就需要执行释放内存(清理缓存)的操作了。
Linux系统的缓存机制是相当先进的,他会针对dentry(用于VFS,加速文件路径名到inode的转换)、Buffer Cache(针对磁盘块的读写)和Page Cache(针对文件inode的读写)进行缓存操作。但是在进行了大量文件操作之后,缓消漏存会把内存资源基本用光。但实际上我们文件操作已经完成,这部分缓存已经用不到了。这个时候,我们难道只能眼睁睁的看着缓存把内存空间占据掉么?
所以,我们还是有必要来手动进行Linux下释放内存的操作,其实也就是释放缓存的操作了。
要达到释放缓存的目搭档的,我们首先需要了解下关键的配置文件/proc/sys/vm/drop_caches。这个文件中记录了缓存释放的参数,默认值为0,也就是不释放缓存。他的值可以为0~3之间的任意数字,代表着不同的含义:
0 – 不释放
1 – 释放页缓存
2 – 释放dentries和inodes
3 – 释放所有缓存
知道了参数后,我们就可以根据我们的需要,使用下面的指令来进行操作。
首先我们需要使用sync指令,将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件。否则在释放缓存的过程中,可能会丢失未保存的文件。
#sync
接下来,我们需要将需要的参数写进/proc/sys/vm/drop_caches文件中,比如我们需要释放所有缓存,就输入下面的命令:
#echo 3 > /proc/sys/vm/drop_caches
此指令输入后会立即生效,可以查询现在的可用内存明显的变多了。
要查询当前缓存释放的参数,可以输入下面的指令:
#cat /proc/sys/vm/drop_caches
#free -m
对于清除swap,只有先关闭swap了,用:
#swapoff -a
而后启用swap,因为只是清除,不是说不要用swap的嘛 :
#swapon -a
Linux 自动释放内存脚本
发表于119 天前 ? 技术文章 ? 暂无评论
脚本下载
脚本内容:
#! /bin/bash
# cache释放:
# To free pagecache:
sync
sync
#echo 1 > /proc/sys/vm/drop_caches
# To free dentries and inodes:
#echo 2 > /proc/sys/vm/drop_caches
# To free pagecache, dentries and inodes:
echo 3 > /proc/sys/vm/drop_caches
# 说明,释放前更好sync一下,防止丢数据。
利用系统crontab实现每天自动运行:
crontab -e
输入以下内容:
00 00 * * * /root/Cached.sh
每天0点释放一次内存,这个时间可以根据自己需要自行设置,我的服务器情况是每天自动释放一次就OK了
在设置这个脚本的时候,发生了一系列的问题
在测试运行./Cached.sh时提示错误:Permission denied 权限的问题
解决方法:
chmod +x .Cached.sh
或
chmod 777 Cached.sh
接着又出现错误提示:/bin/bash^M: bad interpreter: No such file or directory
这是因为在windows下编辑的.sh文件编码格式和linux下不一样,转换一下编码格式即可:
dos2unix Cached.sh
关于linux 串口缓存空的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
香港服务器选创新互联,2H2G首月10元开通。
创新互联(www.cdcxhl.com)互联网服务提供商,拥有超过10年的服务器租用、服务器托管、云服务器、虚拟主机、网站系统开发经验。专业提供云主机、虚拟主机、域名注册、VPS主机、云服务器、香港云服务器、免备案服务器等。
当前名称:标题:解决Linux串口缓存空闲问题(linux串口缓存空)
网站URL:http://www.shufengxianlan.com/qtweb/news21/55621.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联