Linux 使用fcntl c_cc[VMIN] c_cc[CTIME]设置串口阻塞与非阻塞读取数据

一、概述

Linux串口非常灵活,可以根据需要配置成标准串口和自定义串口模式,就Linux 串口读取数据来说,有有两种主要方式:阻塞与非阻塞。

  1. 阻塞:一直等待数据,直到退出条件成立;
  2. 非阻塞:及时返回当前数据,不管有无均退出。

这里的退出条件有数据等待时间间隔、需要读取的字节数等。例如,有以下两种串口场景使用场景,请进行配置:

  1. 非阻塞方式,及时返回当前完整数据包。
  2. 固定200ms的时间等待串口返回数据,超时退出。

二、配置方法

Linux 用命令F_GETFL和F_SETFL设置文件标志(set file flag), O_ACCMODE、O_RDONLY、O_WRONLY、O_RDWR、O_CREAT、O_APPEND、O_NONBLOCK如阻塞与非阻塞、O_NDELAY是否延迟、O_SYNC与O_ASYNC同步与异步等。

在串口初始化的驱动程序中,先采用open打开串口,再采用fcntl的方式进行配置串口模式。

因此,阻塞和非阻塞可以用fcntl设定其是否加O_NONBLOCK来说明。

其中,阻塞情况下,可以采用 c_cc[VTIME] 与 c_cc[VMIN] 进行限定。

  • c_cc[VTIME] 非规范模式读取时的超时时间(单位:0.1秒),从接收到最后一个字节开始计时,如果超时,则退出READ
  • c_cc[VMIN]  非规范模式读取时的最小字符数,设为0则为非阻塞,如果设为其它值则阻塞,直到读到到对应的数据

需要说明的是,VMIN与VTIME设置的值不同会影响fcntl是否阻塞。

例如以下几种情景:

