POSIX 串列埠程式設計指南

SoldierJazz2019發表於2017-05-20

介紹


POSIX 串列埠程式設計指南將教會你在你的 UNIX 工作站或者 PC 上面如何成功、有效以及可移植性的對串列埠程式設計。每一章提供了使用 POSIX 終端控制函式的程式設計例程,可以基本不經修改地工作在 IRIX®, HP-UX, SunOS®, Solaris®, Digital UNIX®, Linux® 以及其他大多數 UNIX 作業系統。你會發現作業系統之間的最大差異是串列埠裝置檔名和鎖檔案。
本指南分為以下章節和附錄:
  • 第一章 串列埠通訊基礎
  • 第二章 串列埠配置
  • 第三章 MODEM 通訊
  • 第四章 高階串列埠程式設計
  • 附錄A 引腳分佈
  • 附錄B ASCII 碼

第一章 串列埠通訊基礎


本章介紹了串列埠通訊,RS-232 和 大多數計算機上使用的其他標準,以及如何通過 C 程式操作串列埠。

什麼是串列埠通訊


計算機一次傳輸資訊(資料)一位或多個位元位。序列是指傳輸資料一次只傳輸一位。當進行串列埠通訊時你傳送或者接收的每個字(即位元組或字元)一次傳送一位。每一位都是 on 或者 off。術語用mark代表 on,用 space代表 off。
串列埠資料速率使用 bits-per-second ("bps") 或者 baudot rate ("baud")。這表示一秒內可以傳輸多少邏輯 1 和 0。當波特率超過 1000,你會經常看到用 kilo baud 表示的速率。對於超過 1000000 的速率用 megabaud,或者 Mbps 來表示。
當涉及到串列埠裝置或者埠,它們被標識為“資料通訊裝置”("DCE")或者“資料終端裝置”("DTE")。兩者之間的區別很簡單 - 每個訊號對,如傳送和接收,是交叉的。

什麼是 RS-232


RS-232 是由 EIA 定義的用於串列埠通訊的標準電氣介面。RS-232 實際上有三種不同的型別(A,B和C),每一種對於 on 和 off 電平定義了不同的電壓範圍。最常用的種類是 RS-232C,它定義mark位電壓範圍:-3V~-12V 和space位電壓範圍:+3V~+12V。RS-232C 規範上說,這些訊號可以傳輸 25英尺(8m),通常你可以傳輸更遠一些只要波特率足夠低。
除了資料輸入和輸出資料線,還有其他提供時序、狀態與握手的訊號線。這裡我們僅列舉最為常見的 DB-9 介面分佈圖,引腳和功能描述如下所示:
  • 1 - DCD - 資料載波檢測
  • 2 - RXD - 接收資料
  • 3 - TXD - 傳送資料
  • 4 - DTR - 資料終端就緒
  • 5 - GND - 地
  • 6 - DSR - 資料裝置就緒
  • 7 - RTS - 請求傳送
  • 8 - CTS - 清除傳送
  • 9 - RI - 振鈴指示
你還可能遇到 RS-422 以及 RS-485 串列埠標準。RS-422 使用更低電壓與差分訊號允許線纜長達 1000英尺(300m)。在實際應用中,使用 TTL 電平逐漸成為趨勢,在 MCU  與串列埠轉接晶片提供的串列埠中比較常見,此時mark 電平:+5V或+3.3V等,space位:0V(邏輯地)。

訊號定義


RS-232 標準針對串列埠通訊定義了18種不同的訊號。其中,在 UNIX 環境下通常只有 6 種可用。

GND - 邏輯地
從技術上講,邏輯接地不是訊號,但沒有它,其他訊號就不能工作。從根本上說,邏輯地充當一個參考電壓,從而知道哪些電壓為正或負。

TXD - 傳送資料
mark 電平為邏輯 1,space 電平為邏輯 0。注意 RS232 電平與 TTL 電平反相。

RXD - 接收資料
同樣的,mark 電平為邏輯 1,space 電平為邏輯 0。注意 RS232 電平與 TTL 電平反相。

DCD - 資料載波檢測
DCD 訊號接收自串列埠線纜的另一端的計算機或裝置。訊號線低電平表示計算機或裝置當前已連線或線上。DCD 不經常使用。

DTR - 資料終端就緒
DTR 訊號用於通知對端計算機或裝置己方已就緒(space 電平)或未就緒(mark 電平)。DTR 通常在開啟串列埠時自動使能。

