1. 程式人生 > >Linux作業系統下的串列埠通訊學習筆記

Linux作業系統下的串列埠通訊學習筆記

一、什麼是串列埠通訊

串列埠通訊是指計算機主機與外設之間以及主機系統與主機系統之間資料的序列傳送。使用串列埠通訊時,傳送和接收到的每一個字元實際上都是一次一位的傳送的,每一位為1或者為0。

二、串列埠通訊的分類

串列埠通訊可以分為同步通訊和非同步通訊兩類。同步通訊是按照軟體識別同步字元來實現資料的傳送和接收,非同步通訊是一種利用字元的再同步技術的通訊方式。

2.1同步通訊

同步通訊是一種連續序列傳送資料的通訊方式,一次通訊只傳送一幀資訊。這裡的資訊幀與非同步通訊中的字元幀不同,通常含有若干個資料字元。如圖:

單同步字元幀結構

+-----+------+-------+------+-----+--------+-------+-------+

|同步|資料 |資料 |資料 | ... |資料 |CRC1|CRC2|

|字元|字元1|字元2|字元3| |字元N| | |

+-----+------+-------+------+-----+--------+-------+-------+

雙同步字元幀結構

+-----+--------+------+-------+---+-------+-------+--------+

|同步 |同步 |資料 |資料 | ... |資料 |CRC1|CRC2|

|字元1|字元2|字元1|字元2| |字元N| | |

+-----+--------+------+-------+---+-------+-------+--------+

它們均由同步字元、資料字元和校驗字元(CRC)組成。其中同步字元位於幀開頭,用於確認資料字元的開始。資料字元在同步字元之後,個數沒有限制,由所需傳輸的資料塊長度來決定;校驗字元有1到2個,用於接收端對接收到的字元序列進行正確性的校驗。

同步通訊的缺點是要求傳送時鐘和接收時鐘保持嚴格的同步。

2.2非同步通訊

非同步通訊中,資料通常以字元或者位元組為單位組成字元幀傳送。字元幀由傳送端逐幀傳送,通過傳輸線被接收裝置逐幀接收。傳送端和接收端可以由各自的時鐘來控制資料的傳送和接收,這兩個時鐘源彼此獨立,互不同步。

接收端檢測到傳輸線上傳送過來的低電平邏輯"0"(即字元幀起始位)時,確定傳送端已開始傳送資料,每當接收端收到字元幀中的停止位時,就知道一幀字元已經發送完畢。

在非同步通行中有兩個比較重要的指標:字元幀格式和波特率。

(1)字元幀,由起始位、資料位、奇偶校驗位和停止位組成。如圖:

無空閒位字元幀

+--+---+---+---+---+--+--+--+--+--+--+--+---+---+---+--+--+

|D7|0/1| 1 | 0 |D0|D1|D2|D3|D4|D5|D6|D7|0/1| 1 | 0 |D0|D1|

+--+---+---+---+--+--+--+--+--+--+--+--+---+---+---+--+--+

奇偶 停 起 奇偶 停 起

校驗 止 始 校驗 止 始

位 位 位 位

有空閒位字元幀

+---+---+--+--+--+--+--+--+--+--+---+---+---+---+---+---+--+

| 1 | 0 |D0|D1|D2|D3|D4|D5|D6|D7|0/1| 1 | 1 | 1 | 1 | 0 |D0|

+---+---+--+--+--+--+--+--+--+--+---+---+---+---+---+---+--+

空 起 奇偶 停 空 閒 位 起

閒 始 校驗 止 始

位 位 位 位

1.起始位:位於字元幀開頭,佔1位,始終為邏輯0電平,用於向接收裝置表示傳送端開始傳送一幀資訊。

2.資料位:緊跟在起始位之後,可以設定為5位、6位、7位、8位,低位在前高位在後。

3.奇偶校驗位:位於資料位之後,僅佔一位,用於表示序列通訊中採用奇校驗還是偶校驗。

(2)波特率,波特率是每秒鐘傳送二進位制數碼的位數,單位是b/s。

非同步通訊的優點是不需要傳送同步脈衝,字元幀長度也不受到限制。缺點是字元幀中因為包含了起始位和停止位,因此降低了有效資料的傳輸速率。

三、什麼是RS-232

