1. 程式人生 > >linux驅動子系統--TTY

linux驅動子系統--TTY


tty目錄下的8250指的是intel的8250系列串列埠晶片驅動目錄;8250系列包括8250,16450,16450A等。

【struct uart_port解析】

flag串列埠屬性標誌,以下是解釋

#define UPF_FOURPORT                       4埠串列埠卡,8250系列

#define UPF_SAK                                      當串列埠接收到break訊號時終止在當前虛擬終端上執行的所有程序(包括X視窗)。這個組合鍵被稱為“安全訪問鍵“(SAK). <Alt><SysRq><k>

#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

非規範模式讀取時的最小字元數