1. 程式人生 > >termios 結構體

termios 結構體

一、資料成員


termios 函式族提供了一個常規的終端介面,用於控制非同步通訊埠。 這個結構包含了至少下列成員: 
tcflag_t c_iflag;      /* 輸入模式 */
tcflag_t c_oflag;      /* 輸出模式 */
tcflag_t c_cflag;      /* 控制模式 */
tcflag_t c_lflag;      /* 本地模式 */
cc_t c_cc[NCCS];       /* 控制字元 */


struct termios
{unsigned short c_iflag; /* 輸入模式標誌*/
unsigned short c_oflag; /* 輸出模式標誌*/
unsigned short c_cflag; /* 控制模式標誌*/
unsigned short c_lflag; /*區域模式標誌或本地模式標誌或區域性模式*/
unsigned char c_line; /*行控制line discipline */
unsigned char c_cc[NCC]; /* 控制字元特性*/
};
二、作用
這個變數被用來提供一個健全的線路設定集合, 如果這個埠在被使用者初始化前使用. 驅動初始化這個變數使用一個標準的數值集, 它拷貝自 tty_std_termios 變數. tty_std_termos 在 tty 核心被定義為:


struct termios tty_std_termios = {
 .c_iflag = ICRNL | IXON,
 .c_oflag = OPOST | ONLCR,
 .c_cflag = B38400 | CS8 | CREAD | HUPCL,
 .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
 ECHOCTL | ECHOKE | IEXTEN,
 .c_cc = INIT_C_CC
};這個 struct termios 結構用來持有所有的當前線路設定, 給這個 tty 裝置的一個特定埠. 這些線路設定控制當前波特率, 資料大小, 資料流控設定, 以及許多其他值.


三、成員的值


(一)c_iflag 標誌常量:Input mode ( 輸入模式) input mode可以在輸入值傳給程式之前控制其處理的方式。


其中輸入值可能是由序列埠或鍵盤的終端驅動程式所接收到的字元。   我們可以利用termios結構的c_iflag的標誌來加以控制,其定義的方式皆以OR來加以組合。    
IGNBRK :忽略輸入中的 BREAK 狀態。 (忽略命令列中的中斷) 
BRKINT :(命令列出現中斷時,可產生一插斷)如果設定了 IGNBRK,將忽略 BREAK。如果沒有設定,但是設定了 BRKINT,那麼 BREAK 將使得輸入和輸出佇列被重新整理,如果終端是一個前臺程序組的控制終端,這個程序組中所有程序將收到 SIGINT 訊號。如果既未設定 IGNBRK 也未設定 BRKINT,BREAK 將視為與 NUL 字元同義,除非設定了 PARMRK,這種情況下它被視為序列 377 � �。  
IGNPAR :忽略楨錯誤和奇偶校驗錯。  
PARMRK :如果沒有設定 IGNPAR,在有奇偶校驗錯或楨錯誤的字元前插入 377 �。如果既沒有設定 IGNPAR 也沒有設定 PARMRK,將有奇偶校驗錯或楨錯誤的字元視為 �。  
INPCK :啟用輸入奇偶檢測。  
ISTRIP :去掉第八位。  
INLCR :將輸入中的 NL 翻譯為 CR。(將收到的換行符號轉換為Return)  
IGNCR :忽略輸入中的回車。  
ICRNL :將輸入中的回車翻譯為新行 (除非設定了 IGNCR)(否則當輸入訊號有 CR 時不會終止輸入)。  
IUCLC :(不屬於 POSIX) 將輸入中的大寫字母對映為小寫字母。  
IXON :啟用輸出的 XON/XOFF 流控制。   
IXANY :(不屬於 POSIX.1;XSI) 允許任何字元來重新開始輸出。(?)  
IXOFF :啟用輸入的 XON/XOFF 流控制。  
IMAXBEL:(不屬於 POSIX) 當輸入佇列滿時響零。Linux 沒有實現這一位,總是將它視為已設定。 




(二) c_oflag 標誌常量:Output mode ( 輸出模式)