RS-232-C 介面(又稱 EIA RS-232-C)它是在 1970 年由美國電子工業協會(EISB2.0、網絡卡介面、Modem介面、VGA介面、擴充套件塢、IEEE 1394以及六合一讀卡器,常用的埠一應俱全。

HP Ze2022AP

Ze2022AP外觀上採用了惠普經典的Pavilion DV1000的模具,模具成熟,外觀無可挑剔。銀白色的主色調,再經過磨砂處理,視覺效果和觸感都相當理想。Ze2202AP外形方方正正,稜角分明,同時惠普還頗費心思地在前後採用了傾斜的切割,整個外形更顯精細動感。

Ze2202AP的埠主要分佈在左右兩端,右側有2個USB介面、1個1394介面, SD/MS/MMC多功能儲存卡讀取插槽,還有COMBO光碟機,以及S埠。左側從後到前分佈電源介面、VGA輸出介面、基座擴充套件介面、 RJ11/RJ45網路介面,1個USB介面,以及PCMCIA擴充套件插槽。除此之外,這款機型同樣配備擴充套件埠,擴充套件性無疑是相當強大的。

ThinkPad R50e 1834HC1

IBM的R系列實際上是T系列的經濟版本,有人將其形象地表示為“偷工減料版的T”,外形上依然承襲了IBM“小黑”一貫的酷。這款R50e頂蓋材料採用了ABS工程塑料,但藉助不錯的頂蓋框架,強度還是不錯的。

R150e的埠相對齊全,不僅有ThinkPad經典的指定杆,介面上還包括RJ45/11網路介面、兩個USB介面、PC卡插槽、VGA介面、S視訊埠,但沒有IEEE1394介面,對經常使用數碼產品的消費者無疑是個壞訊息。

五、全雙工與半雙工

1.全雙工,表示機器可以同時傳送資料也可以接收資料,有兩個獨立的資料通道(一個用於傳送,一個用於接收)

2.半雙工,表示機器不能在傳送資料的同時也接收資料。

六、流量控制

1.使用軟體方法

使用特殊的字元來標記資料流的開始和結束,比如XON,DC1,八進位制021來標誌開始,用X0FF,DC3,八進位制023來標誌結束。

2.使用硬體方法

使用RS232的CTS和RTS訊號來代替特殊字元控制。當接收方準備接收更多資料時,設定CTS為0,反之設定成1。對應的傳送端準備傳送資料時,設定RTS為0。

七、串列埠的訪問

串列埠裝置在LINUX下與所有裝置一樣都是通過裝置檔案來進行訪問。

7.1開啟串列埠

LINUX系統下串列埠裝置是通過open函式來開啟的,不過需要注意的是,一般使用者是沒有許可權訪問裝置檔案的,需要將開啟的串列埠裝置的訪問許可權設定成一般使用者可以訪問的許可權。

open函式

標頭檔案

#include

#include

#include

函式原型

int open(const char *pathname, int oflag, .../*, mode_t mode*/);

引數

const char *pathname - 要開啟檔案的檔名稱,例如/dev/ttyS0

int oflag - 檔案開啟方式,可用標誌如下:

O_RDONLY 以只讀方式開啟檔案

O_WRONLY 以只寫方式開啟檔案

O_RDWR 以讀寫方式開啟檔案

O_APPEND 寫入資料時新增到檔案末尾

O_CREATE 如果檔案不存在則產生該檔案,使用該標誌需要設定訪問許可權位mode_t

O_EXCL 指定該標誌,並且指定了O_CREATE標誌,如果開啟的檔案存在則會產生一個錯誤

O_TRUNC 如果檔案存在並且成功以寫或者只寫方式開啟,則清除檔案所有內容,使得檔案長度變為0

O_NOCTTY 如果開啟的是一個終端裝置,這個程式不會成為對應這個埠的控制終端,如果沒有該標誌,任何一個輸入,例如鍵盤中止訊號等,都將影響程序。

O_NONBLOCK 該標誌與早期使用的O_NDELAY標誌作用差不多。程式不關心DCD訊號線的狀態,如果指定該標誌,程序將一直在休眠狀態,直到DCD訊號線為0。

O_SYNC 對I/O進行寫等待

返回值

成功返回檔案描述符,如果失敗返回-1

例如:以可讀寫方式開啟/dev/ttyS0裝置

int fd; /* 檔案描述符 */

fd = open("/dev/ttyS0", O_RDWR | 0_NOCTTY | O_NONBLOCK);

7.2關閉串列埠

Linux系統下通過close函式來關閉串列埠裝置

close函式

標頭檔案

#include

函式原型

int close(int filedes);

引數

int filedes - 檔案描述符

返回值

成功返回0,否則返回-1

例如:關閉開啟的串列埠裝置fd

int ret; /* 返回標誌,用於判斷是否正常關閉裝置 */

ret = close(fd);

7.3寫串列埠

寫串列埠是通過write函式來完成的

write函式

標頭檔案

#include

函式原型

ssize_t write(int filedes, const void *buff, size_t nbytes);

引數

int filedes - 檔案描述符

const void *buff - 儲存寫入資料的資料緩衝區

size_t nbytes - 寫入資料位元組數

返回值

ssize_t - 返回寫入資料的位元組數,該值通常等於nbytes,如果寫入失敗返回-1

例如:向終端裝置傳送初始化命令

int n = 0; /* 寫入位元組數 */

n = write(fd, "ATZ/r", 4);

if(n == -1)

{

fprintf(stderr, "Wirte ATZ command error./n");

}

7.4讀串列埠

讀串列埠是通過read函式來完成的

read函式

標頭檔案

#include

函式原型

ssize_t read(int filedes, void *buff, size_t nbytes);

引數

int filedes - 檔案描述符

void *buff - 儲存讀取資料的資料緩衝區

size_t nbytes - 需要讀取的位元組數

返回值

ssize_t - 成功讀取返回讀取的位元組數,否則返回-1

注意,在對串列埠進行讀取操作的時候,如果是使用的RAW模式,每個read系統呼叫將返回當前序列輸入緩衝區中存在的位元組數。如果沒有資料,將會一致阻塞到有字元達到或者間隔時鐘到期,或者發生錯誤。如果想使read函式在沒有資料的時候立即返回則可以使用fcntl函式來設定檔案訪問屬性。例如:

fcntl(fd, F_SETFL, FNDELAY);

這樣設定後,當沒有可讀取的資料時,read函式立即返回0。

通過fcntl(fd, F_SETFL, 0)可以設定回一般狀態。

例如:從終端讀取5個位元組的應答資料

int nRead; /* 從終端讀取的位元組數 */

char buffer[256]; /* 接收緩衝區 */

nRead = read(fd, buffer, 5);

if(nRead == -1)

{

fprintf(stderr, "Read answer message error./n");

}

八、終端配置

8.1 POSIX終端介面

大多數系統都支援POSIX終端介面,POSIX終端通過一個termios結構來進行控制,該結構定義在termios.h檔案中。

termios結構

struct termios

{

tcflag_t c_iflag; /* 輸入選項標誌 */

tcflag_t c_oflag; /* 輸出選項標誌 */

tcflag_t c_cflag; /* 控制選項標誌 */

tcflag_t c_lflag; /* 本地選項標誌 */

cc_t c_cc[NCCS]; /* 控制特性 */

};

c_iflag成員

Flag Description

GNBRK 忽略輸入中的BREAK狀態

BRKINT 如果設定了IGNBRK,將忽略BREAK。如果沒有設定,但是設定了BRKINT,那麼BREAK將使得輸入和輸出佇列被重新整理,如果終端是一個前臺程序組的控制終端,這個程序組中所有程序將收到SIGINT訊號。如果既未設定IGNBRK也未設定BRKINT,BREAK將視為NUL同義字符,除非設定了PARMRK,這種情況下被視為序列/377/0/0

IGNPAR 忽略楨錯誤和奇偶校驗錯誤

PARMRK 如果沒有設定IGNPAR,在有奇偶校驗錯誤或者楨錯誤的字元前插入/377/0。如果既沒有設定IGNPAR也沒有設定PARMRK,將所有奇偶校驗錯誤或者楨錯誤的字元視為/0。

INPCK 啟用輸入奇偶校驗檢測。

ISTRIP 去掉第八位。

INLCR 將輸入的NL翻譯為CR。

IGNCR 忽略輸入中的回車。

ICRNL 將輸入中的回車翻譯為新行字元(除非設定了IGNCR)。

IUCLC (不屬於POSIX)將輸入中的大寫字母對映為小寫字母。

IXON 啟用輸出的XON/XOFF流控制

IXANY (不屬於POSIX。1;XSI)允許任何字元來重新開始輸出。

IXOFF 啟用輸入的XON/XOFF流控制

IMAXBEL (不屬於POSIX)當輸入佇列滿時響鈴。LINUX沒有實現該位,總是將其視為已設定。

c_oflag成員

Flag Description

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成員

Flag Description

CBAUD (不屬於POSIX)波特率掩碼(4+1位)。

CBAUDEX (不屬於POSIX)擴充套件的波特率掩碼(1位),包含在CBAUD中。

CSIZE 字元長度掩碼。取值為CS5,CS6,CS7或CS8。

CSTOPB 設定兩個停止位。

CREAD 開啟接受者。

PARENB 允許輸出產生奇偶資訊以及輸入的奇偶校驗。

PARODD 輸入和輸出是奇校驗

HUPCL 在最後一個程序關閉裝置後,降低MODEM控制線(結束通話)。

CLOCAL 忽略MODEM控制線。

LOBLK (不屬於POSIX)從非當前SHELL層阻塞輸出(用於sh1)。

CIBAUD (不屬於POSIX)輸入速度的掩碼。CIBAUD各位的值與CBAUD各位相同,左移了IBSHIFT位。

CRTSCTS (不屬於POSIX)啟用RTS/CTS(硬體)控制流。

c_lflag成員

Flag Description

ISIG 當接收到字元INTR,QUIT,SUSP或DSUSP時,產生相應的訊號。

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和ECHORPT一樣。

DEFECHO (不屬於POSIX)只在一個程序讀的時候回顯。

FLUSHO (不屬於POSIX;LINUX不支援)輸出被重新整理。這個標誌可以通過鍵入字元DISCARD來開啟和關閉。

NOFLSH 禁止產生SIGINT,SIGQUIT和SIGSUSP訊號時重新整理輸入和輸出佇列。

TOSTOP 向試圖寫控制終端的後臺程序組傳送SIGTTOU訊號。

PENDIN (不屬於POSIX;LINUX不支援)在讀入一個字元時,輸入佇列中的所有字元被重新輸出。(bash用他來處理typeahead)。

IEXTEN 啟用實現自定義的輸入處理。這個標誌必須與ICANON同時使用,才能解釋特殊字元EOL2,LNEXT,REPRINT和WERASE,IUCLC標誌才有效。

c_cc陣列成員

Flag Description

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 模式讀的最小字元數。 VEOL (0, NUL) 附加的行尾字元。當設定 ICANON 時可被識別。 VTIME 非 canonical 模式讀時的延時,以十分之一秒為單位。 VEOL2 (not in POSIX; 0, NUL) 另一個行尾字元。當設定 ICANON 時可被識別。

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).

