linux驱动子系统--TTY

linux驱动子系统--TTY_第1张图片

 

 

tty目录下的8250指的是intel的8250系列串口芯片驱动目录;8250系列包括8250,16450,16450A等。

 

 

【struct uart_port解析】

flag 串口属性标志,以下是解释

#define UPF_FOURPORT                       4端口串口卡,8250系列

#define UPF_SAK                                      当串口接收到break信号时终止在当前虚拟终端上运行的所有进程(包括X窗口)。这个组合键被称为“安全访问键“(SAK). 

#define UPF_SPD_MASK                        波特率掩码

#define UPF_SPD_HI                               当设置波特率的参数非法时,默认其为57600

#define UPF_SPD_VHI                             当设置波特率的参数非法时,默认其为115200

#define UPF_SPD_CUST                       当期望波特率为38400时,如果UPF_SPD_HI和UPF_SPD_VHI同时被指定,则波特率除数由port->custom_divisor指定,这个用不到

#define UPF_SPD_SHI                            当设置波特率的参数非法时,默认其为230400

#define UPF_SPD_WARP                       当设置波特率的参数非法时,默认其为460800

#define UPF_SKIP_TEST                        调过检测串口是否存在,当前只有8250系列驱动在用

#define UPF_AUTO_IRQ                         串口中断号由port->ops->config_port()自动探测

#define UPF_HARDPPS_CD                  支持硬件秒脉冲检测

#define UPF_LOW_LATENCY                串口接收到数据后是否立即传递到line discipline处理

#define UPF_BUGGY_UART                  古怪的串口???一般不用

#define UPF_NO_TXEN_TEST              不进行传输使能检测

#define UPF_MAGIC_MULTIPLIER       波特率除数计算时不通过uart_get_divisor()来获得,而是直接指定

#define UPF_CONS_FLOW                    具有流控功能

#define UPF_SHARE_IRQ                      与其他设备共享中断号,未用到

#define UPF_EXAR_EFR                        串口为8250系列XR17D15x芯片,它的Extended Features Register位置和普通8250系列不一样

#define UPF_BUG_THRE                       8250系列串口,存在THRE的bug

#define UPF_FIXED_TYPE                     串口类型是固定的,否则由port->ops->config_port()来探测

#define UPF_BOOT_AUTOCONF         是否在串口注册时自动配置(调用port->ops->config_port())

#define UPF_FIXED_PORT                    串口类型属性注册后就不可以改变

#define UPF_DEAD                                  置位表示串口已通过uart_remove_one_port()移除,uart_add_one_port()时该位清除

#define UPF_IOREMAP                           串口访问资源需要进行IOREMAP操作

#define UPF_CHANGE_MASK              串口属性类型变更时flag标志需变更的比特位掩码

#define UPF_USR_MASK                      用户可以修改的比特位掩码

 

mctrl                              当前串口控制状态,主要由串口驱动核心在使用,他的标志位如下

TIOCM_LE         ???

TIOCM_DTR      终端设备已准备好

TIOCM_RTS      终端设备请求发送数据

TIOCM_ST        

TIOCM_SR       

TIOCM_CTS      允许终端设备发送数据过来

TIOCM_CAR / TIOCM_CD      线路上已检测到载波

TIOCM_RNG / TIOCM_RI     通知终端设备,modem已被呼叫

TIOCM_DSR      modem已准备好

TIOCM_OUT1 / TIOCM_OUT2       这个啥用???

TIOCM_LOOP    modem处于回环模式

 

timeout                         关断串口时等待数据发送完成的时间

type                               串口类型,serial_core.h中定义,比如PORT_ATMEL系列为49

ops                                实现硬件操作的驱动方法,写串口驱动大部分代码在此处

custom_divisor           计算波特率除数时如果指定的波特率非法则直接使用custom_divisor, 具体参见uart_get_divisor()

line                                串口序号,跟打印信息,设备号等相关

mapbase                     ioremap映射的地址参数,物理地址

membase                    ioremap之后的虚拟地址,所有对串口资源的访问都是用改地址,使用readw()/writew()

iobase                          直接IO指令访问时传递的地址参数,intel X86系列有此功能,但是ARM架构都是通过内存映射访问

serial_in                       传统的串口资源访问方法,调用serial_port_in()访问,驱动可以自己使用

