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

(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_iflag     Input modes.   tcflag_t  c_oflag     Output modes.  tcflag_t  c_cflag     Control modes.tcflag_t  c_lflag     Local modes.cc_t      c_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                 忽略收到的CR
ICRNL                 当收到CR转换为NL
IUCLC                 讲接收到的大写字符映射为小写字符
IMAXBEL               当输入队列满时响铃

2、 c_oflag 输出模式控制

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

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

3、 c_cflag 控制模式标志

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

CBAUD                波特率的位掩码
B0                   0波特率(放弃DTR)
…
…
B1800                1800的波特率
B2400                2400的波特率
B4800                4800的波特率
B9600                9600的波特率
B19200               19200的波特率
B38400               38400的波特率
B57600               57600的波特率
B115200              115200的波特率
EXTA                 外部时钟率
EXTB                 外部时钟率
CSIZE                数据位的位掩码
CS5                  5个数据位
CS6                  6个数据位
CS7                  7个数据位
CS8                  8个数据位
CSTOPB               2个停止位(不设置则是一个)
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+c
VQUIT            退出操作符,对应的键为ctrl+z
VERASE           删除操作符,对应Backspace
VKILL            删除行符,对应的键为ctrl+u
VEOF             文件结尾符,对应的键为ctrl+d
VEOL             附加行结尾符,对应的键为carriage return
VEOL2            第二行结尾符,对应的键为line feed
VMIN             指定最少读取的字符数
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 键开始的功能组合键。但要注意的是,网络通信或处理器的高负载将使得类似这样的定时器失去作用。

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

  1. 嵌入式Linux 串口编程系列2--termios的VMIN和VTIME深入理解

    在上一篇文章中,我们介绍了串口的一些基本知识.串口配置接口 termios结构体的概念,串口的配置参数有n多个,这里面不用都背下来,什么时候使用,翻看手册即可,但是有两个 参数是一定要理解的,就是VM ...

  2. 嵌入式Linux 串口编程系列3——通过VTIM、VMIN、select实现串口不定长数据接收功能

    上一篇文章中,我们详细分析了VTIM和VMIN的功能, <嵌入式Linux 串口编程系列2--termios的VMIN和VTIME深入理解> 也明白了这两个参数设计的初衷和使用方法,接下来 ...

  3. 嵌入式Linux 串口编程系列4——EasyARM287开发板通过freemodbus实现Modbus通信

    前面的文章分析了串口的一些基本知识,在工业应用中,串口通信比较常用的协议就是Modbus RTU,freemodbus是一款微型modbus协议栈,之前对各种单片机.小型处理器支持的比较好,从V1.6 ...

  4. [Linux网络编程]以太网封装格式及相关结构体

    木草山人声明: 本文非教学资料,不涉及理论.文章只是个人的一些笔记,其中的对与错,我不清楚,因为都是从书上.资料中学到的.虽然做过实践测试,但不保证100%正确.能力有限,错误难免,欢迎指正. 以太网 ...

  5. Linux串口编程(中断方式和select方式)

    Linux下的串口编程,在嵌入式开发中占据着重要的地位,因为很多的嵌入式设备都是通过串口交换数据的.在没有操作系统的我们可以使用UART的中断来出来数据的接受和发送,而在Linux操作系统下,我们也可 ...

  6. 七、Linux串口编程

    相关程序代码和资源我都已经给大家打包好了.可以到https://download.csdn.net/download/qq_28938511/13080045下载. 不方便下载的,可以给我留言,我直接 ...

  7. 【分享】4412开发板-嵌入式Linux开发须要掌握的基础知识和技能

    本文转自迅为电子论坛:http://www.topeetboard.com 1.Linux 基础 安装Linux操作系统 Linux文件系统 Linux经常使用命令 Linux启动过程具体解释 熟悉L ...

  8. I.MX6U嵌入式Linux应用编程学习

    I.MX6U嵌入式Linux应用编程学习 目录 I.MX6U嵌入式Linux应用编程学习 〇.备忘 0.0 本文大写字母缩写说明 0.1 C编译 0.2 NFS与文件夹挂载 一.应用编程概念 1.1 ...

  9. 嵌入式Linux的OTA更新,基础知识和实现

    嵌入式Linux的OTA更新,基础知识和实现 OTA updates for Embedded Linux, Fundamentals and implementation 更新的需要 一旦嵌入式Li ...

最新文章

  1. OSSIM系统——mysql的使用
  2. 上海网络推广为大家讲解细节标签能给网站带来的作用与效果!
  3. ajax get时不能更新页面的解决方法
  4. java中sql语句怎么把开始和结束时间作为参数写sql查询_聊一聊MyBatis 和 SQL 注入间的恩恩怨怨
  5. mysql索引缓存的内容_mysql服务器变量、缓存及索引
  6. MySQL深入02-DML之Select查询
  7. MIT App Inventor使用与入门教程
  8. jQuery 选择器、DOM操作、事件、动画
  9. ping IP简单应用,查找故障
  10. adb脚本选择语句_Python开发:王者荣耀自动刷金币脚本
  11. HarmonyOS官网壁纸图片,华为鸿蒙系统HarmonyOS目前收集到的壁纸分享
  12. 测试如何进行有效的需求分析
  13. h5学习笔记 左右布局
  14. 基于Matlab的简单视频处理
  15. 家用nas存储,家庭个人云推荐
  16. java 自动识别邮箱服务器类型_Java实现通过smtp服务器验证邮箱的真实有效性
  17. AR Foundation
  18. 基于stm32f10x的超声波模块HC-SR04的测距示例,并用串口将数据打印出来
  19. Google Play游戏服务入门
  20. Android快速入门(一):Android介绍

热门文章

  1. 5G NR CSI-RS介绍(1)-- 物理时频资源映射
  2. 汉字转16进制 php,PHP实现中文汉字与16进制编码转换
  3. 全球前10大数据库产品厂家
  4. 考试排名(结构体专题)
  5. Node抓取有道精品课视频
  6. 使用 PyTorch 检测眼部疾病
  7. win7如何启用计算机的无线功能,win7如何开启无线功能
  8. jfinal的简单使用(一)
  9. PS 2021安装插件提示”无法加载,未经签署“怎么办?ps2021插件未经正确签署解决办法!
  10. 音视频基础知识-时间戳的理解