Output mode主要負責控制輸出字元的處理方式。輸出字元在傳送到序列埠或顯示器之前是如何被程式來處理。


輸出模式是利用termios結構的c_oflag的標誌來加以控制,其定義的方式皆以OR來加以組合。


  
OPOST :啟用具體實現自行定義的輸出處理。  
OLCUC :(不屬於 POSIX) 將輸出中的小寫字母對映為大寫字母。  
ONLCR :(XSI) 將輸出中的新行符對映為回車-換行。  
OCRNL :將輸出中的回車對映為新行符  
ONOCR :不在第 0 列輸出回車。  
ONLRET :不輸出回車。  
OFILL :傳送填充字元作為延時,而不是使用定時來延時。  
OFDEL :(不屬於 POSIX) 填充字元是 ASCII DEL (0177)。如果不設定,填充字元則是 ASCII NUL。  
NLDLY :新行延時掩碼。取值為 NL0 和 NL1。  
CRDLY :回車延時掩碼。取值為 CR0, CR1, CR2, 或 CR3。  
TABDLY :水平跳格延時掩碼。取值為 TAB0, TAB1, TAB2, TAB3 (或 XTABS)。取值為 TAB3,即 XTABS,將擴充套件跳格為空格 (每個跳格符填充 8 個空格)。(?)  
BSDLY :回退延時掩碼。取值為 BS0 或 BS1。(從來沒有被實現過)  
VTDLY :豎直跳格延時掩碼。取值為 VT0 或 VT1。  
FFDLY :進表延時掩碼。取值為 FF0 或 FF1。




(三)c_cflag 標誌常量:Control mode ( 控制模式)


Control mode主要用於控制終端裝置的硬體設定。利用termios結構的c_cflag的標誌來加以控制。控制模式用在序列線連線到資料裝置,也可以用在與終端裝置的交談。


一般來說,改變終端裝置的組態要比使用termios的控制模式來改變行(lines)的行為來得容易。




CBAUD :(不屬於 POSIX) 波特率掩碼 (4+1 位)。  
CBAUDEX :(不屬於 POSIX) 擴充套件的波特率掩碼 (1 位),包含在 CBAUD 中。  
(POSIX 規定波特率儲存在 termios 結構中,並未精確指定它的位置,而是提供了函式 cfgetispeed() 和 cfsetispeed() 來存取它。一些系統使用 c_cflag 中 CBAUD 選擇的位,其他系統使用單獨的變數,例如 sg_ispeed 和 sg_ospeed 。)  
CSIZE:字元長度掩碼(傳送或接收字元時用的位數)。取值為 CS5(傳送或接收字元時用5bits), CS6, CS7, 或 CS8。  
CSTOPB :設定兩個停止位,而不是一個。  
CREAD :開啟接受者。  
PARENB :允許輸出產生奇偶資訊以及輸入的奇偶校驗(啟用同位產生與偵測)。  
PARODD :輸入和輸出是奇校驗(使用奇同位而非偶同位)。  
HUPCL :在最後一個程序關閉裝置後,降低 modem 控制線 (結束通話)。(?)  
CLOCAL :忽略 modem 控制線。  
LOBLK :(不屬於 POSIX) 從非當前 shell 層阻塞輸出(用於 shl )。(?)  
CIBAUD :(不屬於 POSIX) 輸入速度的掩碼。CIBAUD 各位的值與 CBAUD 各位相同,左移了 IBSHIFT 位。  
CRTSCTS :(不屬於 POSIX) 啟用 RTS/CTS (硬體) 流控制。