serial_out                     传统的串口资源访问方法,调用serial_port_out()访问,驱动可以自己使用

set_termios                 设置串口的属性,现在只有8250系列芯片还在使用,该功能现在由struct uart_ops的set_termios实现

handle_irq                   串口中断处理函数,现在只有8250系列芯片还在使用,在该函数外面再包一层注册中断函数,多此一举,所以最好的方法是不用此方法。

pm                                8250系列芯片独享,其他驱动在struct uart_ops的pm方法里实现

irq                                  中断号,既可以指定,也可以动态探测得到,取决于系统架构

irqflags                         中断函数的标志位,注册中断时使用

uartclk                           串口输入时钟频率

fifosize                          fifo大小,一般串口都带有fifo吧。。

x_char                          保存需要发送的XON/XOFF字符时,一般上层调用port->ops->send_xchar,如果没提供该方法则调用port->ops->start_tx(),这样一来就基本上是在中断函数中查询是否需要发送XON/XOFF字符

regshift                        寄存器序号之间的地址偏移,一般设为4,但是这个用处不大

iotype                           串口资源的类别,有UPIO_PORT、UPIO_HUB6、UPIO_MEM、UPIO_MEM32、UPIO_AU、UPIO_TSI,  UPIO_PORT和UPIO_HUB6都是IO访问型,UPIO_MEM、UPIO_MEM32是需要内存映射的,后三个坑爹吧,应该也是内存映射的,为啥要独立出来???

unused1                     确实没用到,那么驱动可以用来干自己的小九九

read_status_mask        串口工作状态读取掩码,掩码外的状态不处理,因此显然这个成员是驱动用的

ignore_status_mask        uart_insert_char()读取数据时需要忽略哪些状态位

state                           指向struct uart_state,uart_state用于汇总上下层的数据结构

icount                         串口统计计数,驱动要用到的

cons                           当串口需要作为Printk系统打印控制台时用到

sysrq                          执行sysrq操作时的timeout时间,串口驱动核心自己使用,当前确定为5s,底层驱动不要赋值

dev                             设备驱动模型表示

hub6                          8250系列6端口串口卡,指定其端口序号

suspended              串口是否处于休眠状态,驱动别去碰他

irq_wake                  串口是否处于中断待唤醒状态,没怎么用

unused                     这个驱动可以用,但是不推荐

private_data             驱动特定的数据结构,貌似大家都没用

lock                            自旋锁,驱动和串口核心都用,注意互斥访问


struct uart_ops驱动操作方法:

tx_empty                  传输缓冲区是否为空

set_mctrl                 设置串口控制状态

get_mctrl                 获取串口控制状态

stop_tx                     停止传输数据

start_tx                     启动传输数据

send_xchar            发送XON/XOFF字符

stop_rx                    停止接收数据

enable_ms             允许modem状态中断

break_ctl                break信号控制

startup                    启动串口所需的软件资源,比如定时器、中断注册等

shutdown               关断串口,与startup相反

flush_buffer           清空传输缓冲区

set_termios           设置串口工作模式

set_ldisc                 进行线路规程相关设置

pm                            电源管理操作

set_wake               ???

type                          查询串口类别,返回字符串

release_port          释放串口注册的软件资源

request_port         申请串口使用的软件资源

config_port             端口配置

verify_port               验证用户层的设置是否正确

ioctl                         用户ioctl操作,一般底层驱动不需要实现了,因为uart层已经实现了大部分的命令

poll_put_char       以查询方式发送数据

poll_get_char       以查询方式接收数据


uart接口API

uart_add_one_port       

1、通过struct uart_state和struct tty_port挂接;

2、配置端口硬件port->ops->config_port、port->ops->set_mctrl;

3、向设备驱动核心注册;

uart_register_driver

1、创建并初始化struct uart_driver的上层代表struct tty_driver;

2、注册设备号(后续用户操作时根据设备号就能找到对应的驱动);

3、链接到tty驱动的单链表中;


struct ktermios的标志位说明

struct ktermios {

          tcflag_t  c_iflag;                  /*input mode flags */

          tcflag_t c_oflag;                 /*output mode flags */

          tcflag_t c_cflag;                 /*control mode flags */