CTS - 清除傳送
CTS 訊號接收自串列埠線纜的另一端。訊號線 space 電平表示可以己方可以傳送資料。CTS 通常用於串列埠資料流控。

RTS - 請求傳送
RTS 設定為 space 電平表示己方準備好就接收資料。一般與 CTS 一起用於串列埠流控,通常被設定為預設有效狀態。

非同步通訊


解析串列埠資料需要確定一個字元的結束與下一個字元的開始。本章專門講述非同步串列埠資料。
在非同步模式下串列埠資料線保持在 mark 狀態(邏輯 '1')直到有字元傳送,也即串列埠的空閒態是 mark 態。每個位元組起始位在前,位元組的每一位緊隨其後,一位可選校驗位以及一位或者兩位停止位。起始位始終是 space 電平(邏輯'0'),通知對方有新串列埠資料可用。資料可以同時傳送和接收,因此稱為“非同步”。

可選校驗位是資料位的簡單累加和,指示資料是否包含奇數或者偶數個 1。偶校驗時,如果一個字元中有偶數個 1 那麼校驗位是 0。奇校驗時,如果一個字元中有奇數個 1 那麼校驗位是 0。除此之外,你還可能聽過術語 space 校驗,mark 校驗以及無校驗。Space 校驗指示校驗位永遠是 0,而 mark 校驗是指校驗位一直為 1。無校驗意味著沒有校驗位存在或被傳輸。
剩下的位稱作停止位。在字元之間可能會有 1,1.5 或者 2 位停止位並且這些位總為 1。停止位過去用於騰出時間為硬體處理之前的資料,但現在只用於接收字元與硬體裝置的同步。非同步資料格式通常表達成“8N1”,“7E1”等。

什麼是全雙工和半雙工


全雙工是指裝置可以同時傳送和接收資料 - 有兩個獨立資料通道(一路輸入,一路輸出)。
半雙工是指裝置不能同時傳送和接收資料。這通常意味著只有一路可以通訊。這並不代表有任何的 RS-232 訊號未被使用,相反,這通常意味著使用的一些非 RS-232 標準的通訊鏈路不支援全雙工操作。

流控


在兩個串列埠裝置間傳輸資料時經常有必要進行資料流控。這可能是受到中間串列埠通訊線路、其中一個裝置或者其他儲存介質的限制。非同步資料流控通常使用的有兩種方法。
第一種方法通常稱為“軟體”流控,使用特殊字元開始(XON or DC1)或者停止(XOFF or DC3)資料流。這些字元定義參見 ASCII 碼錶。這些碼值在傳輸文字資訊時很有用,但不能在未經特殊程式設計時用於傳輸其他型別的資訊。
第二種方法稱作“硬體”流控,使用 CTS 和 RTS 訊號線取代特殊字元。當接收方準備好接收資料時會將 RTS 置為 space 電壓以請求對方傳送資料,當未準備好時置為 mark 電壓,因此傳送方會通過檢測 CTS 電平狀態判斷是否可以傳送資料。由於硬體流控使用獨立的訊號集合,因此比軟體流控速度要快。

Break訊號


通常情況下收發資料訊號線保持在 mark 電平狀態直到傳輸一個新位元組。如果訊號拉低至 space 電壓一段時間,通常是 1/4 到 1/2 秒,那麼就說一個 break 條件滿足。一個 break 訊號有時用於復位通訊或者改變通訊硬體的操作模式,如 MODEM。

同步通訊


不同於非同步資料,同步資料以恆定位元流顯示。為了讀取資料,通訊方必須提供或接收一通用位作為時鐘使傳送和接收者同步
儘管有時鐘同步,通訊方也必須以某種方式標記資料開始。實現的最常用方法是使用像“序列資料鏈路控制”(“SDLC”)或者“高速資料鏈路控制”(“HDLC”)的資料包協議。
每種協議定義了一定的位序列來表示資料包的開始和結束,也定義了沒有資料時的位序列。這些位序列使得通訊方明確資料包的開始。由於同步協議不使用每位元組同步位它們比非同步通訊有至少25%的效能提升並且在多餘兩個串列埠的情形下更適合於遠端網路和配置。
儘管同步通訊有速度優勢,由於需要額外的軟硬體大多數 RS-232 硬體不支援。

程式設計指南的其他章節內容我先前翻譯過,但是由於內容和部分知識點較為陳舊,因此我用其他整錄的部落格系列 -《Linux 串列埠程式設計》中進行詳細講解,感興趣的可以移步至:


相關文章