8.2設定波特率

對於波特率的設定通常使用cfsetospeed和cfsetispeed函式來完成。獲取波特率資訊是通過cfgetispeed和cfgetospeed函式來完成的。

cfsetospeed函式

標頭檔案:

#include

函式原型:

int cfsetospeed(struct termios *termptr, speed_t speed);

引數:

struct termios *termptr - 指向termios結構的指標

speed_t speed - 需要設定的輸出波特率

返回值:

如果成功返回0,否則返回-1

cfsetispeed函式

標頭檔案:

#include

函式原型:

int cfsetispeed(struct termios *termptr, speed_t speed);

引數:

struct termios *termptr - 指向termios結構的指標

speed_t speed - 需要設定的輸入波特率

返回值:

如果成功返回0,否則返回-1

cfgetospeed函式

標頭檔案:

#include

函式原型:

speed_t cfgetospeed(const struct termios *termptr);

引數:

const struct termios - 指向termios結構的指標

返回值:

返回輸出波特率

cfgetispeed函式

標頭檔案:

#include

函式原型:

speed_t cfgetispeed(const struct termios *termptr);

引數:

const struct termios *termptr - 指向termios結構的指標

返回值:

返回輸入波特率

波特率常量:

CBAUD 掩碼

B0 0波特

B50 50波特

