为什么你的串口总是丢一些特殊字符?

描述

导读

在嵌入式开发和物联网应用中,Linux系统的串口通信至关重要。本文将简单介绍Linux下串口设备的命名规则和termios结构体,并解析终端的三种工作模式,帮助开发者更好地掌握Linux串口编程。

Linux下串口设备名称一般为 "/dev/ttySn",n是数字,若串口是 USB 扩展的,则串口设备文件命名多为/dev/ttyUSBn。串口是一个终端设备,在Linux中用 termios结构体来描述:

  •  
  •  
  •  
  •  
  •  
  •  
  •  

 struct termios {    tcflag_t c_cflag;            /* 控制标志 */        tcflag_t c_iflag;            /* 输入标志 */        tcflag_t c_oflag;            /* 输出标志 */        tcflag_t c_lflag;            /* 本地标志 */        tcflag_t c_cc[NCCS];         /* 控制字符 */  };

termios是在POSIX规范中定义的标准接口,表示终端设备(包括虚拟终端,串口等)。终端有 3 种工作模式,分别为规范模式(canonical mode)、非规范模式(non-canonical mode)和原始模式(raw mode)。

c_lflag 中设置 ICANNON 标志来定义终端的三种模式:规范模式、非规范模式和原始模式。

1. 规范模式

规范模式下所有的输入都是基于行进行处理的。在用户输入一个行结束符(回车符、EOF等)之前,系统调用read()函数读不到用户输入的任何字符。除了EOF之外的行结束符(回车符等)和普通字符一样都会被read()函数读取到缓冲区之中。在规范模式中,行编辑是可行的,而且一次调用read()函数最多只能读取一行数据。 

2. 非规范模式

非规范模式所有的输入是即时有效的,不需要用户另外输入行结束符,而且不可进行行编辑。在非规范模式下,对参数 MIN(c_cc[VMIN])和 TIME(c_cc[VTIME])的设置决定read()函数的调用方式。设置可以有 4 种不同的情况。

  • VMIN=0和VTIME=0:read() 函数立即返回。若有可读数据,则读取数据并返回被读取的字节数,否则读取失败并返回0。
  • VMIN > 0 和 VTIME = 0:read()函数会被阻塞直到 VMIN 个字节数据可被读取。
  • VMIN = 0 和 VTIME > 0: 只要有数据可读或者经过VTIME 个1/10秒的时间,read()函数则立即返回, 返回值为被读取的字节数。如果超时并且未读到数据, 则 read()函数返回0。
  • VMIN > 0 和 VTIME > 0: 当有VMIN 个字节可读或者两个输入字符之间的时间间隔超过VTIME个1/10秒时,read()函数才返回。因为在输入第一个字符之后系统才会启动定时器,所以在这种情况下,read()函数至少读取一个字节之后才返回。

3. 原始模式

原始模式是一种特殊的非规范模式。在原始模式下,所有的输入数据以字节为单位被处理。在这个模式下,终端是不可回显的,而且所有特定的终端输入/输出控制处理不可用。通过调用 cfmakeraw()函数可以将终端设置为原始模式。
 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分