Linux tty子系统分析之二相关数据结构及设备抽象说明

 

      在上一章我们主要介绍了tty子系统的软件架构,并简要说明了数据结构间的关系,本章我们详细说明一下数据结构的抽象以及相关数据结构的说明。struct tty_file_private struct file struct tty_struct struct tty_driver struct tty_operations struct tty_ldisc struct tty_port

 

针对tty子系统,主要的数据结构抽象说明如下:

  1. 针对每一个tty控制器,抽象了一个tty_driver的数据结构,该数据结构即为tty控制器的抽象,该数据结构包含该tty控制器的访问接口(包括读、写等接口)
  2. 针对每一个tty端口设备(也可称为tty端口),抽象为tty_port数据结构,该结构体包含了存储从tty端口中接收的数据以及每一个数据对应的flag信息,并包含对应的接口(包括数据载波监听是否启动判断、tty端口激活及关闭、dtr/rts启动、tty port释放等接口);
  3. 在之前我们已经介绍了,借助一个tty端口传输不同格式的协议数据,即可实现不同的协议传输,即针对一个tty端口可实现多个不同的协议,因此tty驱动模块针对协议数据传输抽象出线路规程,现内核中实现了tty线路规程、irda线路规程、SLIP线路规程、PPP线路规程等
  4. 以上即为针对物理设备以及协议规程的抽象,而针对linux tty子系统,为了将tty子模块与上层文件系统关联,实现tty设备文件,又抽象了tty_struct数据结构,该数据结构包含一个tty端口、tty端口对应的线路规程、该tty端口所依附的tty控制器以及打开该tty端口的文件变量,即通过该数据结构,即可完成应用程序读写tty端口设备的功能。

 

        对于tty子系统而言,主要即为上述四个数据结构,同时在数据传输的过程中,又定义了辅助数据传输的数据结构tty_buffer等,下面我们分别介绍这四个数据结构。

 

tty子系统数据结构说明

tty_driver数据结构

       tty_driver即为tty控制器的抽象,该数据结构包含了该tty控制器所支持的tty端口个数、与tty端口通信的方法等信息。具体说明如下:

  1. 包含该ttyy控制器上所有已注册tty端口对应的字符设备变量(对于flag为TTY_DRIVER_DYNAMIC_DEV);
  2. tty端口对应字符设备的主设备号、次设备号起始值等
  3. 定义了tty_driver的类型(通过type、subtype变量进行定义,对于串口而言,其type为TTY_DRIVER_TYPE_SERIAL,而subtype为SERIAL_TYPE_NORMAL);
  4. 定义了tty_struct类型的二维指针,主要指向该tty控制器所支持的所有tty端口对应的tty_struct类型的变量;
  5. 定义了该tty控制器支持的所有tty端口的属性相关变量(ktermios类型);
  6. 而driver_state则定义了该tty控制器的私有变量,主要由具体的tty_dirver决定是否使用该变量;
  7. 定义了该tty控制器所支持的操作接口(即struct tty_operations类型变量);
  8. 定义了链表类型变量,用于将所有注册至系统的tty_driver链接至一起;

 

 

 

而针对tty_operations,其定义如下,主要内容如下:

  1. 定义了install接口,该接口完成tty_struct、tty_driver等数据结构之间的关联;
  2. remove则是解除这些数据结构间的关联;
  3. open、close、shutdown则对应于tty端口的打开与关闭,其中在open函数中则包含启动数据收发中断等;
  4. cleanup则释放tty端口相关的资源;
  5. 而write、put_char一般即完成将数据写入tty端口中(若需要构造复杂的框架,如uart而言,则只是将数据写入uart port的缓存中,在调用start接口时,才是将数据从缓存写入tty端口中)
  6. ioctl主要是用于通过字符设备对tty端口设置控制信息等;
  7. 包含了数据流速控制相关的接口throttle、unthrottle等
  8. 包含了对于写buff空间相关的接口等

 

struct tty_port

       针对tty端口而言,主要包括该tty端口所对应的buff接口,用于存储该tty端口所接受的数据,同时也包含了指向tty控制器的指针以及该tty端口所包含的操作接口等信息。

 

 

