圖14.5 串列埠核心層
串列埠核心層為串列埠裝置驅動提供了如下3個結構體:
1、uart_driver
uart_driver包含串列埠裝置的驅動名、裝置名、裝置號等資訊,它封裝了tty_driver,使得底層的uart驅動無需關心tty_driver,其定義如**清單14.13。
**清單14.13 uart_driver結構體
1 struct uart_driver
2 ;
乙個tty驅動必須註冊/登出tty_driver,而乙個uart驅動則演變為註冊/登出uart_driver,使用如下介面:
int uart_register_driver(struct uart_driver *drv);
void uart_unregister_driver(struct uart_driver *drv);
實際上,uart_register_driver()和uart_unregister_driver()中分別包含了tty_register_driver()和tty_unregister_driver()的操作,如**清單14.14所示。
**清單14.14 uart_register_driver()和uart_unregister_driver()函式
1 int uart_register_driver(struct uart_driver *drv)
2 34 return retval;
35 }
36 37 void uart_unregister_driver(struct uart_driver *drv)
38 2、uart_port
uart_port用於描述乙個uart埠(直接對應於乙個串列埠)的i/o埠或i/o記憶體位址、fifo大小、埠型別等資訊,其定義如**清單14.15。
**清單14.15 uart_port結構體
1 struct uart_port
2 ;
串列埠核心層提供如下函式來新增1個埠:
int uart_add_one_port(struct uart_driver *drv, struct uart_port *port);
對上述函式的呼叫應該發生在uart_register_driver()之後,uart_add_one_port()的乙個最重要作用是封裝了tty_register_device()。
uart_add_one_port()的「反函式」是uart_remove_one_port(),其中會呼叫tty_unregister_device(),原型為:
int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port);
驅動中雖然不需要處理uart_port的uart_info成員,但是在傳送時,從使用者來的資料被儲存在xmit(被定義為circ_buf,即環形緩衝 區)中,因此uart驅動在傳送資料時(一般在傳送中斷處理函式中),需要從這個circ_buf獲取上層傳遞下來的字元。
3、uart_ops
uart_ops 定義了針對uart的一系列操作,包括傳送、接收及線路設定等,如果說tty_driver中的tty_operations對於串列埠還較為抽象,那麼 uart_ops則直接面向了串列埠的uart,其定義如**清單14.16。linux驅動的這種層次非常類似於物件導向程式設計中基類、派生類的關係,派生類針對特定的事物會更加具體,而基類則站在更高的抽象層次上。
**清單14.16 uart_ops結構體
1 struct uart_ops
2 ;
serial_core.c 中定義了tty_operations的例項,包含uart_open()、uart_close()、uart_write()、 uart_send_xchar()等成員函式(如**清單14.17),這些函式會借助uart_ops結構體中的成員函式來完成具體的操作,**清單 14.18給出了tty_operations的uart_send_xchar()成員函式利用uart_ops中start_tx()、 send_xchar()成員函式的例子。
**清單14.17 串列埠核心層的tty_operations例項
1 static struct tty_operations uart_ops =
2 ;
**清單14.18 串列埠核心層的tty_operations與uart_ops關係
1 static void uart_send_xchar(struct tty_struct *tty, char ch)
2 18 }
19 }
注意: 整個呼叫流程為: 系統呼叫write()->uart_write()(tty_driver)->port->ops->start_tx();
在使用串列埠核心層這個通用串列埠tty驅動層的介面後,乙個串列埠驅動要完成的主要工作將包括:
• 定義uart_driver、uart_ops、uart_port等結構體的例項並在適當的地方根據具體硬體和驅動的情況初始化它們,當然具體裝置 ***的驅動可以將這些結構套在新定義的***_uart_driver、***_uart_ops、***_uart_port之內。
• 在模組初始化時呼叫uart_register_driver()和uart_add_one_port()以註冊uart驅動並新增埠,在模組解除安裝時 呼叫uart_unregister_driver()和uart_remove_one_port()以登出uart驅動並移除埠。
• 根據具體硬體的datasheet實現uart_ops中的成員函式,這些函式的實現成為uart驅動的主體工作
Linux 終端裝置驅動
1 控制台 1 控制台是乙個虛擬的終端,它必須對映到真正的終端上 2 控制台是個只輸出的裝置,功能很簡單,只能在核心中訪問 2 偽終端 一種特殊的終端裝置,由主 從兩個成對的裝置構成,當開啟主裝置時,對應的從裝置隨之開啟,形成連線狀態 輸入到主裝置的資料成為從裝置的輸出,輸入到從裝置的資料成為主裝置...
linux 終端裝置
終端解釋 終端是一種字元型裝置,它有多種型別,通常使用tty來簡稱各種型別的終端裝置。tty是teletype的縮寫。teletype是最早出現的一種終端裝置,很象電傳打字機 或者說就是 是由teletype公司生產的。在linux系統的裝置特殊檔案目錄 dev 下,終端特殊裝置檔案一般有以下幾種 ...
linux 終端裝置
早期計算機通常用電傳印表機充當終端裝置,終端裝置的作用就是接受使用者的輸入並傳遞給計算機,接受計算機的反饋返回給使用者。如下圖所示 後來電傳印表機被鍵盤和顯示器取代,linux為了支援這種外部終端裝置的連線,提供了終端裝置介面 tty 下面以海思hi3559開發板為例說明串列埠終端。在除錯開發板的時...