Linux 串口编程二 深入了解 termios

前言

这一系列串口编程重点在应用层编程,但是在讲解原理与相关概念时需要对驱动框架有个基础的认识。如果只是浅尝辄止,以后在遇到串口驱动与应用层程序调试难免遇到瓶颈。关于 tty驱动架构参见我的其他博客:Linux tty驱动程序架构。有时了解下底层以及实现方式对于应用层编程的帮助也是大有裨益的。之前博客讲了终端,tty,控制台等概念以及区别,因此在串口编程相关章节中提及串口,有时也会用终端,tty等来替代,注意它们实际上所指是相同的。

在 Linux 中可以通过一组函数调用(通用终端接口,简称GTI)来控制终端,这组函数调用与用于读写数据的函数是分离的,这就使得读写数据的接口非常简洁,同时又允许可以对终端或串口的行为进行更精细地控制。但由于需要支持大量不同类型的硬件,GTI 中实现的 IO 接口却不简洁。

详解 termios

termios 是在 POSIX 规范中定义的标准接口,它类似与 System V 中的 termio 接口。通过设置 termios 类型的数据结构中的值和使用一小组函数调用,就可以对终端接口进行控制。termios 的结构体定义以及相关函数调用参见 termios.h 头文件。termios 结构的定义如下:


如定义所示,影响终端的参数按照不同模式分成如下几类:

  • 输入模式
  • 输出模式
  • 控制模式
  • 本地模式
  • 线路规程
  • 特殊控制字符
  • 输入速率
  • 输出速率

输入模式

输入模式控制输入数据(终端驱动程序从串行口或键盘接收到的字符)在被传递给程序之前的处理方式。通过设置 termios 结构中 c_iflag 成员的标志对它们进行控制。所有的标志都被定义为宏,这也是所有终端模式都采用的方法。可用于 c_iflag 成员的宏如下所示:

  • BRKINT:当在输入行中检测到一个终止状态(连接丢失)时,产生一个中断。
  • IGNBRK:忽略输入行中的终止状态。
  • ICRNL:将接收到的回车符转换为新行符。
  • IGNCR:忽略接收到的回车符。
  • INLCR:将接收到的新行符转换为回车符。
  • IGNPAR:忽略奇偶校验错误的字符。
  • INPCK:对接收到的字符执行奇偶校验。
  • PARMRK:对奇偶校验错误做出标记。
  • ISTRIP:将所有接收到的字符裁剪为 7 比特位。
  • IXOFF:对输入启动软件流控。
  • IXON:对输出启动软件流控。
如果 BRKINT 和 IGNBRK 标志都未被设置,则输入行中的终止状态就被读取为 NULL 字符。

输出模式

输出模式控制输出字符的处理方式,即由程序发送出去的字符在传递到串行口或屏幕之前是如何处理的。可用于 c_oflag 成员的宏如下所示:

  • OPOST:打开输出处理功能。
  • ONLCR:将输出中的换行符转换为回车/换行符。
  • OCRNL:将输出中的回车符转换为新行符。
  • ONOCR:在第0列不输出回车符。
  • ONLRET:不输出回车符。
  • OFILL:发送填充字符以提供延时。
  • OFDEL:用DEL而不是NULL字符作为填充字符。
  • NLDLY:新行符延时选择。
  • CRDLY:回车符延时选择。
  • TABDLY:制表符延时选择。
  • BSDLY:退格符延时选择。
  • VTDLY:垂直制表符延时选择。
  • FFDLY:换页符延时选择。
如果没有设置 OPOST,其他标志都被忽略,输出模式使用频率较小。

控制模式


控制模式控制终端的硬件特性。通过设置 termios 结构中 c_cflag 标志对控制模式进行配置。可用于 c_cflag 成员宏如下所示:
  • CLOCAL:忽略所有调制解调器的状态行。
  • CREAD:启动字符接收器。
  • CS5:发收采用5位数据位。
  • CS6:发收采用6位数据位。
  • CS7:发收采用7位数据位。
  • CS8:发收采用8位数据位。
  • CSTOPB:字符采用两位停止位。
  • HUPCL:关闭时挂断调制解调器。
  • PARENB:使能奇偶校验。
  • PARODD:使用奇校验。
若设置了 HUPCL,当终端驱动程序检测到与终端对应的最后一个文件描述符被关闭时,它将通过设置调制解调器控制线来挂断线路。控制模式主要用于串行线连接的物理模型中,是在串口编程中十分重要的标志。

本地模式


本地模式控制终端的各种特性。通过设置 termios 结构中 c_lflag 标志对本地模式进行配置。可用于 c_lflag 成员宏如下所示:
  • ECHO:启用输入字符的本地回显功能。
  • ECHOE:接收到 ERASE 时执行退格、空格、退格的动作组合。
  • ECHOK:接收到 KILL 字符时执行行删除操作。
  • ECHONL:回显新行符。
  • ICANON:启用标准输入处理。
  • IEXTEN:启用基于特定实现的函数。
  • ISIG:启用新号。
  • NOFLSH:禁止清空队列。
  • TOSTOP:在试图进行写操作之前给后台进程发送一个信号。
这里最重要的标志是 ECHO 和 ICANON。如果设置了 ICANON 标志,就启用标准输入行处理模式,否则,就启动非标准模式。

特殊控制字符

特殊控制字符是一些字符组合,如 Ctrl+C,当用户键入这样的组合键,终端会采取特殊处理方式。termios 中 c_cc 数组将各种特殊字符映射到对应的支持函数。每个字符位置(数组下标)由对应的宏定义的。根据终端是否被设置为标准模式(即上节提到的 ICANON 标志),数组使用也分为标准与非标准两种情形。

标准模式可以使用的数组下标:

  • VEOF:EOF 字符。
  • VEOL:EOL 字符。
  • VERASE:ERASE 字符。
  • VINTR:INTR 字符。
  • VKILL:KILL 字符。
  • VQUIT:QUIT 字符。
  • VSUSP:SUSP 字符。
  • VSTART:START 字符。
  • VSTOP:STOP 字符。
非标准模式可以使用的数组下标:
  • VINTR:INTR 字符。
  • VMIN:MIN 值。
  • VQUIT:QUIT 字符。
  • VSUSP:SUSP 字符。
  • VTIME:TIME 值。
  • VSTART:START 字符。
  • VSTOP:STOP 字符。
字符的详细解释如下标所示:

字符说明
INTR该字符使终端驱动程序向与终端相连的进程发送 SIGINT 信号
QUIT该字符使终端驱动程序向与终端相连的进程发送 SIGQUIT 信号
ERASE该字符使终端驱动程序删除输入行中的最后一个字符
KILL该字符使终端驱动程序删除整个输入行
EOF该字符使终端驱动程序将输入行中的全部字符传递给正在读取输入的应用程序。若输入行为空,read为0
EOL作用类似于行结束符,效果和常用的新行符相同
SUSP该字符使终端驱动程序向与终端相连的进程发送SIGSUSP信号,用于挂起当前应用程序
STOP字符作用“截流”,即阻止向终端的进一步输出。用于支持 XON/XOFF 流控,通常被设置为 ASCII 的XOFF
START重新启动被 STOP 暂停的输出,通过被设置为 ASCII 的 XON 字符。

VTIME 和 VMIN

TIME值和MIN值只能用于非标准模式,关于二者的使用详见博客:Linux termios 串口编程之 VTIME与VMIN

SHELL下使用 stty 访问终端模式

在 shell 下可以使用 stty 可以访问终端 termios。如:

#打印串口设备 ttyUSB0 设置情况。
root@ubuntu:/# stty -F /dev/ttyUSB0 -a    
#设置 ttyUSB0 为 115200 波特率,8位数据位。
root@ubuntu:/# stty -F /dev/ttyUSB0 ispeed 115200 ospeed 115200 cs8   

在设置成功之后就可以通过 cat、echo 等 shell 命令对设备进行读写了。

本篇重点在于介绍 termios 概念以及详细模式标志位等,大部分是不需要记忆的,使用频率也很低。

关于 Linux 串口编程的其他文章,可以移步至以下链接:

  1. 《Linux 串口编程<一> 一些背景》
  2. 《Linux 串口编程<二> 深入了解 termios》
  3. 《Linux 串口编程<三> 使用termios与API 进行串口程序开发》
  4. 《Linux 串口编程<四> 串口设备程序开发》

