Linux 串列埠程式設計 深入瞭解 termios
前言
這一系列串列埠程式設計重點在應用層程式設計,但是在講解原理與相關概念時需要對驅動框架有個基礎的認識。如果只是淺嘗輒止,以後在遇到串列埠驅動與應用層程式除錯難免遇到瓶頸。關於 tty驅動架構參見我的其他部落格:Linux tty驅動程式架構。有時瞭解下底層以及實現方式對於應用層程式設計的幫助也是大有裨益的。之前部落格講了終端,tty,控制檯等概念以及區別,因此在串列埠程式設計相關章節中提及串列埠,有時也會用終端,tty等來替代,注意它們實際上所指是相同的。
在 Linux 中可以通過一組函式呼叫(通用終端介面,簡稱GTI)來控制終端,這組函式呼叫與用於讀寫資料的函式是分離的,這就使得讀寫資料的介面非常簡潔,同時又允許可以對終端或串列埠的行為進行更精細地控制。但由於需要支援大量不同型別的硬體,GTI 中實現的 IO 介面卻不簡潔。
詳解 termios
termios 是在 POSIX 規範中定義的標準介面,它類似與 System V 中的 termio 介面。通過設定 termios 型別的資料結構中的值和使用一小組函式呼叫,就可以對終端介面進行控制。termios 的結構體定義以及相關函式呼叫參見 termios.h 標頭檔案。termios 結構的定義如下:
如定義所示,影響終端的引數按照不同模式分成如下幾類:
- 輸入模式
- 輸出模式
- 控制模式
- 本地模式
- 線路規程
- 特殊控制字元
- 輸入速率
- 輸出速率
輸入模式
輸入模式控制輸入資料(終端驅動程式從序列口或鍵盤接收到的字元)在被傳遞給程式之前的處理方式。通過設定 termios 結構中 c_iflag 成員的標誌對它們進行控制。所有的標誌都被定義為巨集,這也是所有終端模式都採用的方法。可用於 c_iflag 成員的巨集如下所示:
- BRKINT:當在輸入行中檢測到一個終止狀態(連線丟失)時,產生一箇中斷。
- IGNBRK:忽略輸入行中的終止狀態。
- ICRNL:將接收到的回車符轉換為新行符。
- IGNCR:忽略接收到的回車符。
- INLCR:將接收到的新行符轉換為回車符。
- IGNPAR:忽略奇偶校驗錯誤的字元。
- INPCK:對接收到的字元執行奇偶校驗。
- PARMRK:對奇偶校驗錯誤做出標記。
- ISTRIP:將所有接收到的字元裁剪為 7 位元位。
- IXOFF:對輸入啟動軟體流控。
- IXON:對輸出啟動軟體流控。
輸出模式
輸出模式控制輸出字元的處理方式,即由程式傳送出去的字元在傳遞到序列口或螢幕之前是如何處理的。可用於 c_oflag 成員的巨集如下所示:
- OPOST:開啟輸出處理功能。
- ONLCR:將輸出中的換行符轉換為回車/換行符。
- OCRNL:將輸出中的回車符轉換為新行符。
- ONOCR:在第0列不輸出回車符。
- ONLRET:不輸出回車符。
- OFILL:傳送填充字元以提供延時。
- OFDEL:用DEL而不是NULL字元作為填充字元。
- NLDLY:新行符延時選擇。
- CRDLY:回車符延時選擇。
- TABDLY:製表符延時選擇。
- BSDLY:退格符延時選擇。
- VTDLY:垂直製表符延時選擇。
- FFDLY:換頁符延時選擇。
控制模式
- CLOCAL:忽略所有調變解調器的狀態行。
- CREAD:啟動字元接收器。
- CS5:發收採用5位資料位。
- CS6:發收採用6位資料位。
- CS7:發收採用7位資料位。
- CS8:發收採用8位資料位。
- CSTOPB:字元采用兩位停止位。
- HUPCL:關閉時結束通話調變解調器。
- PARENB:使能奇偶校驗。
- PARODD:使用奇校驗。
本地模式
- ECHO:啟用輸入字元的本地回顯功能。
- ECHOE:接收到 ERASE 時執行退格、空格、退格的動作組合。
- ECHOK:接收到 KILL 字元時執行行刪除操作。
- ECHONL:回顯新行符。
- ICANON:啟用標準輸入處理。
- IEXTEN:啟用基於特定實現的函式。
- ISIG:啟用新號。
- NOFLSH:禁止清空佇列。
- TOSTOP:在試圖進行寫操作之前給後臺程式傳送一個訊號。
特殊控制字元
特殊控制字元是一些字元組合,如 Ctrl+C,當使用者鍵入這樣的組合鍵,終端會採取特殊處理方式。termios 中 c_cc 陣列將各種特殊字元對映到對應的支援函式。每個字元位置(陣列下標)由對應的巨集定義的。根據終端是否被設定為標準模式(即上節提到的 ICANON 標誌),陣列使用也分為標準與非標準兩種情形。
標準模式可以使用的陣列下標:
- VEOF:EOF 字元。
- VEOL:EOL 字元。
- VERASE:ERASE 字元。
- VINTR:INTR 字元。
- VKILL:KILL 字元。
- VQUIT:QUIT 字元。
- VSUSP:SUSP 字元。
- VSTART:START 字元。
- VSTOP:STOP 字元。
- VINTR:INTR 字元。
- VMIN:MIN 值。
- VQUIT:QUIT 字元。
- VSUSP:SUSP 字元。
- VTIME:TIME 值。
- VSTART:START 字元。
- VSTOP:STOP 字元。
字元 | 說明 |
---|---|
INTR | 該字元使終端驅動程式向與終端相連的程式傳送 SIGINT 訊號 |
QUIT | 該字元使終端驅動程式向與終端相連的程式傳送 SIGQUIT 訊號 |
ERASE | 該字元使終端驅動程式刪除輸入行中的最後一個字元 |
KILL | 該字元使終端驅動程式刪除整個輸入行 |
EOF | 該字元使終端驅動程式將輸入行中的全部字元傳遞給正在讀取輸入的應用程式。若輸入行為空,read為0 |
EOL | 作用類似於行結束符,效果和常用的新行符相同 |
SUSP | 該字元使終端驅動程式向與終端相連的程式傳送SIGSUSP訊號,用於掛起當前應用程式 |
STOP | 字元作用“截流”,即阻止向終端的進一步輸出。用於支援 XON/XOFF 流控,通常被設定為 ASCII 的XOFF |
START | 重新啟動被 STOP 暫停的輸出,通過被設定為 ASCII 的 XON 字元。 |
VTIME 和 VMIN
TIME值和MIN值只能用於非標準模式,關於二者的使用詳見部落格:Linux termios 串列埠程式設計之 VTIME與VMIN。
SHELL下使用 stty 訪問終端模式
在 shell 下可以使用 stty 可以訪問終端 termios。如:
#列印串列埠裝置 ttyUSB0 設定情況。
root@ubuntu:/# stty -F /dev/ttyUSB0 -a
#設定 ttyUSB0 為 115200 波特率,8位資料位。
root@ubuntu:/# stty -F /dev/ttyUSB0 ispeed 115200 ospeed 115200 cs8
在設定成功之後就可以通過 cat、echo 等 shell 命令對裝置進行讀寫了。
本篇重點在於介紹 termios 概念以及詳細模式標誌位等,大部分是不需要記憶的,使用頻率也很低。
關於 Linux 串列埠程式設計的其他文章,可以移步至以下連結:
- 《Linux 串列埠程式設計<一> 一些背景》
- 《Linux 串列埠程式設計<二> 深入瞭解 termios》
- 《Linux 串列埠程式設計<三> 使用termios與API 進行串列埠程式開發》
- 《Linux 串列埠程式設計<四> 串列埠裝置程式開發》
如果有其他想法或者疑問可以給我郵件或者評論~:-D
相關文章
- Linux 串列埠程式設計 使用termios與API進行串列埠程式開發Linux串列埠程式設計iOSAPI
- Linux串列埠程式設計Linux串列埠程式設計
- Linux 串列埠程式設計Linux串列埠程式設計
- Linux 串列埠程式設計 串列埠裝置程式開發Linux串列埠程式設計
- Linux下串列埠程式設計基礎Linux串列埠程式設計
- 你真的瞭解串列埠嗎(示波器串列埠波形分析)串列埠
- Linux 串列埠程式設計 一些背景Linux串列埠程式設計
- POSIX 串列埠程式設計指南串列埠程式設計
- VC++串列埠通訊程式設計詳解C++串列埠程式設計
- Android之串列埠程式設計Android串列埠程式設計
- Linux下串列埠通訊詳解(下)讀寫串列埠及關閉串列埠Linux串列埠
- ROS串列埠程式設計學習筆記ROS串列埠程式設計筆記
- Linux程式設計入門 - termios/keymap/terminal(轉)Linux程式設計iOS
- 深入瞭解Mybatis架構設計MyBatis架構
- Linux程式設計入門 - termios/keymap/terminal program(轉)Linux程式設計iOS
- 深入C#並行程式設計(1) -- 瞭解執行緒C#並行行程程式設計執行緒
- 深入瞭解Java社群程式Java
- Windows下的Win32串列埠程式設計WindowsWin32串列埠程式設計
- Linux下PCI轉串列埠卡及USB轉串列埠Linux串列埠
- linux 串列埠通訊Linux串列埠
- android串列埠程式Android串列埠
- 初級程式設計師應該瞭解的Linux命令程式設計師Linux
- VC++串列埠程式設計之簡訊應用開發(轉)C++串列埠程式設計
- 啟明雲端帶你瞭解4.3寸串列埠屏的應用串列埠
- 啟明雲端帶你瞭解2.1寸串列埠屏的應用串列埠
- 詳解linux下的串列埠通訊開發Linux串列埠
- 快速瞭解非同步程式設計 RxJava非同步程式設計RxJava
- 高效理解 FreeSql WhereDynamicFilter,深入瞭解設計初衷[.NET ORM]SQLFilterORM
- UART串列埠及Linux實現串列埠Linux
- linux串列埠命令列除錯Linux串列埠命令列除錯
- 使用串列埠連線到Linux串列埠Linux
- 更深入地瞭解 Linux 許可權Linux
- JavaScript——深入瞭解thisJavaScript
- 深入瞭解機器學習機器學習
- 深入瞭解原型原型
- 深入瞭解 NSURLSessionSession
- 串列埠通訊應用程式的解決方案 (轉)串列埠
- 初步瞭解C語言Windows程式設計C語言Windows程式設計