(四)c_lflag 標誌常量:Local mode ( 區域性模式)
Local mode主要用來控制終端裝置不同的特色。利用termios結構裡的c_lflag的標誌來設定區域性模式。
在巨集中有兩個比較重要的標誌:
1.ECHO:它可以讓你阻止鍵入字元的迴應。
2.ICANON(正規模式)標誌,它可以對所接收的字元在兩種不同的終端裝置模式之間來回切換。 
ISIG:當接受到字元 INTR, QUIT, SUSP, 或 DSUSP 時,產生相應的訊號。  
ICANON:啟用標準模式 (canonical mode)。允許使用特殊字元 EOF, EOL, EOL2, ERASE, KILL, LNEXT, REPRINT, STATUS, 和 WERASE,以及按行的緩衝。  
XCASE:(不屬於 POSIX; Linux 下不被支援) 如果同時設定了 ICANON,終端只有大寫。輸入被轉換為小寫,除了有字首的字元。輸出時,大寫字元被字首(某些系統指定的特定字元) ,小寫字元被轉換成大寫。  
ECHO :回顯輸入字元。  
ECHOE :如果同時設定了 ICANON,字元 ERASE 擦除前一個輸入字元,WERASE 擦除前一個詞。  
ECHOK :如果同時設定了 ICANON,字元 KILL 刪除當前行。  
ECHONL :如果同時設定了 ICANON,回顯字元 NL,即使沒有設定 ECHO。  
ECHOCTL :(不屬於 POSIX) 如果同時設定了 ECHO,除了 TAB, NL, START, 和 STOP 之外的 ASCII 控制訊號被回顯為 ^X, 這裡 X 是比控制訊號大 0x40 的 ASCII 碼。例如,字元 0x08 (BS) 被回顯為 ^H。  
ECHOPRT :(不屬於 POSIX) 如果同時設定了 ICANON 和 IECHO,字元在刪除的同時被列印。  
ECHOKE :(不屬於 POSIX) 如果同時設定了 ICANON,回顯 KILL 時將刪除一行中的每個字元,如同指定了 ECHOE 和 ECHOPRT 一樣。  
DEFECHO :(不屬於 POSIX) 只在一個程序讀的時候回顯。  
FLUSHO :(不屬於 POSIX; Linux 下不被支援) 輸出被重新整理。這個標誌可以通過鍵入字元 DISCARD 來開關。  
NOFLSH :禁止在產生 SIGINT, SIGQUIT 和 SIGSUSP 訊號時重新整理輸入和輸出佇列,即關閉queue中的flush。  
TOSTOP :向試圖寫控制終端的後臺程序組傳送 SIGTTOU 訊號(傳送欲寫入的資訊到後臺處理)。  
PENDIN :(不屬於 POSIX; Linux 下不被支援) 在讀入下一個字元時,輸入佇列中所有字元被重新輸出。(bash 用它來處理 typeahead)  
IEXTEN :啟用實現自定義的輸入處理。這個標誌必須與 ICANON 同時使用,才能解釋特殊字元 EOL2,LNEXT,REPRINT 和 WERASE,IUCLC 標誌才有效。  
(五)c_cc 陣列:特殊控制字元


可提供使用者設定一些特殊的功能, 如Ctrl+C的字元組合。特殊控制字元主要是利用termios結構裡c_cc的陣列成員來做設定。
c_cc陣列主要用於正規與非正規兩種環境,但要注意的是正規與非正規不可混為一談。
其定義了特殊的控制字元。符號下標 (初始值) 和意義為:


