1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 嵌入式Linux 串口编程系列1——基本知识 termios结构体

嵌入式Linux 串口编程系列1——基本知识 termios结构体

时间:2020-10-10 16:30:14

相关推荐

嵌入式Linux 串口编程系列1——基本知识 termios结构体

对于嵌入式系统开发而言,串口应用编程几乎是使用最 广泛的,应用案例如下:

(1)串口与 外围设备通信,比如串口作为主设备,访问各种仪表从设备,协议一般有自有协议、Modbus通信协议。

(2)开发的设备作为从设备,外部设备通过串口进行相关通信,也比如Modbus通信协议及各种其他 私有协议。

(3)通过串口实现 交互,本质上也是通信,我们使用的shell,最 常见的通信渠道 就是串口。

可以说, 串口几乎是所有嵌入式设备的必备功能。关于串口的硬件层面的相关规定,可以参考之前的文章

《串口的一些基本概念--RS485 RS422 RS232 流控制》

无论在任何的系统环境下开发,串口的配置是必不可少的,包括串口通信参数:波特率、数据位、奇偶校验等,这些都是比较简单的,理解起来也是很容易的,串口配置的难点在于“接收中断”,之所以有这个难点的 原因是在于应用场景,因为所有的应用程序通过串口进行通信,都必然涉及到协议,所谓 协议就是 两个设备之间 对话的 规则,而成功通信的基础就是彼此都遵守通信协议,比如 工业上常用的 Modbus通信协议,主设备A只有发送 符合Modbus通信框架的数据,从设备B才会相应设备A,而从设备B 也需要符合Modbus协议标准,设备A才会认可,进而A、B之间才能成功通信。所以这就带来了一些难点,比如最常见的串口接收数据长度不定,怎么去处理?这个一般是通过固定结束字符、定时器空闲中断、DMA接收中断 等等。

在非linux下进行 串口配置,大多通过配置相应的 控制寄存器来实现,而接收层面,则是通过上面说的,对各种中断的处理,具体场景 具体分析。

在Linux下进行串口的配置,主要是通过 对结构体 termios 进行配置,这个就类似于 上面说的 寄存器,只不过Linxu的开发是采用多级分层的,应用 程序员是不用考虑底层CPU的寄存器的,只需要关注 专用 结构体 termios即可。因为应用层下面还有驱动层,只有驱动工程师才需要解除实际的硬件。

termios结构体

我们通过官方 手册里可以看到, 这个结构体内容如下:

The <termios.h> header shall define the termios structure, whichshall include at least the following members:tcflag_t c_iflagInput modes. tcflag_t c_oflagOutput modes. tcflag_t c_cflagControl modes.tcflag_t c_lflagLocal _tc_cc[NCCS] Control characters.

其中 tcflag_t 是 unsigned short类型,cc_t 是 unsigned char类型,翻译过来如下:

