本文共 3347 字,大约阅读时间需要 11 分钟。
详细解析termios结构体及其操作函数
termios结构体是终端设备操作中常用的数据结构,该结构体定义了终端设备操作的各种控制参数。termios结构体的成员主要用于描述终端输入和输出模式、控制功能等设置。以下将逐步分析termios结构体及其相关操作函数。
termios结构体的成员分析
termios结构体的成员主要包括c_iflag、c_oflag、c_cflag、c_lflag和cc_t类型的成员c_cc[NCCS]。每个成员都有特定的意义:
c_iflag(输入模式标志)c_iflag用于控制终端的输入模式。其具体参数包括:
- IGNBRK:忽略BREAK键输入
- BRKINT:如果设置了IGNBRK,BREAK键的输入将被忽略。如果设置了BRKINT,将产生SIGINT中断
- IGNPAR:忽略奇偶校验错误
- PARMRK:标识奇偶校验错误
- INPCK:允许输入奇偶校验
- ISTRIP:去除字符的第8个比特
- INLCR:将输入的NL(换行)转换成CR(回车)
- IGNCR:忽略输入的回车
- ICRNL:将输入的回车转化成换行(如果IGNCR未设置的情况下)
- IUCLC:将输入的大写字符转换成小写字符(非POSIX)
- IXON:允许输入时对XON/XOFF流进行控制
- IXANY:输入任何字符将重启停止的输出
- IXOFF:允许输入时对XON/XOFF流进行控制
- IMAXBEL:当输入队列满的时候开始响铃。Linux在使用该参数时认为该参数总是已经设置
c_oflag(输出模式标志)c_oflag用于控制终端的输出模式。其具体参数包括:
- OPOST:处理后输出
- OLCUC:将输入的小写字符转换成大写字符(非POSIX)
- ONLCR:将输入的NL(换行)转换成CR(回车)及NL(换行)
- OCRNL:将输入的CR(回车)转换成NL(换行)
- ONOCR:第一行不输出回车符
- ONLRET:不输出回车符
- OFILL:发送填充字符以延迟终端输出
- OFDEL:以ASCII码的DEL作为填充字符(非POSIX)。如果未设置该参数,填充字符将是NUL(‘\0’)
- NLDLY:换行输出延时。可能取值为NL0(不延迟)或NL1(延迟0.1s)
- CRDLY:回车延迟。取值范围为CR0、CR1、CR2和CR3
- TABDLY:水平制表符输出延迟。取值范围为TAB0、TAB1、TAB2和TAB3
- BSDLY:空格输出 延迟。可能取值为BS0或BS1
- VTDLY:垂直制表符输出延迟。可能取值为VT0或 VT1
- FFDLY:换页延迟。可能取值为FF0或FF1
c_cflag(控制模式标志)c_cflag用于控制终端的硬件模式。其具体参数包括:
- CBAUD:波特率(4+1位)(非POSIX)
- CBAUDEX:附加波特率(1位)(非POSIX)
- CSIZE:字符长度。取值范围为CS5、CS6、CS7或CS8
- CSTOPB:设置两个停止位
- CREAD:使用接收器
- PARENB:使用奇偶校验
- PARODD:对输入使用奇偶校验,对输出使用偶校验
- HUPCL:关闭设备时挂起
- CLOCAL:忽略调制解调器线路状态
- CRTSCTS:使用RTS/CTS流控制
c_lflag(本地模式标志)c_lflag用于控制终端的编辑功能(本地模式)。其具体参数包括:
- ISIG:当输入INTR、QUIT、SUSP或DSUSP时,产生相应的信号
- ICANON:使用标准输入模式
- XCASE:在ICANON和XCASE同时设置的情况下,终端只使用大写字符。如果只设置了XCASE,则输入字符将被转换为小写字符(除非字符使用了转义字符,非POSIX,且Linux不支持该参数)
- ECHO:显示输入字符
- ECHOE:如果ICANON同时设置,ERASE将删除输入的字符,WERASE将删除输入的单词
- ECHOK:如果ICANON同时设置,KILL将删除当前行
- ECHONL:如果ICANON同时设置,即使ECHO没有设置仍然显示换行符
- ECHOPRT:如果ECHO和ICANON同时设置,将删除打印出的字符(非POSIX)
- TOSTOP:向后台输出发送SIGTTOU信号
termios结构体的相关函数
tcgetattr()函数原型:int tcgetattr(int fd, struct termios *termios_p); 功能:取得终端介质(fd)初始值,并将其值赋给termios_p。该函数可以从后台进程中调用。但需要注意的是,终端属性可能会被后续的前台进程所修改。
- tcsetattr()函数原型:int tcsetattr(int fd, int actions, const struct termios *termios_p);
功能:设置与终端相关的参数。optional_actions 参数决定了什么时候会生效。
- TCSANOW:立即生效
- TCSADRAIN:在所有写入操作完成后才生效。通常用于修改影响输出的参数
- TCSAFLUSH:在所有写入操作完成后才生效。同时会舍弃当前已接受但未读的输入
- TCSADRAIN与TCSAFLUSH的区别在于TCSAFLUSH会舍弃所有已接受但未读的输入
- tcsendbreak()函数原型:int tcsendbreak(int fd, int duration);
功能:传送连续的0比特流。如果duration为0,则至少发送0.25秒,不会超过0.5秒。如果duration非零,由实现定义传输时间。
- tcdrain()函数原型:int tcdrain(int fd);
功能:等待直到所有写入操作完成。该函数通常用于确保所有数据都被发送到终端。
- tcflush()函数原型:int tcflush(int fd, int action);
功能:刷新终端缓冲区。具体action参数的取值决定了操作方式:
- TCFINSH:刷新收到的数据但不读
- TCOFLUSH:刷新写入的数据但不传送
- TCIOFLUSH:同时刷新收到的数据但不读,并且刷新写入的数据但不传送
- tcflow()函数原型:int tcflow(int fd, int action);
功能:控制数据流。具体action参数的取值决定了操作方式:
- TCOOFF:挂起输出
- TCOON:重新启用被挂起的输出
- TCIoff:发送一个STOP字符,停止终端设备向系统传输数据
- TCIon:发送一个START字符,恢复终端设备的数据传输
termios结构体的波特率控制
cfgetospeed()函数原型:int cfgetospeed(struct termios *termios_p);
cfsetospeed()函数原型:int cfsetospeed(struct termios *termios_p, int speed);
cfgetispeed()函数原型:int cfgetispeed(struct termios *termios_p);
cfsetispeed()函数原型:int cfsetispeed(struct termios *termios_p, int speed);
波特率参数说明:
- B0:断开连接,通常表示连接被断开。使用B0时,不建议假定仍有连接
- B50、B75、B110等:标准波特率。B38400是常见的modem波特率
- B57600及以上:需要处理CBAUDEX掩码。例如,B57600与CBAUDEX的掩码结果为非零时表示高速
注意事项:
- tcsetattr()函数返回成功的条件是所有修改都可以实现。因此在进行多重修改时,建议在执行tcsetattr后调用tcgetattr()以确认所有修改都生效
- Input和output波特率的设置需要通过cfmakeraw函数进行特殊处理
- 所有关函数的行为在不同系统或平台上可能存在差异,开发者应仔细参考该平台的文档
以上内容详细解释了termios结构体的各个参数及其对应的函数操作。开发者在进行终端控制任务时,应根据实际需要合理设置各个参数,并注意函数调用时的参数配置和生效时机。
转载地址:http://rjzfk.baihongyu.com/