B75 75波特

B110 100波特

B134 134波特

B150 150波特

B200 200波特

B300 300波特

B600 600波特

B1200 1200波特

B1800 1800波特

B2400 2400波特

B9600 9600波特

B19200 19200波特

B38400 38400波特

B57600 57600波特

B115200 115200波特

8.3設定字元大小

設定字元的大小通過設定c_cflag標誌位來實現的。

例如:

option.c_cflag &= ~CSIZE;

option.c_cflag |= CS7;

8.4設定奇偶校驗

對於奇偶校驗是需要手工設定的,常用的設定方式如下:

No parity (8N1):

options.c_cflag &= ~PARENB

options.c_cflag &= ~CSTOPB

options.c_cflag &= ~CSIZE;

options.c_cflag |= CS8;

Even parity (7E1):

options.c_cflag |= PARENB

options.c_cflag &= ~PARODD

options.c_cflag &= ~CSTOPB

options.c_cflag &= ~CSIZE;

options.c_cflag |= CS7;

Odd parity (7O1):

options.c_cflag |= PARENB

options.c_cflag |= PARODD

options.c_cflag &= ~CSTOPB

options.c_cflag &= ~CSIZE;

options.c_cflag |= CS7;

Space parity is setup the same as no parity (7S1):

options.c_cflag &= ~PARENB

