linux 串口 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秒)超過時將值 傳回
四、 與此結構體相關的函數
                (一)tcgetattr()
                        1.原型
                        int tcgetattr(int fd,struct termois & termios_p);
                        2.功能
                        取得終端介質(fd)初始值,並把其值 賦給temios_p;函數可以從後臺進
                        程中調用;但是,終端屬性可能被後來的前 臺進程所改變。
                       
                       
                (二)tcsetattr()
                        1.原型
                        int tcsetattr(int fd,int actions,const struct    termios
                        *termios_p);
                        2.功能
                        設置與終端相關的參數 (除非需要底層支持卻無法滿足),使用
                        termios_p 引用的 termios 結構。optional_actions (tcsetattr函數
                        的第二個參數)指定了什麼時候改變會起作用:
                              * TCSANOW:改變立即發生 
                              * TCSADRAIN:改變在所有寫入 fd 的輸出都被傳輸後生效。這個
                                函數應當用於修改影響輸出的參數時使用。(當前輸出完成時將
                                值改變) 
                              * TCSAFLUSH :改變在所有寫入 fd 引用的對象的輸出都被傳輸後
                                生效,所有已接受但未讀入的輸入都在改變發生前丟棄(同
                                TCSADRAIN,但會捨棄當前所有值)。
                (三)tcsendbreak()
                  傳 送連續的 0 值比特流,持續一段時間,如果終端使用異步串行數據傳輸的
                話。如果 duration 是 0,它至少傳輸 0.25 秒,不會超過 0.5 秒。如果
                duration 非零,它發送的時間長度由實現定義。
                如果終端並非使用異步串行數據傳輸,tcsendbreak() 什麼都不做。
                (四)tcdrain()
                等待直到所有寫入 fd 引用的對象的輸出都被傳輸。
                (五)tcflush()
                丟棄要寫入 引用的對象,但是尚未傳輸的數據,或者收到但是尚未讀取的數據,
                取決於 queue_selector 的值:
               
                              * TCIFLUSH :刷新收到的數據但是不讀 
                              * TCOFLUSH :刷新寫入的數據但是不傳送 
                              * TCIOFLUSH :同時刷新收到的數據但是不讀,並且刷新寫入的數
                                據但是不傳送
                (六)tcflow()
                掛起 fd 引用的對象上的數據傳輸或接收,取決於 action 的值:
               
                              * TCOOFF :掛起輸出 
                              * TCOON :重新開始被掛起的輸出 
                              * TCIOFF :發送一個 STOP 字符,停止終端設備向系統傳送數
                                據 
                              * TCION :發送一個 START 字符,使終端設備向系統傳輸數據
                        打開一個終端設備時的默認設置是輸入和輸出都沒有掛起。
                       
                       
                (七)波特率函數
                被用來獲取和設置 termios 結構中,輸入和輸出波特率的值。新值不會馬上生
                效,直到成功調用了 tcsetattr() 函數。
                設 置速度爲 B0 使得 modem "掛機"。與 B38400 相應的實際比特率可以用
                setserial(8) 調整。
                輸 入和輸出波特率被保存於 termios 結構中。
                cfmakeraw 設置終端屬性如下:
                            termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|
                IGNCR|ICRNL|IXON);
                            termios_p->c_oflag &= ~OPOST;
                            termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
                            termios_p->c_cflag &= ~(CSIZE|PARENB);
                            termios_p->c_cflag |= CS8;
               
                1.cfgetospeed() 返回 termios_p 指向的 termios 結構中存儲的輸出波特率
                2.cfsetospeed() 設置 termios_p 指向的 termios 結構中存儲的輸出波特率爲
                speed。取值必須是以下常量之一:
                        B0        B50        B75        B110        B134        B150
                      B200        B300        B600        B1200        B1800
                   B2400        B4800        B9600        B19200        B38400
                   B57600        B115200        B230400
                其中:零值 B0 用來中斷連接。如果指定了 B0,不應當再假定存在連接。通常,
                這樣將斷開連接。CBAUDEX 是一個掩碼,指示高於 POSIX.1 定義的速度的那一些
                (57600 及以上)。因此,B57600 & CBAUDEX 爲非零。
                3.cfgetispeed() 返回 termios 結構中存儲的輸入波特率。
                4.cfsetispeed() 設置 termios 結構中存儲的輸入波特率爲 speed。如果輸入波
                特率被設爲0,實際輸入波特率將等於輸出波特率。
                五、 RETURN VALUE 返回值
                1.cfgetispeed() 返回 termios 結構中存儲的輸入波特率。
                2.cfgetospeed() 返回 termios 結構中存儲的輸出波特率。
                3.其他函數返回:
                  (1)0:成 功
                   (2)-1:失 敗,
                         並且爲 errno 置值來指示錯誤。
                注意 tcsetattr() 返回成功,如果任何所要求的修改可以實現的話。因此,當進
                行多重修改時,應當在這個函數之後再次調用 tcgetattr() 來檢測是否所有修改
                都成功實現。
                六、NOTES 注意
                Unix V7 以及很多後來的系統有一個波特率的列表,在十四個值 B0, ..., B9600
                之後可以看到兩個常數 EXTA, EXTB ("External A" and "External B")。很多系
                統將這個列表擴展爲更高的波特率。
                tcsendbreak 中非零的 duration 有不同的效果。SunOS 指定中斷 duration*N
                秒,其中 N 至少爲 0.25,不高於 0.5 。Linux, AIX, DU, Tru64 發送 duration
                微秒的 break 。FreeBSD, NetBSD, HP-UX 以及 MacOS 忽略 duration 的值。在
                Solaris 和 Unixware 中, tcsendbreak 搭配非零的 duration 效果類似於
                tcdrain。
                SEE ALSO 參見
                stty(1), setserial(8)

發佈了137 篇原創文章 · 獲贊 31 · 訪問量 116萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章