LDD-TTY

简介

tty源自teletypewriter——最初用于连接Unix的物理或虚拟终端;由于终端可以建立在串口上,后来tty也指任何串口设备。 物理tty设备包括串口,USB-串口转换器,还有一些调制解调器;虚拟tty设备通过网络连接或者xterm会话登陆计算机的虚拟控制台。
下图是tty的系统结构图,tty core负责控制tty设备的数据流和数据格式,和用户交互。驱动负责将core传送的数据格式化成硬件能够识别的数据格式。line discipline控制数据流,将来自core或者驱动的数据格式化。驱动不能与line discipline直接交互,后者对前者透明。
tty驱动有三种,console、serial port、pty。通过/proc/tty/drivers可以查看内核中的tty驱动类型。
 
TTY驱动

内核数据结构struct tty_driver,定义在linux/tty_driver.h中。相关的函数包括:alloc_tty_driver、tty_register/unregister_driver(调用时会建立sysfs目录)、tty_register/unregister_device。
struct tty_driver在初始化时需要指定init_termios域的值,如果端口在初始化前使用,会根据termios的值设置line的状态,这些值定义在include/linux/tty.h中。当然,tty_driver也包含一些函数指针:
open函数在用户打开该驱动程序管理的设备结点时由tty core调用。驱动程序需要在open函数内保存设备的相关信息;还要保存设备被打开的计数。close函数功能和open相对应。
write函数在用户向硬件发送数据时调用,需要返回发送的数据的长度。write函数可以在中断上下文和用户程序调用——tty驱动不能在中断上下文内调用任何可能休眠的程序,例如copy_from_user、kmalloc、printk。write_room可以返回写缓冲区内可用的空间;chars_in_buffer可以获得写缓冲区内已有的字符数——此函数非必须,但是如果驱动能在将字符发送到硬件前保存,必须实现这个函数。
tty core会将驱动收到的数据缓存在struct tty_flip_buffer,每个buffer都包含两个main data array。tty设备收到的数据首先保存在第一个数组中;充满时,会通知等待数据的程序。用户读取第一个数组的数据时,新到的数据会保存在第二个数组中。结构体内的count域包含当前缓冲区剩余的数据的数量信息。tty_flip_flush_push可以将缓冲区内的数据传递给用户。tty_insert_flip_char可以将驱动收到的数据添加到flip buffer中。
tty core还可以通过tty设备的termios域获取当前的line设置,也可以通过驱动实现的tiocmget、tiocmset函数获取和设置line状态;或者通过ioctl函数。
 
 
/proc和sysfs

tty core提供了简单的方法来创建/proc/tty/driver下对应的文件——只要驱动程序定义了read_proc或者write_proc函数,文件就会创建;针对这个文件的读写操作也会被发送到驱动程序执行。
tty core在驱动注册阶段或者一个individual tty devices are created时进行sysfs目录和设备的创建。
 
 
posted @ 2018-11-06 17:09  glob  阅读(267)  评论(0编辑  收藏  举报