/*  配置1 非阻塞方式
fcntl (fd, F_SETFL, O_NONBLOCK) ;
,,,;
option.c_cc[VMIN]  = n;
option.c_cc[VTIME] = m;

配置1 设置了O_NONBLOCK 无论VMIN和CTIME 都处于非阻塞,即接收数据不完整,需要拼帧。

/*  配置2 非阻塞方式 n = 0 m > 0
fcntl (fd, F_SETFL, O_RDWR) ;
,,,;
option.c_cc[VMIN]  = n;
option.c_cc[VTIME] = m;

配置2 不设置O_NONBLOCK,设置VMIN = 0, 从接收到第一个字节开始启动定时器,每收到一个字节刷新定时器,直到定时器超时,返回接收到的所有字节数;如果没有收到第一个字节,则一直阻塞等待。

/*  配置3 阻塞方式 n != 0 m > 0
fcntl (fd, F_SETFL, O_RDWR) ;
,,,;
option.c_cc[VMIN]  = n;
option.c_cc[VTIME] = m;

配置3 这种情况的数据接收由VMIN和VTIME决定,当接收的数据长度达到VMIN的值时,会按照接收缓存当前的最小数据包返回。

  • 当串口发送数据是40字节,VMIN设置10,VTIME设置5,则read函数返回的长度是16、16、8(树莓派环境下)。
  • 当串口发送数据是40字节,VMIN设置100,VTIME设置5,则read函数返回的长度是40(树莓派环境下)。

当接收的数据长度没有达到VMIN设置的值,则从接收的最后一字节开始等待VTIME时间,超时退出read。因此,可以将VMIN值设大,然后分配一个合适的VTIME时间即可实现阻塞读取数据。

/*  配置4 阻塞方式 n != 0 m = 0
fcntl (fd, F_SETFL, O_RDWR) ;
,,,;
option.c_cc[VMIN]  = n;
option.c_cc[VTIME] = m;

在配置3的基础上,改一下m=0,变成长时间等待,直到数据达到VMIN设定值。

三、具体操作

那么上述的两个场景可以按照如下方式进行操作。

3.1 非阻塞配置方法:用O_NONBLOCK非阻塞配置。

  if ((fd = open (device, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY)) == -1)return -1 ;fcntl (fd, F_SETFL, O_NONBLOCK) ;

非阻塞模式下的调用read函数读取串口内容,存在数据分包的情况,因为它立即返回当前接收缓存中的内容,并非当前数据帧,实际测试发现数据是按照8字节为最小的完整缓存。因此需要对非阻塞模式下的数据进行拼包处理。

int size_i,i;i = 0;size_i = 0;while(1){i = read(fd, buf+size_i ,1024);size_i += i;if(i == 8){//NONE }else if(i>0 && i <= 8){*size = size_i;return 0;}else{return -1;}}

采用非阻塞方式的好处是无需提前知道数据的大小和数据帧的间隔,收到数据拼包即是一帧数据,但是需要一直查询。

3.1 阻塞配置方法

从前变的代码看出 fcntl 默认是采用阻塞,需要非阻塞用O_NONBLOCK配置。因此,阻塞时将O_NONBLOCK设置为其他即可,例如O_RDWR可读可写,或者直接设置成0. 然后配置option.c_cc[VMIN] 和 option.c_cc[VTIME] ,这里配置VMIN的值大一些,这样可以有VTIME决定超时时间,例如配置VMIN=1024,VTIME=0.1s。

  if ((fd = open (device, O_RDWR) == -1)return -1 ;,,,option.c_cc[VMIN]  = 1;option.c_cc[VTIME] = 1;,,,
//serial fifo=8byte 因此非阻塞模式下也需要拼帧 
int serialDataRead( char *buf,  int * size)
{int size_i,i;i = 0;size_i = 0;while(1){i = read(gsfd, buf+size_i ,1024);if( i < 0){return -1;}else{size_i += i;if((i < 8 && size_i != 0)||(size_i == 1024)){*size = size_i;return 0;}}}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/405427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS3选择器(二)--表单

:enabled 选择可用状态的表单元素 :disabled 选择不可用状态的表单元素 :checked 复选框、单选框选中状态的选项 ::selection 用来匹配突出显示的文本(用鼠标选择文本时的文本)。 :read-only 用来指定处于只读状态元素的样式.即元素中设置了“readonly’readonly’” :read…

Linux Shell 通配符、元字符、转义符使用实例介绍

From: http://www.cnblogs.com/chengmo/archive/2010/10/17/1853344.html 说到shell通配符&#xff08;wildcard&#xff09;&#xff0c;大家在使用时候会经常用到。下面是一个实例&#xff1a; ?1?1234[chengmolocalhost ~/shell]$ lsa.txt b.txt c.old#2?1234[chengmo…

ant design model实现图片预览

代码部分 <divgutter{16}style{{width: 100%,display: flex,justifyContent: space-between,flexWrap: wrap ,}}>{detailMsg.imgList &&detailMsg.imgList.map((item, index) > (<div style{{ width: 30% }} key{index} onClick{() > this.handleClick(…

VMware Workstation Pro 无法在Windows 上运行的 解决办法

一、问题描述 国庆期间window10来了一次更新&#xff0c;导致VMware Workstation 无法在windows上运行&#xff0c;我的虚拟机版本是VMware Pro14。有两种方法解决该问题&#xff0c;第一种是直接卸载新安装的windows安装包&#xff0c;然后重启。第二种方式是升级VMware到最新…

机器学习之深度学习

本文基于台大机器学习技法系列课程进行的笔记总结。 一、主要内容 topic 1 深度神经网络结构 从类神经网络结构中我们已经发现了神经网络中的每一层实际上都是对前一层进行的特征转换&#xff0c;也就是特征抽取。一般的隐藏层&#xff08;hidden layer&#xff09;较少的类神…

sockaddr和sockaddr_in的区别

From: http://www.it165.net/pro/html/201211/4066.html 初学者很容易对二者有困惑的感觉&#xff0c;下面来讲一下二者的区别。 sockaddr是在头文件 /usr/include/bits/socket.h 中定义的&#xff0c;如下&#xff1a; view sourceprint?1.struct sockaddr2.{3.__SOCKADDR_C…

[react] 什么时候使用状态管理器?

[react] 什么时候使用状态管理器&#xff1f; 1用户的使用方式复杂 2.不同身份的用户有不同的使用方式&#xff08;比如普通用户和管理员&#xff09; 3.多个用户之间可以协作 4.与服务器大量交互&#xff0c;或者使用了WebSocket 5.View要从多个来源获取数据 从组件角度看 1.…

FlexViewer2.3中拉帘Widget下载

http://www.giser.net/?p280 由于最新的ArcGIS API for flex2.x使用了Flex SDK4&#xff0c;因此造成了对之前ArcGIS API for flex1.x制 作的拉帘Widget无法使用&#xff0c;因此重新制作了拉帘工具供大家使用。 下载地址&#xff1a; Swipe 使用方法&#xff1a;将下载后的sw…

scanf sscanf 的用法

一、scanf函数 scanf() - 以屏幕(stdin)为输入源&#xff0c;提取输入指定格式的数据&#xff0c;返回提取的数据个数。 函数原型:int scanf( const char *format [,argument]... ); 二、sscanf函数 sscanf() - 从一个字符串中读进与指定格式相符的数据&#xff0c;非常适合…

spring ioc原理

IOC&#xff08;DI&#xff09;&#xff1a;java程序员都知道&#xff1a;java程序中的每个业务逻辑 至少需要两个或以上的对象来协作完成&#xff0c;通常&#xff0c;每个对象在使用他的合作对象时&#xff0c;自己均要使用像new object&#xff08;&#xff09; 这样的语法来…

五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O

From: http://blog.163.com/xychenbaihuyeah/blog/static/13222965520112163171778/ 五种I/O 模式&#xff1a; 【1】 阻塞 I/O (Linux下的I/O操作默认是阻塞I/O&#xff0c;即open和socket创建的I/O都是阻塞I/O) 【2】 非阻塞 I/O (可以通过f…

【hive】Hive中的大宽表及其底层详细技术点

简介: 在大数据环境中&#xff0c;处理大规模数据集是常见的需求。为了满足这种需求&#xff0c;Hive引入了大宽表&#xff08;Large Wide Table&#xff09;的概念&#xff0c;它是一种在Hive中管理和处理大量列的数据表格。本文将详细介绍Hive中的大宽表概念以及其底层的详细…

[react] render函数中return如果没有使用()会有什么问题?

[react] render函数中return如果没有使用()会有什么问题&#xff1f; 我们在使用JSX语法书写react代码时&#xff0c;babel会将JSX语法编译成js&#xff0c;同时会在每行自动添加分号&#xff08;&#xff1b;&#xff09;&#xff0c;如果return后换行了&#xff0c;那么就会…

小程序tabbar文字在服务器上不显示,小程序的tabbar不显示

1. tabbar 不显示刚开始给页面加tabbar时{"pages":["pages/index/index","pages/all/all","pages/relax/relax","pages/me/me","pages/wen/wen","pages/logs/logs"],"window":{"backgro…

Linux fprintf的用法

一、fprintf 函数描述 fprintf其作用是格式化打印&#xff0c;也叫格式化输出&#xff0c;可以指定输出到一个流文件中&#xff0c;即相输出流中写入数据。fprintf()函数根据指定的格式(format)&#xff0c;向输出流(stream)写入数据(argument)。fprintf( )会根据参数format 字…

2015 7 18

ExecuteNonQuery返回的是受影响的行数ExecuteScalar返回的是第一行第一列的值 制作密码找回的冻结功能 一个变量 当点击提交密码问题答案时1 达到3次时 数据库中的时间项纪录为当前时间 返回首页 执行找回密码操作时 点击下一步 先进行判定 如果用户名存在 其当前日期-冻…

windows组件向导里没有internet 信息服务(iis) 的解决办法

From: http://blog.163.com/red419126/blog/static/18862284200882155215627/ 电脑要重装系统&#xff0c;借同事的xp光盘&#xff0c;一切顺利。却发现这个新系统添加删除组件向导里没有iis了。怎么办呢&#xff1f; 在运行中输入"c:\windows\inf\sysoc.inf"&…

Linux tm time_t timeval timespec以及与时间相关函数用法

一、时间类型 linux中编程通常需要用到时间变量&#xff0c;和相关的时间操作函数。常用的时间类型有&#xff1a; time_t 、struct timeval、struct timespec、struct tm。 在用到相关的类型和函数时&#xff0c;需要加上头文件&#xff1a;#include <time.h> …

Apache的prefork模式和worker模式

prefork模式 这个多路处理模块(MPM)实现了一个非线程型的、预派生的web服务器&#xff0c;它的工作方式类似于Apache 1.3。它适合于没有线程安全库&#xff0c;需要避免线程兼容性问题的系统。它是要求将每个请求相互独立的情况下最好的MPM&#xff0c;这样若一个请求出现问题就…

[react] 说说Context有哪些属性?

[react] 说说Context有哪些属性&#xff1f; context属于一种解决组件间层级过多传递数据的问题&#xff0c;避免了层层嵌套的通过props传递的形式&#xff0c;同时对于不需要使用到redux时&#xff0c;是一种解决方案&#xff0c;关于组件的复用性变差的问题&#xff0c;我觉…