成都网站建设设计

将想法与焦点和您一起共享

Linux串口IO模式的心得有哪些呢

Linux串口IO模式的心得有哪些呢,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

成都创新互联,是一家集策划、设计、技术开发一体的专业互联网产品服务公司,致力于为企业信息化提供驱动力。技术团队十年来致力于为客户提供企业网站定制,移动网站建设。先后服务了上千多家客户,包括各类中小企业、高校、政府。 成都创新互联将利用公司在过去十年的资源积累,力争为客户打造真正革命性的口碑产品!

众所周知,在Linux系统下所有设备都是以文件的形式存在,串口也一样。

通常I/O操作都是有阻塞与非阻塞的两种方式。

其中"超时"这个概念其实是阻塞中的一种处理手段,本质还是属于阻塞的I/O模式.

在Linux中串口的IO操作 本文将它分为三种状态:

  • 阻塞状态

  • 超时状态

  • 非阻塞状态

这三种状态的转换组合有这么几种:

  • 阻塞 --> 超时

  • 阻塞 --> 非阻塞

  • 超时 --> 阻塞

  • 超时 --> 非阻塞

  • 非阻塞 --> 阻塞

我们一个一个来分析

首先在一个串口的描述符打开的时候指定它的模式是阻塞还是阻塞

fd = open("/dev/tttyS0",O_RDWR | O_NOCTTY);//以阻塞模式打开串口  fd = open("/dev/tttyS0",O_RDWR | O_NOCTTY | O_NDELAY);//以非阻塞模式打开串口  //O_NDELAY 等价于 O_NOBLOCK

当一个串口是阻塞状态的时候便可以设置它为超时状态。

利用 struct termios 的 cc_t c_cc[NCCS] 成员

  • c_cc[VTIME] 非规范模式读取时的超时时间(单位:百毫秒)

  • c_cc[VMIN] 非规范模式读取时的最小字符数

如需需要设置超时则c_cc[VMIN] 必须等于0。这代表能够读取的最小字符是0个,即使用read读取数据超时read返回0

有一个需要注意的地方!

当c_cc[VTIME] 设置为 0 且 c_cc[VMIN] == 0 的时候,代表超时0秒(姑且这么叫吧!)这个时候使用read读取数据会立即返回(有读到数据时返回字节数,没有数据和一般超时一样返回0)但是,虽然这时候在现象上看起来和非阻塞模式一样(read都不会阻塞)但返回值不同

非阻塞模式: read没有读到数据立即返回-1

超时0秒时: read没有读到数据立即返回 0 (设置了超时的阻塞模式)

ret = read(fd,recvbuf,BUF_SIZE);  if(ret == -1)//非阻塞模式时"无数据返回"  {  //do something  }  ret = read(fd,recvbuf,BUF_SIZE);  if(ret == 0)//阻塞模式设置超时0秒时"超时返回"  {  //do something  }

虽然表现形式一样,但在编程时必须要了解自己使用的是哪一种模式和串口当前的状态才能更好的分析和处理问题。

这里说一下我曾经遇到过的一个问题:

我在打开串口时使用阻塞模式打开,但是没有设置c_cc[VMIN]的值,而它初始化后就是0,所以发现串口没有被阻塞,其实原因就是串口模式还是阻塞模式没错,但是它是超时0秒的状态,所以在没有数据到达时read也返回了。

阻塞状态和非阻塞状态的切换

非阻塞状态时使用

fcntl(fd,F_SETFL,0);

即可转换成阻塞状态,同样可以设置超时

当非阻塞状态已经设置了超时时,在转换成阻塞状态后超时也随同生效

阻塞状态时使用

fcntl(fd,F_SETFL,FNDELAY);  //FNDELAY等价于FNONBLOCK

即可转换成非阻塞状态,超时失效

这里提一下 fcntl.h中几个宏的定义

/* Define some more compatibility macros to be backward compatible with  BSD systems which did not managed to hide these kernel macros. */  #ifdef __USE_BSD  # define FAPPEND O_APPEND  # define FFSYNC O_FSYNC  # define FASYNC O_ASYNC  # define FNONBLOCK O_NONBLOCK  # define FNDELAY O_NDELAY  #endif /* Use BSD. */

现在一目了然了吧?打开串口时非阻塞模式的O_NDELAY或O_NONBLOCK选项

fcntl设置非阻塞模式的第3个参数FNDELAY或者FNONBLOCK 其实都是O_NONBLOCK主要就是为了兼容

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。


本文标题:Linux串口IO模式的心得有哪些呢
URL地址:http://chengdu.cdxwcx.cn/article/igshhj.html