Linux 串口termios.h分析

1、背景

该到转嵌入式LInux应用开发的时候了。现在学习,不晚吧。努力。

1.1 参考资料

http://emb.hqyj.com/Column/Column811.htm

http://www.hqyj.com/news/emb174.htm

http://blog.chinaunix.net/uid-11582448-id-745506.html

https://blog.csdn.net/TAlice/article/details/80077064

2、termios.h 的分析

2.0 termios 结构体

     termios是Posix规范中定义的标准接口,表示终端设备(包括虚拟终端、串口等)。由于串口是一种终端设备,因此通过终端编程接口对其进行配置和控制。    

#define NCCS		18
struct termios
{
    unsigned short c_iflag;  // 输入模式标志
    unsigned short c_oflag;  // 输出模式标志
    unsigned short c_cflag;  // 控制模式标志
    unsigned short c_lflag;  // 本地模式标志
    unsigned char c_line;    // 线路规程
    unsigned char c_cc[NCC]; // 控制特性
    speed_t c_ispeed;        // 输入速度
    speed_t c_ospeed;        // 输出速度
}

 在结构体termios中c_cflag最为重要,可设置波特率、数据位、校验位、停止位。对于c_cflag成员不能直接对其初始化,而要将其通过 & 和 | 操作使用其中的某些选项。 

/* cflag bits */

/* Baud rate values.  These must fit in speed_t, which is unsigned
   char.  See also the extended baud rates below.  These baud rates
   set an additional bit. */
#define CBAUD	 0x0100f     //波特率的位掩码
#define B0	 0x00000         //0波特率(放弃DTR)
#define B50	 0x00001
#define B75	 0x00002
#define B110	 0x00003
#define B134	 0x00004
#define B150	 0x00005
#define B200	 0x00006
#define B300	 0x00007
#define B600	 0x00008
#define B1200	 0x00009
#define B1800	 0x0000a
#define B2400	 0x0000b
#define B4800	 0x0000c
#define B9600	 0x0000d
#define B19200	 0x0000e
#define B38400	 0x0000f

#define CSIZE	 0x00030      //数据位的位掩码
#define CS5	 0x00000          //5个数据位
#define CS6	 0x00010          //6个数据位
#define CS7	 0x00020          //7个数据位
#define CS8	 0x00030          //8个数据位
#define CSTOPB	 0x00040     //默认两位停止位,否则为1位
#define CREAD	 0x00080     //接收使能
#define PARENB	 0x00100     //校验位使能
#define PARODD	 0x00200     //使用奇校验而不使用偶校验
#define HUPCL	 0x00400     //关闭时挂线(放弃DTR)
#define CLOCAL	 0x00800     //本地链接(不改变端口所有者)

/* Extended baud rates above 37K. */
#define CBAUDEX	 0x0100f
#define B57600	 0x01001
#define B115200	 0x01002
#define B128000	 0x01003
#define B230400  0x01004
#define B256000	 0x01005
#define B460800  0x01006
#define B500000  0x01007
#define B576000  0x01008
#define B921600  0x01009
#define B1000000 0x0100a
#define B1152000 0x0100b
#define B1500000 0x0100c
#define B2000000 0x0100d
#define B2500000 0x0100e
#define B3000000 0x0100f

#define CRTSXOFF 0x04000
#define CRTSCTS	 0x08000     //使能硬件流控

成员c_iflag控制端口接收端的字符输入处理(Read)

/* iflag bits */
#define IGNBRK	0x00001   //忽略中断情况
#define BRKINT	0x00002   //当发生中断时发送SIGINT信号
#define IGNPAR	0x00004   //忽略奇偶校验
#define IMAXBEL	0x00008   //当输入太长时回复ECHO(振铃)
#define INPCK	0x00010   //打开输入奇偶校验
#define ISTRIP	0x00020   //剥除输入字符的第8位
#define INLCR	0x00040   //将输入的NL转换为CR
#define IGNCR	0x00080   //忽略CR
#define ICRNL	0x00100   //将输入额CR映射到NL
#define IXON	0x00400   //使启动/停止输出控制流起作用  启动输出软件流控
#define IXOFF	0x01000   //使启动/停止输入控制流起作用  启动输入软件流控
#define IUCLC	0x04000   //将输入的大写字符转换为小写字符
#define IXANY	0x08000   //允许字符重新启动输出
#define PARMRK	0x10000   //标记奇偶校验错误