如果有其他想法或者疑问可以给我邮件或者评论~:-D



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

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

相关文章

Linux 串口编程四 串口设备程序开发

Linux 串口编程和程序相对来说是很简单的&#xff0c;之所以用博客连载来展示&#xff0c;主要是想在学会使用的基础上掌握相关背景&#xff0c;原理以及注意事项。相信在遇到问题的时候&#xff0c;我们就不会对于技术的概念和 API 的使用浅尝辄止了。下面进入具体应用案例&am…

POSIX 串口编程指南

介绍 POSIX 串口编程指南将教会你在你的 UNIX 工作站或者 PC 上面如何成功、有效以及可移植性的对串口编程。每一章提供了使用 POSIX 终端控制函数的编程例程&#xff0c;可以基本不经修改地工作在 IRIX, HP-UX, SunOS, Solaris, Digital UNIX, Linux 以及其他大多数 UNIX 操作…

快速解决 Android SDK Manager 无法下载或者下载速度慢

在这里以 Windows 下的 Android SDK Manager 为例&#xff0c;其他系统下与此类似&#xff0c;只会存在部分工具栏名称不同的情况&#xff0c;不明之处可以追问。下面就进入具体配置流程&#xff1a; 1. 选择 Tools->Options 进入代理设置。 代理设置选项&#xff0c;在 H…

安卓之USB主机(Host)与配件(Accessory)模式

安卓设备与USB硬件通讯时有两种模式可以选择&#xff1a;USB Host 模式与 USB Accessory 模式。从 USB 逻辑角色来说&#xff0c;USB Host 模式是指安卓设备作为 USB 主机&#xff0c;所有活动均由安卓设备发起&#xff1b;USB Accessory 模式是指安卓设备作为 USB 设备&#x…

安卓USB开发教程 一 USB Host 与 Accessory

安卓通过两种模式&#xff1a;USB Accessory 与 USB Host 模式支持多种 USB 外设与安卓 USB 配件&#xff08;实现安卓配件协议的硬件&#xff09;。在 USB 配件模式下&#xff0c;外部 USB 硬件充当 USB 主机。配件实例可能包含机器人控制器、扩展坞、诊断和音乐设备、售货亭、…

轻松访问 Android 系统源码与下载

有时研究 Android 某个特性或者协议的时候需要参阅安卓系统源代码中代码实现或者协议文档等。通过正常的建立 repo&#xff0c;git 获取十分耗时&#xff0c;并且速度很慢&#xff0c;除非是需要重新编译系统&#xff0c;定制系统才需要这样做。因此&#xff0c;推荐一个 Andro…

Cygwin 下载极速源推荐

Cygwin 默认列表中的源下载速度太慢&#xff0c;国内使用时常用以下几个源&#xff0c;经过实际使用速度很快&#xff0c;下载时不妨几者都尝试下&#xff1a; 如上图所示&#xff0c;下载时在此栏填写 URL 地址即可&#xff0c;推荐地址&#xff1a; http://mirrors.sohu.com…

Java 结构体之 JavaStruct 使用教程二 JavaStruct 用例分析

使用环境 前一篇在介绍 JavaStruct 类时指定了使用库使用环境为 Java 5 及以上&#xff0c;也即开发我们使用的 JDK 版本为1.5及以上就可以了。以下讲解的用例可以直接将 code 直接粘贴到 java 的 main 函数中执行就可以了&#xff0c;后面会给出测试用例和结果。 使用方法 Jav…

Java 结构体之 JavaStruct 使用教程三 JavaStruct 数组进阶

经过前面两篇博客的介绍&#xff0c;相信对于 JavaStruct 的认识以及编程使用&#xff0c;读者已经有一定的基础了。只要理解和实践结合起来&#xff0c;掌握还是很容易的。下面进行一些数组使用方面的实例说明及演示。 在结构体类中使用数组有几种方式&#xff0c;可以使用静…

Android开发如何使用JNA

1. JNA&#xff08;Java Native Access&#xff09;项目已经迁移到 github&#xff0c;最新的项目链接&#xff1a;https://github.com/java-native-access/jna 。首先前往该地址下载使用 JNA 需要的两个 jar 库文件&#xff0c;jna.jar&#xff0c;jna-platform.jar 。 2. 在…