          tcflag_t c_lflag;                  /*local mode flags */

          cc_t    c_line;          /* line discipline */

          cc_t    c_cc[NCCS];           /* control characters */

          speed_t c_ispeed;     /* input speed */

          speed_t c_ospeed;    /* output speed */

}


c_iflag:输入模式标志,控制终端输入方式,具体参数如表1所示。

1 c_iflag参数表

   

   

IGNBRK

忽略BREAK键输入

BRKINT

如果设置了IGNBRKBREAK键输入将被忽略

IGNPAR

忽略奇偶校验错误

PARMRK

标识奇偶校验错误

INPCK

允许输入奇偶校验

ISTRIP

去除字符的第8个比特

INLCR

将输入的NL(换行)转换成CR(回车)

IGNCR

忽略输入的回车

ICRNL

将输入的回车转化成换行(如果IGNCR未设置的情况下)

IUCLC

将输入的大写字符转换成小写字符(非POSIX

IXON

允许输入时对XON/XOFF流进行控制

IXANY

输入任何字符将重启停止的输出

IXOFF

允许输入时对XON/XOFF流进行控制

IMAXBEL

当输入队列满的时候开始响铃

c_oflag:输出模式标志,控制终端输出方式,具体参数如表2所示。

2 c_oflag参数

   

   

OPOST

处理后输出

OLCUC

将输入的小写字符转换成大写字符(非POSIX

ONLCR

将输入的NL(换行)转换成CR(回车)及NL(换行)

OCRNL

将输入的CR(回车)转换成NL(换行)

ONOCR

第一行不输出回车符

ONLRET

不输出回车符

OFILL

发送填充字符以延迟终端输出

OFDEL

ASCII码的DEL作为填充字符,如果未设置该参数,填充字符为NUL

NLDLY

换行输出延时,可以取NL0(不延迟)或NL1(延迟0.1s

CRDLY

回车延迟,取值范围为:CR0CR1CR2 CR3

TABDLY

水平制表符输出延迟,取值范围为:TAB0TAB1TAB2TAB3

BSDLY

空格输出延迟,可以取BS0BS1

VTDLY

垂直制表符输出延迟,可以取VT0VT1

FFDLY

换页延迟,可以取FF0FF1

c_cflag:控制模式标志,指定终端硬件控制信息,具体参数如表3所示。

3 c_cflag参数

   

   

CBAUD

波特率(4+1位)(非POSIX

CBAUDEX

附加波特率(1位)(非POSIX

CSIZE

字符长度,取值范围为CS5CS6CS7CS8

CSTOPB

设置两个停止位

CREAD

使用接收器

PARENB

使能校验

PARODD

置1使用奇校验,置0使用偶校验

HUPCL

关闭设备时挂起

CLOCAL

忽略调制解调器线路状态

CRTSCTS

使用RTS/CTS流控制

CMSPAR  

 使用MARK/SPACE校验方式



c_lflag:本地模式标志,控制终端编辑功能,具体参数如表4所示。

4 c_lflag参数

   

   

ISIG

当输入INTRQUITSUSPDSUSP时,产生相应的信号

ICANON

使用标准输入模式

XCASE

ICANONXCASE同时设置的情况下,终端只使用大写。

ECHO

显示输入字符

ECHOE

如果ICANON同时设置,ERASE将删除输入的字符

ECHOK

如果ICANON同时设置,KILL将删除当前行

ECHONL

如果ICANON同时设置,即使ECHO没有设置依然显示换行符

ECHOPRT

如果ECHOICANON同时设置,将删除打印出的字符(非POSIX

TOSTOP

向后台输出发送SIGTTOU信号

c_cc[NCCS]:控制字符,用于保存终端驱动程序中的特殊字符,如输入结束符等。c_cc中定义了如表5所示的控制字符。

5 c_cc支持的控制字符

   

   

VINTR

Interrupt字符

VEOL

附加的End-of-file字符

VQUIT

Quit字符

VTIME

非规范模式读取时的超时时间

VERASE

Erase字符

VSTOP

Stop字符

VKILL

Kill字符

VSTART

Start字符

VEOF

End-of-file字符

VSUSP

Suspend字符

VMIN

非规范模式读取时的最小字符数


你可能感兴趣的:(linux驱动子系统--TTY)