成员c_lflag 用于控制终端的本地数据处理和工作模式。通过c_lflag成员控制终端的某些特性。

/* lflag bits */
#define ISIG	0x0001   //若收到信号字符(INTR、QUIT等),则会产生相应的信号
#define ICANON	0x0002   //终端规范模式,默认为规范模式,否则为非规范模式
#define ECHO	0x0004   //启动输入字符的本地本地回显功能
#define ECHOE	0x0008   //若设置ICANNO,则允许退格操作
#define ECHOK	0x0010   //若设置ICANNO,则KILL字符会删除当前行
#define ECHONL	0x0020   //若设置ICANNO, 则允许回显换行符
#define NOFLSH	0x0040   //在通常情况下,当接受到INTR、QUIT和SUSP控制字符时,会清空输入和输出队列。如果设置该标志,则所有的队列不会被清空
#define TOSTOP	0x0080   //若一个后台进程试图向它的控制终端进行写操作,则系统向该后台进程的进程组发送SIGTTOU信号,该信号通常终止进程的执行
#define IEXTEN	0x0100   //启用输入处理功能
#define FLUSHO	0x0200
#define ECHOKE	0x0400
#define ECHOCTL	0x0800   //若设置ECHO,则控制字符(制表符、换行符)会显示成"^X",其中X的ASCII码等于给相应控制字符的ASCII码加上0x40.例如退格符(0x08)会显示为"^H"('H'的ASCII码为0x48)

 2.1 终端

终端是指用户与计算机交互的接口,如键盘、显示屏和串口设备等物理设备,还有X Window上的虚拟终端。

2.1.1虚拟终端:

Windows下由putty  SecureCRT等虚拟终端;

类UNIX操作系统有行term、rxvt、zterm、eterm等。 文本式虚拟终端    X Window 上的图形式虚拟终端。

2.1.2 终端工作模式

终端有三种工作模式:规范模式(canonical mode )、非规范模式(non-canonical mode)和原始模式(raw mode).可通过termios.c_lflag的ICANNON位来配置。选择规范模式则设置ICANNON位,非规范模式则清除ICANNON位。

<1>规范模式----面向行

在规范模式下,输入数据基于行进行处理。

 >在用户输入一个行结束符(回车符、EOF等)之前,系统调用read()读不到用户输入的任何字符。

>除了EOF之外的行结束符(如回车符等),与普通字符一样会被read()读到缓冲区中。

>在规范模式中,可以进行行编辑,而且一次调用read()最多只能读取到一行数据

>如果read()请求读取的数据字节少于当前行可读取的字节时,则read()只读取被请求的字节数,剩余的下次再读。

输入字符会被放入一个缓冲中,这样可以以与用户交互的方式编辑缓冲区的内容,知道收到CR(carriage return,回车)或者LF(Line feed,换行)字符。

规范模式下,设置ICANNO、ECHO和ECHOE选项。

|= (ICANNO | ECHO | ECHOE);

<2> 非规范模式

在非规范模式下,所有的输入即时生效,用户不需要另外输入行结束符,不能进行行编辑。read()有四种中作模式。

可通过termios.c_cc[MIN] 和termios.c_cc[TIMEOUT]来设置工作模式。这里TIMEOUT的单位为1/10秒。

MIN TIMEOUT 工作模式
=0 =0 read()立即返回。若有数据可读,则读取并返回读取的字节数,否则返回0。
>0 =0 read()被阻塞,直到MIN个字节数据可被读取。
=0 >0 若数据可读,或超过TIMEOUT无数据,则read()返回。
>0 >0 若MIN个字节可读,或超过TIMEOUT无数据,则read()返回。

设置非规范模式,需要请掉ICANNO、ECHO、ECHOE和ISIG选项。

&= ~(ICANNO | ECHO | ECHOE | ISIG);

 

<3>原始模式

原始模式是一种特殊的非规范模式。在这种模式下,所有输入数据以字节为单位处理。原始输入根本不会被处理,输入字符只是被原封不动的接收。

 

 

3、串口初始化、设置和读写代码

 

 

4、

 

 

 

你可能感兴趣的:(Linux应用程序开发)