termios是在Posix规范中定义的标准接口,表示终端设备(包括虚拟终端、串口等)。因为串口是一种终端设备,所以通过终端编程接口对其进行配置和控制。
A、termios结构体
1 | struct termios |
1. c_iflag 标志常量:Input mode (输入模式)
input mode可以在输入值传给程序之前控制其处理的方式。
1 | /* c_iflag bits */ |
2. c_oflag 标志常量:Output mode (输出模式)
Output mode主要负责控制输出字元的处理方式。
1 | /* c_oflag bits */ |
3. c_cflag 标志常量:Control mode ( 控制模式)
Control mode主要用于控制终端设备的硬件设置。利用termios结构的c_cflag的标志来加以控制。
1 | /* c_cflag bit meaning */ |
4. c_lflag 标志常量:Local mode (局部模式)
Local mode主要用来控制终端设备不同的特色。利用termios结构里的c_lflag的标志来设定局部模式。
1 | /* c_lflag bits */ |
5. c_cc 数组:特殊控制字元可提供使用者设定一些特殊的功能
特殊控制字元主要是利用termios结构里c_cc的阵列成员 来做设定。
1 | /* c_cc characters */ |
6. 其他
1 | /* tcflow() and TCXONC use these */ |
B. 相关函数
1. tcgetattr
1 | /* Put the state of FD into *TERMIOS_P. */ |
取得终端介质(fd)初始值,并把其值 赋给temios_p;函数可以从后台进程中调用;但是,终端属性可能被后来的前 台进程所改变。
2. tcsetattr
1 | /* Set the state of FD to *TERMIOS_P. |
设置与终端相关的参数 (除非需要底层支持却无法满足),使用termios_p 引用的 termios 结构。optional_actions (tcsetattr函数的第二个参数)指定了什么时候改变会起作用:
- TCSANOW:改变立即发生
- TCSADRAIN:改变在所有写入 fd 的输出都被传输后生效。
- TCSAFLUSH :改变在所有写入 fd 引用的对象的输出都被传输后生效,所有已接受但未读入的输入都在改变发生前丢弃
3. tcsendbreak
1 | /* Send zero bits on FD. */ |
传送连续的 0 值比特流,持续一段时间,如果终端使用异步串行数据传输的话。如果 duration 是 0,它至少传输 0.25 秒,不会超过 0.5 秒。如果duration 非零,它发送的时间长度由实现定义。如果终端并非使用异步串行数据传输,tcsendbreak() 什么都不做。
4. tcdrain
1 | /* Wait for pending output to be written on FD. |
等待直到所有写入 fd 引用的对象的输出都被传输。
5. tcflush
1 | /* Flush pending data on FD. |
丢弃要写入引用的对象,但是尚未传输的数据,或者收到但是尚未读取的数据,取决于 queue_selector 的值:
- TCIFLUSH:刷新收到的数据但是不读
- TCOFLUSH:刷新写入的数据但是不传送
- TCIOFLUSH:同时刷新收到的数据但是不读,并且刷新写入的数据但是不传送
6. tcflow
1 | /* Suspend or restart transmission on FD. |
挂起 fd 引用的对象上的数据传输或接收,取决于 action 的值:
- TCOOFF :挂起输出
- TCOON :重新开始被挂起的输出
- TCIOFF :发送一个 STOP 字符,停止终端设备向系统传送数据
- TCION :发送一个 START 字符,使终端设备向系统传输数据打开一个终端设备时的默认设置是输入和输出都没有挂起。
7. 波特率函数
被用来获取和设置 termios 结构中,输入和输出波特率的值。新值不会马上生效,直到成功调用了 tcsetattr() 函数。设置速度为 B0 使得 modem “挂机”。与 B38400 相应的实际比特率可以用setserial(8) 调整。 输入和输出波特率被保存于 termios 结构中。
1 | /* Return the output baud rate stored in *TERMIOS_P. */ |
- cfgetospeed() 返回 termios_p 指向的 termios 结构中存储的输出波特率
- cfgetispeed() 返回 termios结构中存储的输入波特率
- cfsetospeed() 设置 termios_p 指向的 termios 结构中存储的输出波特率为speed
- cfsetispeed() 设置 termios 结构中存储的输入波特率为 speed
8. 返回值
cfgetospeed()、cfgetispeed() 返回 termios 结构中存储的输入波特率。
其他函数返回 0-成功;-1-失败,并且为 errno 置值来指示错误。
C. 实例:串口
串口是计算机上一种非常通用设备通信的协议,常用PC机上包含的是RS232规格的串口,具有连接线少,通讯简单,得到广泛的使用。
Linux对所有设备的访问是通过设备文件来进行的,串口也是这样,为了访问串口,只需打开其设备文件即可操作串口设备。在linux系统下面,每一个串口设备都有设备文件与其关联,设备文件位于系统的/dev目录下面。如linux下的/ttyS0,/ttyS1分别表示的是串口1和串口2。
在串口编程中,比较重要的是串口的设置,需要设置的部分包括:波特率,数据位,停止位,奇偶校验位
1 | /* stty.h 头文件*/ |
1 | /* stty.c 源码*/ |
D. 实例:非堵塞按键监听
1 | //用非阻塞io |