JAVA循环队列

关于自定义循环队列的实现原理和要点可以参见之前的博文系列&#xff1a;循环队列及C语言实现。这里主要对JAVA下的具体实现方式与原理进行说明。 一、JAVA 中已经自带了 Queue、DQueue、ArrayList、LinkedList 等常用的数据结构&#xff0c;为什么还要单独实现循环队列&#…

VMware 虚拟机占用磁盘空间

使用VMware创建的虚拟机尽管已经设定分配的磁盘大小&#xff0c;但仍然会发现虚拟机占用的磁盘空间会越来越大&#xff0c;而直观体现就是虚拟机系统文件 vmdk 不断增大。因此下面介绍一个简单的方法&#xff0c;使用 VMware 自带的工具对 vmdk 文件进行压缩以节省磁盘空间。拿…

frameworks/av/media/CedarX-Projects/CedarAndroidLib/LIB_KK44_/Android.mk: No such file or directory

在安卓系统编译过程中如果遇到上述或者与之类似的错误&#xff0c;可以采取相同的处理方法进行解决。直接进入到 CedarAndroidLib 目录下&#xff0c;也即此例中的 frameworks/av/media/CedarX-Projects/CedarAndroidLib。看一下当前文件&#xff1a; 注意第9行为包含标题中报错…

Windows与Linux下tftp服务的使用

tftp 协议是基于 udp 的&#xff0c;轻量小巧&#xff0c;用在局域网和嵌入式上很顺手。大部分帖子把在 linux 上配置的过程描述的过于复杂&#xff0c;其实只是个工具而已。研究协议抓下包对比协议内容也可以满足需求了&#xff0c;下面进入正文。分别讲下在 linux 以及 windo…

饥荒Mod 开发(二二):显示物品信息

饥荒Mod 开发(二一)&#xff1a;超大便携背包&#xff0c;超大物品栏&#xff0c;永久保鲜 饥荒中的物品没有详细信息&#xff0c;基本上只有一个名字&#xff0c;所以很多物品的功能都不知道&#xff0c;比如浆果吃了也不知道恢复什么&#xff0c; 采集的胡萝卜也不知道什么功…

安卓BLE开发教程(一) BLE基础

我试图以一种简单的方式去把重要的事情讲清楚。目的是希望BLE协议栈和基础概念简单化&#xff0c;让自己及类似的安卓开发者可以在较短的时间内把握住BLE的核心及使用方法。BLE本身很复杂&#xff0c;但对于安卓开发而言只要抓住一些核心点&#xff0c;便已足够。如果你想全面了…

Linux驱动如何在不同版本上快速迭代升级

As well known&#xff0c;Linux内核版本更新很快&#xff0c;有些内核版本的迭代升级可能会导致在使用的驱动版本存在编译失败或使用的兼容性问题&#xff0c;如何快速定位到内核版本间变更的地方&#xff0c;并处理掉该问题&#xff0c;列一下我常用的解决方法。&#xff08;…

苹果MacOS系统上安装第三方驱动失败/无效

近期不少用户在苹果系统上安装一些第三方驱动时反馈没有作用&#xff0c;但是驱动安装提示是完成的&#xff0c;并拷贝到了系统的驱动路径下&#xff1b;造成该问题的原因可参见如下苹果官方说明&#xff1a; User-Approved Kernel Extension Loading 引用下第一段官网说明 …

OpenWrt 之 MT7628 移植第三方SPI驱动

1、在OpenWrt系统上移植SPI驱动前&#xff0c;首先要确保SPI相关引脚未被复用为其他功能&#xff0c;比如GPIO&#xff1b;以下操作已假定该条件成立&#xff0c;否则请修改相关dts和c文件中复用配置&#xff1b; 2、打开dts配置文件进行修改&#xff0c;这里我是用的硬件为WR…

CH9102 USB转串口应用体验

近期使用CH9102 USB转串口芯片成功用在原有使用CP2102的产品板上&#xff0c;整个替换和验证过程还是很顺利的&#xff0c;顺带写个blog做个记录。 原项目上使用CP2102搭载ESP32实现Arduino物联网应用&#xff0c;采用USB转串口芯片实现串口下载&#xff0c;代码的Debug调试&am…