options.c_cflag &= ~CSTOPB

options.c_cflag &= ~CSIZE;

options.c_cflag |= CS8;

8.5獲取和設定終端屬性

設定和獲取終端控制屬性是通過tcgetattr和tcsetattr兩個函式來完成的

tcgetattr函式

標頭檔案:

#include

函式原型:

int tcgetattr(int filedes, struct termios *termptr);

引數:

int filedes - 檔案描述符

struct termiso *termptr - 指向termios結構的指標,

返回值:

如果成功返回0,否則返回-1

tcsetattr函式

標頭檔案:

#include

函式原型:

int tcsetattr(int filedes, int opt, const struct termios *termptr);

引數:

int filedes - 檔案描述符

int opt - 選項值,可以為下面三個值之一

TCSANOW - 不等資料傳輸完畢就改變屬性

TCSADRAIN - 等待所有資料傳輸結束才改變屬性

TCSAFLUSH - 清空輸入輸出緩衝區並且是設定屬性

const struct termios *termptr - 指向termios結構的指標,

返回值:

成功返回0,否則返回-1

九、常用設定

9.1設定規範模式

規範模式是面向行的輸入方式,輸入字元被放入用於和使用者互動可以編輯的緩衝區內,直接到讀入回車或者換行符號時才結束。

可以通過如下方式來設定

option.c_lflag |= (ICANON | ECHO | ECHOE);

9.2設定原始輸入模式

原始輸入模式是沒有處理過的,當接收資料時,輸入的字元在它們被接收後立即被傳送,使用原始輸入模式時候,一般可以選擇取消ICANON,ECHO,ECHOE和ISIG選項。

例如:

option.c_lflag &= ~(ICANON | ECHO | ECHOE);

9.3設定輸入奇偶選項

當啟用c_cflag中的奇偶校驗後,應該啟用輸入的奇偶校驗。與之相關的標誌有INPCK,IGNPAR,PARMRK和ISTRIP。一般是通過選擇INPCK和ISTRIP啟用檢驗和移除奇偶位。

例如:

option.c_iflag |= (INPCK | ISTRIP);

9.4設定軟體控制流

軟體控制流通過IXON,IXOFF和IXANY標誌來設定

例如:

option.c_iflag |=(IXON | IXOFF | IXANY);

9.5選擇預處理輸出

通過OPOST標誌來設定預處理的輸出

例如:

option.c_oflag |= OPOST;

9.6選擇原始資料輸出

原始資料的輸出通過設定c_oflag的OPOST標誌

例如:

option.c_oflag &= ~OPOST;

9.7設定軟體流控制字元

軟體流控制字元是通過c_cc陣列中的VSTART和VSTOP來設定的,一般來說,它們應該被設定城DC1(021八進位制)和DC3(023八進位制),分別表示ASCII碼的XON和XOFF字元。

9.8設定讀超時

c_cc陣列中的VMIN指定了最少讀取的字元數,如果設定為0,那麼VTIME就指定了讀取每個字元的等待時間。VTIME是以1/10秒為單位指定接收字元的超時時間的,如果VTIME設定為0,而埠沒有用open或者fcntl設定為 NONBLOCK,那麼read操作將會阻塞不確定的時間。

十、參考資料

1.《Serial Programming Guide for POSIX Operating Systems》5th Edition Michael R.Sweet

2.《Linux 下串列埠程式設計入門》左錦

3.《Advanced Programming in the UNIX Environment》 W.Richard Stevens

4.《Linux Serial Programming HOWTO》

5.《Unix Systems Programming》Kay A.Robbins & Steven Robbins

6.《Linux Programming by Example》Arnold Robbins

7.《Linux Programmer's Manual》
(e129)