VINTR:(003, ETX, Ctrl-C, or also 0177, DEL, rubout) 中斷字元。發出 SIGINT 訊號。當設定 ISIG 時可被識別,不再作為輸入傳遞。  
VQUIT :(034, FS, Ctrl-) 退出字元。發出 SIGQUIT 訊號。當設定 ISIG 時可被識別,不再作為輸入傳遞。  
VERASE :(0177, DEL, rubout, or 010, BS, Ctrl-H, or also #) 刪除字元。刪除上一個還沒有刪掉的字元,但不刪除上一個 EOF 或行首。當設定 ICANON 時可被識別,不再作為輸入傳遞。  
VKILL :(025, NAK, Ctrl-U, or Ctrl-X, or also @) 終止字元。刪除自上一個 EOF 或行首以來的輸入。當設定 ICANON 時可被識別,不再作為輸入傳遞。  
VEOF :(004, EOT, Ctrl-D) 檔案尾字元。更精確地說,這個字元使得 tty 緩衝中的內容被送到等待輸入的使用者程式中,而不必等到 EOL。如果它是一行的第一個字元,那麼使用者程式的 read() 將返回 0,指示讀到了 EOF。當設定 ICANON 時可被識別,不再作為輸入傳遞。  
VMIN :非 canonical 模式讀的最小字元數(MIN主要是表示能滿足read的最小字元數)。  
VEOL :(0, NUL) 附加的行尾字元。當設定 ICANON 時可被識別。  
VTIME :非 canonical 模式讀時的延時,以十分之一秒為單位。  
VEOL2 :(not in POSIX; 0, NUL) 另一個行尾字元。當設定 ICANON 時可被識別。  
VSWTCH :(not in POSIX; not supported under Linux; 0, NUL) 開關字元。(只為 shl 所用。)  
VSTART :(021, DC1, Ctrl-Q) 開始字元。重新開始被 Stop 字元中止的輸出。當設定 IXON 時可被識別,不再作為輸入傳遞。  
VSTOP :(023, DC3, Ctrl-S) 停止字元。停止輸出,直到鍵入 Start 字元。當設定 IXON 時可被識別,不再作為輸入傳遞。  
VSUSP :(032, SUB, Ctrl-Z) 掛起字元。傳送 SIGTSTP 訊號。當設定 ISIG 時可被識別,不再作為輸入傳遞。  
VDSUSP :(not in POSIX; not supported under Linux; 031, EM, Ctrl-Y) 延時掛起訊號。當用戶程式讀到這個字元時,傳送 SIGTSTP 訊號。當設定 IEXTEN 和 ISIG,並且系統支援作業管理時可被識別,不再作為輸入傳遞。  
VLNEXT :(not in POSIX; 026, SYN, Ctrl-V) 字面上的下一個。引用下一個輸入字元,取消它的任何特殊含義。當設定 IEXTEN 時可被識別,不再作為輸入傳遞。  
VWERASE :(not in POSIX; 027, ETB, Ctrl-W) 刪除詞。當設定 ICANON 和 IEXTEN 時可被識別,不再作為輸入傳遞。  
VREPRINT :(not in POSIX; 022, DC2, Ctrl-R) 重新輸出未讀的字元。當設定 ICANON 和 IEXTEN 時可被識別,不再作為輸入傳遞。  
VDISCARD :(not in POSIX; not supported under Linux; 017, SI, Ctrl-O) 開關:開始/結束丟棄未完成的輸出。當設定 IEXTEN 時可被識別,不再作為輸入傳遞。  
VSTATUS :(not in POSIX; not supported under Linux; status request: 024, DC4, Ctrl-T).  
這些符號下標值是互不相同的,除了 VTIME,VMIN 的值可能分別與 VEOL,VEOF 相同。 (在 non-canonical 模式下,特殊字元的含義更改為延時含義。MIN 表示應當被讀入的最小字元數。TIME 是以十分之一秒為單位的計時器。如果同時設定了它們,read 將等待直到至少讀入一個字元,一旦讀入 MIN 個字元或者從上次讀入字元開始經過了 TIME 時間就立即返回。如果只設置了 MIN,read 在讀入 MIN 個字元之前不會返回。如果只設置了 TIME,read 將在至少讀入一個字元,或者計時器超時的時候立即返回。如果都沒有設定,read 將立即返回,只給出當前準備好的字元。) 
 MIN與TIME組合有以下四種:


1、 MIN = 0 , TIME =0
              有READ立即回傳
              否則傳回 0 ,不讀取任何字元
2、 MIN = 0 , TIME >0
              READ 傳回讀到的字元,或在十分之一秒後傳回TIME
       若來不及讀到任何字元,則傳回0
3、 MIN > 0 , TIME =0
              READ 會等待,直到MIN字元可讀
4、 MIN > 0 , TIME > 0
              每一格字元之間計時器即會被啟動
              READ 會在讀到MIN字元,傳回值或TIME的字元計時(1/10秒)超過時將值傳回