UART/TTL/RS232学习总结
关于RS232与TTL间的转换
特别注意的是:UART是将计算机的并行信号转换成串行信号的硬件设备,不要简单理解为协议
关于Linux终端①
Linux在为用户提供对终端设备简洁的读写接口之外,还提供了一组编程接口来对终端进行更精细的控制。下面是用户能够控制的主要功能:
行编辑: 是否允许使用退格键来编辑。
缓存:是立即读取字符,还是等待一段可配置的延迟之后再读取它们。
回显:允许控制字符的回显,例如读取密码时。
回车/换行(CR/LF):定义如何在输入/输出时映射回车/换行符,比如打印\n字符时应该如何处理。
线速:这种功能很少用于PC控制台,但对调制解调器或通过串行线连接的终端就很重要。
标准模式:所有的操作都基于行进行处理,在一个输入行完成前(通常是用户按下回车键之前),终端接口负责管理所有的键盘输入,包括退格键(Backspace)和删除键(Del),应用程序读不到用户的任何输入。这样做是有益的,因为允许用户来纠正输入中的错误直到满意为止。
termios结构
可以分为以下几个模式:输入模式,输出模式,控制模式,本地模式,特殊控制字符模式。
函数接口原型:②
1 |
|
参数action控制修改方式,共有三种修改方式:
TCSANOW:立即对值进行修改。
TCSADRAIN:等当前的值输出完成后再对值进行修改。
TCSAFLUSH:等当前的值输出完成后再对值进行修改,但丢弃还未从read调用返回的当前可用的任何输入。
特别注意,程序有责任将终端设置恢复到程序开始运行之前的状态,这一点是非常重要的。在kydevmonit的devicesManagerd中该如何做呢?
本地模式
通过设置termios中的c_lflag成员的标志来对本地模式进行设置。可用于c_lflag成员的宏如下:
ECHO:启用输入字符的本地回显功能。
ECHONL:回显新行符。
ICANON:启用标准输入处理,否则就启用非标准模式。
ISIG:启用信号。
NOFLUSH:禁止清空队列。
TOSTOP:在试图进行写操作之前给后台进程发送一个信号。
ECHOE/ECHOK/IEXTEN:略
输入模式
输入模式控制输入数据(终端驱动程序从串行口或键盘接收到的字符)在被传递给程序之前的处理方式。设置c_iflag。成员宏如下:
BRKINT:当在输入行中检测到一个终止状态(连接丢失)时,产生一个中断。
IGNBRK:忽略输入行中的终止状态。
ICRNL:将接收到的回车符转换为新行符。
INLCR:将接收到的新行符转换为回车符。
IGNCR:忽略接收到的回车符。
IGNPAP:忽略奇偶校验错误的字符。
INPCK:对接收到的字符进行奇偶校验。
ISTRIP:将所有接收到的字符裁剪为7bit。
IXOFF/IXON:关闭/打开软件流控。
输出模式
输出模式控制输出字符的处理方式,即由程序发送出去的字符在传递到串行口或屏幕之前是如何处理的。设置c_oflag。成员宏如下:
OPOST:打开输出处理功能。如果没有设置该标志,则所有其他标志则被忽略。
OCRNL:将输出的回车符转换为新行符。
ONLCR:将输出到的新行符转换为回车符。
ONLRET:不输出回车符。
其他略
控制模式
控制模式控制终端的硬件特性。你通过设置c_cflag成员的标志来对控制模式进行配置。成员宏如下:
CLOCAL:忽略所有调试解调器的状态行。
CREAD:启用字符接收器。
CS5:发送或接收时使用5bit。
CS6:发送或接收时使用6bit。
CS7:发送或接收时使用7bit。
CS8:发送或接收时使用8bit。
CSTOP:每个字符使用两个停止位而不是一个。
CSIZE:对数据的bit位使用掩码。注意,在设置CS数据位时要先屏蔽其他位。c_cflag &= ~CSIZE;
HUPCL:关闭时挂断调制解调器。
PARENB:启用就校验码的生成和检测功能。
PARODD:使用奇校验而不是偶检验。
1 | c_flag &= ~PARENB; // 无校验 |
特殊控制字符
这里只说明TIME与MIN值。用于是作为c_cc数组的index:
1 | int TIME,MIN; |
TIME与MIN只能用于非标准模式(禁用ICANON标志),两者结合起来共同控制对输入的读取。
两者的结合分为如下四种情况:
MIN=0和TIME=0:在这种情况下,read调用总是立即返回,如果有等待处理的字符,它们就会被返回;如果没有字符等待处理,read调用返回0,并且不读取任何字符。
MIN=0和TIME>1:这种情况下,只要有字符可以处理或者是经过TIME个0.1秒的时间间隔,read调用会返回。如果因为超时而未读到任何字符,read返回0,否则read返回读取的字符数目。
MIN>0和TIME=0:这种情况下,read调用会一直等待,直到有MIN个字符可以读取时才返回,返回值是读取的字符数量,但文件尾时返回0。
MIN>0和TIME>0:这种情况下,当read被调用时,它会等待接收一个字符。在接收到第一个字符及后续的每个字符后,一个字符间隔定时器被启动。当有MIN个字符可读或者两个字符的时间间隔超过TIME个0.1秒时,read调用返回。这个功能可用于区分是单独按下了Escape键还是按下了以Escape键开始的功能组合键。但要注意的是,网络通信或处理器的高负载使得类似这样的定时器失去作用。
通过设置非标准模式与使用MIN和TIME值,程序可以逐个字符地处理输入
终端速度
设置终端速度直接作用于termios结构,因此要设置新的终端速度,你必须使用tcgetattr获取当前配置,最后使用tcsetattr写回。只有写回后,终端速度才会改变。
1 | speed_t cfgetispeed(const struct termios*); |
speed的值可设置如下:
B0:挂起终端。
B9600:9600波特率。
B115200:115200波特率。
其他波特率包括B1200,B2400,B19200,B38400等。
其他函数
1 | int tcdrain(int fd); //让调用程序一直等待,直到所有排队的输出都已发送完毕。 |
使用shell命令stty -F <DEVICE> -a可以查看某个设备当前的termios值。
虚拟控制台
Linux提供一组终端设备来共享PC电脑的屏幕、键盘和鼠标。虚拟控制台通过字符设备文件/dev/ttyN来使用。
使用命令who或者ps -e你可以查看目前登录进系统的用户,以及在这个虚拟控制台上运行的shell和执行的程序。
Linux系统通常会在前6个虚拟台上运行一个getty进程,这样用户既可用同一个屏幕、键盘和鼠标在6个不同的虚拟控制台上登录。
伪终端
PTY与pts
参考资料
① Linux程序设计:第4版/(英)马修(Mattew,N.),(英)斯通斯(Stones,R.)著;陈健,宋健健译.——北京:人民邮电出版社,2010.6
② manpage for tcgetattr/tcsetattr