struct termios{unsigned short c_iflag; //输入模式unsigned short c_oflag; //输出模式unsigned short c_cflag; //控制模式unsigned short c_lflag; //本地模式unsigned char c_cc[NCC]; //控制 字符 数据}

1、c_iflag 输入模式控制

该参数如要是 实现 串口接收到的数据 传给应用程序 之前,进行先一步的处理,比如将输入中的 NL 翻译为CR,去掉第8位、忽略帧错误和奇偶校验错误,启用输入 奇偶校验检测等。具体宏定义如下:

INPCK 奇偶校验使能IGNPAR忽略奇偶校验错误PARMRK奇偶校验错误掩码ISTRIP裁剪掉第8比特IXON 启动输出软件控制流IXOF 启动输入软件控制流IXANY 输入任意字符可以重新启动输入(默:起始字符)IGNBRK忽略输入终止条件BRKINT当检测到输入终止条件时发送SIGINT信号INLCR 当收到NL(换行符)转换CR(回车符)IGNCR 忽略收到的CRICRNL 当收到CR转换为NLIUCLC 讲接收到的大写字符映射为小写字符IMAXBEL当输入队列满时响铃

2、c_oflag 输出模式控制

与输入模式控制相对应,负责控制输出单元的处理方式,具体参数宏定义如下:

OPOST启动输出处理功能,如果不设置,其他位忽略OLCUC将输出中的大写字符转换成小写字符ONLCR将输出中的换行符(‘\n’)转换成回车符(‘\r’)ONOCR如果当前列号为0,则不输出回车字符OCRNL将输出中的回车符转换成换行ONLRET不输出回车符OFILL发送填充字符以提供延时OFDEL如果设置该标志,则表示填充字符为DEL字符,否则为NULNLDLY换行延时掩码CRDLY回车延时掩码TABDLY制表符延时掩码BSDLY水平退格符延时掩码VTDLY垂直退格符延时掩码FFLDY换页符延时掩码

3、c_cflag 控制模式标志

该元素主要是 用于控制终端设备的硬件设备,波特率、数据位等,这也是最需要配置的元素,宏定义如下:

CBAUD波特率的位掩码B0 0波特率(放弃DTR)……B18001800的波特率B24002400的波特率B48004800的波特率B96009600的波特率B1920019200的波特率B3840038400的波特率B5760057600的波特率B115200 115200的波特率EXTA 外部时钟率EXTB 外部时钟率CSIZE数据位的位掩码CS5 5个数据位CS6 6个数据位CS7 7个数据位CS8 8个数据位CSTOPB2个停止位(不设置则是一个)GREAD接收使能PARENB校验使能位PARODD使用奇校验而不是偶校验HUPCL最后关闭时挂线(放弃DTR)CLOCAL本地连接(不改变端口所有者)CRTSCTS 硬件流控

4、c_lflag 本地控制模式

ISIG若收到信号字符(INTR,QUIT等)则会产生相应的信号ICANON 启动规范模式ECHO启动本地回显功能ECHOE若设置ICANON则允许退格操作ECHOK若设置ICANON,则KILL字符会删除当前行ECHONL 若设置ICANON,则允许回显换行符ECHOCTL 若设置ECHO,则控制字符会显示成^x,其中x的ASCII码等于给相应的控制字符的ASCII码加上0x40.ECHOPRT 若设置ICANON和IECHO,则删除字符和被删除的字符都会被显示ECHOKE 若设置ICANON,则允许回显在ECHOE和ECHOPRT中设定的KILL字符NOFLASH 在通常情况下,当接收到INTR,QUIT,SUSP控制字符时,会清空输入和输出队列。如果设置改标志,则所有的队列不会被清空TOSTOP 若一个后台进程师徒向他的控制终端进行写操作,则系统向改后台进程的进程组发送SIGTTOU 该信号通常终止进程的执行IEXTEN 启动输入处理功能

5、c_cc 数组:特殊控制字元可提供使用者设定一些特殊的功能,定义如下:

VINTR 中断控制字符,对应的键位ctrl+cVQUIT 退出操作符,对应的键为ctrl+zVERASE 删除操作符,对应BackspaceVKILL 删除行符,对应的键为ctrl+uVEOF 文件结尾符,对应的键为ctrl+dVEOL 附加行结尾符,对应的键为carriage returnVEOL2 第二行结尾符,对应的键为line feedVMIN 指定最少读取的字符数VTIME 指定读取的每个字符之间的超时时间

这里面,最常用的是VMIN和VTIME,

VMIN 指定了 串口至少要读取VMIN个字符,才会不阻塞,也就是 串口接收超过VMIN个字符,read函数才会有返回,

使用该功能,可以实现 定长 数据的接收。

VTIME 指定了字符超时,也就是需要等待几百毫秒的值,read才会返回,单位是100ms,

VMIN和VTIME的组合,可以实现特定接收 处理,关系如下:

VMIN = 0 和 VTIME = 0 :在这种情况下,read 调用总是立刻返回。如果有等待处理的字符,read 就会立刻返回;如果没有字符等待处理,read 调用返回0,并且不读取任何字符;VMIN = 0 和 VTIME > 0 :在这种情况下,只要有字符可以处理或者是经过 VTIME 个十分之一秒的时间间 隔,read 调用就返回。如果因为超时而未读到任何字符,read 返回0,否则 read 返回读取的字符数目。VMIN > 0 和 VTIME = 0 :在这种情况下,read 调用将一直等待,直到有 MIN 个字符可以读取时才返回,返回值是读取的字符数量。到达文件尾时返回0。VMIN > 0 和 VTIME > 0 :在这种情况下,当 read 被调用时,它会等待接收一个字符。在接收到第一个字符及后续的每个字符后,一个字符间隔定时器被启动(如果定时器已经运行,则重启它)。当有 MIN 个字符可读或两个字符之间的时间间隔超过 TIME 个十分之一秒时,read 调用返回。这个功能可用于区分是单独按下了 Escape 键还是按下一个 Escape 键开始的功能组合键。但要注意的是,网络通信或处理器的高负载将使得类似这样的定时器失去作用。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。