tty端口的操作接口如下,主要包括:

  1. 判断tty端口的数据载波信号检测是否开启接口
  2. 启动DTR/RTS接口
  3. 激活与关闭一个tty端口
  4. tty端口释放的接口,若在申请tty端口时,申请了额外的内存,如sdio_uart中申请的是sdio_uart_port类型的内存,

       因此此处需要定义destruct,自动释放该内存,若在实现tty driver的代码中需要使用tty_port_put接口,借助tty port的引用计数实现tty port的释放,且需要实现该接口

       针对tty端口而言,另外重要的数据结构即为tty_bufhead、tty_buffer这两个数据结构的定义如下,针对tty_bufhead,包含了一个工作队列,而在该类型数据变量的初始化时,则定义该工作队列的回调函数为flush_to_ldisc。

      当tty端口的接收中断接收到数据后,则调用tty_insert_flip_char将数据与flag写入tty端口对应的tty_buffer中,然后调用schedule_work,调用tty_bufhead的工作队列回调函数flush_to_ldisc,实现将接收数据写入tty端口的线路规程中,并唤醒线路规程的read接口,从而实现将数据写入到应用程序提供的buffer中。

 

 

 

 

struct tty_struct

       该数据结构主要用于实现vfs与tty子系统的关联,从而实现应用程序通过读写tty字符设备,完成对tty端口的操作,该数据结构包含的主要内容如下:

  1. tty端口号、该tty端口所关联的线路规程、读写等待队列;
  2. 线路规程、tty driver相关的私有数据变量指针;
  3. 该tty端口对应字符设备已打开的所有struct file类型的链表;
  4. 该tty端口所依附的tty_driver及其对应的操作接口等。

 

 

 

以上即为这四个数据结构及其关联数据结构的介绍,下面通过数据结构的关联图,说明它们之间的关系。

如下图所示,主要涉及如下几个方面:

  1. tty子系统定义了字符设备节点相关操作接口,主要包括tty_open、tty_release、tty_ioctl、tty_read、tty_write等,用于实现对tty端口对应字符设备的访问;
  2. 而tty_struct通过其tty_files链表及struct file的private_data指针,实现了file与tty_struct的相互关联(从下图可知,当多个应用程序同时打开一个tty端口对应的字符设备时,tty子系统仅创建一个tty_struct,而多个struct file变量则通过链表链接至tty_struct);
  3. tty字符设备的tty_xxx接口通过调用线路规程的操作接口,进行数据读写,而线路规程的相关接口,则调用tty_driver的操作接口,实现与tty端口的通信;
  4. 系统中所有已注册的tty_driver均链接至tty_drivers链表上。而tty_driver则借助其ttys、ports成员,完成与tty_struct、tty_port的关联。

 

       而针对tty_driver_register、tty_cdev_add、tty_open等接口的调用,也就是建立下图的数据结构之间的关联,当它们之间的关联建立完成以后,即可实现数据的收发。

 

 

tty子系统的层次关系

在上面的数据结构关联中也基本上知道了tty子系统各层间的关联,下面是逻辑抽象,主要说明如下:

  1. 通过tty字符设备接口层,实现将tty端口关联为tty字符设备文件,可通过vfs提供的接口访问该字符设备文件;
  2. tty字符设备接口通过完成tty_struct、tty_ldisc、tty_port、tty_driver的关联,并调用tty_ldisc提供给的接口,实现与线路规程的通信;
  3. 线路规程通过调用tty_driver的接口,实现与tty控制器的通信;
  4. tty控制器的接口会调用tty端口提供的操作接口,进行端口的激活、流控等功能,同时完成与tty端口的通信,并将读取的数据返回给线路规程层,进而上传给应用程序。
  5. 针对具体的tty控制器驱动,只需要实现tty_driver、tty_port数据结构对应的实例(如下面的sdio uart实现的tty_driver、tty_port;串口实现的tty_driver、tty_port;usb转串口实现tty_driver、tty_port;伪端口、控制台等均需要实现对应的tty_driver、tty_port类型的变量,),则应用程序则可通过对应的tty字符设备文件实现对tty端口的访问

 

 

 

 

     以上即为本篇文章的主要内容,这段时间耽搁了,没有及时更新,下面会具体介绍下tty字符设备、tty线路规程、tty注册相关的内容。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值