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鏈接至一起;

Linux tty子系統分析之二相關數據結構及設備抽象說明


而針對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空間相關的接口等
Linux tty子系統分析之二相關數據結構及設備抽象說明

struct tty_port

針對tty端口而言,主要包括該tty端口所對應的buff接口,用於存儲該tty端口所接受的數據,同時也包含了指向tty控制器的指針以及該tty端口所包含的操作接口等信息。

Linux 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的釋放,且需要實現該接口


Linux tty子系統分析之二相關數據結構及設備抽象說明

針對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中。

Linux tty子系統分析之二相關數據結構及設備抽象說明

Linux tty子系統分析之二相關數據結構及設備抽象說明


struct tty_struct

該數據結構主要用於實現vfs與tty子系統的關聯,從而實現應用程序通過讀寫tty字符設備,完成對tty端口的操作,該數據結構包含的主要內容如下:

  1. tty端口號、該tty端口所關聯的線路規程、讀寫等待隊列;
  2. 線路規程、tty driver相關的私有數據變量指針;
  3. 該tty端口對應字符設備已打開的所有struct file類型的鏈表;
  4. 該tty端口所依附的tty_driver及其對應的操作接口等。
Linux tty子系統分析之二相關數據結構及設備抽象說明


以上即為這四個數據結構及其關聯數據結構的介紹,下面通過數據結構的關聯圖,說明它們之間

的關係。

如下圖所示,主要涉及如下幾個方面:

  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等接口的調用,也就是建立下圖的數據結構

之間的關聯,當它們之間的關聯建立完成以後,即可實現數據的收發。

Linux tty子系統分析之二相關數據結構及設備抽象說明

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端口的訪問


Linux tty子系統分析之二相關數據結構及設備抽象說明


以上即為本篇文章的主要內容,這段時間耽擱了,沒有及時更新,下面會具體介紹下tty字符設備、tty線路規程、tty註冊相關的內容。


分享到:


相關文章: