發送回應模型應該是寫序列埠通訊最常遇到的,從這篇開始會分成幾篇來一步步完成這個模型的程式。
發送回應模型應該是寫序列埠通訊最常遇到的,從這篇開始會分成幾篇來一步步完成這個模型的程式。
定義
發送端傳送命令給接收端後,接收端依據命令處理後回應結果給發送端。例如電腦程式經由序列埠發送讀取區塊資料命令給 Mifare 讀卡機, Mifare 讀卡機收到命令後讀取卡片上特定區塊的資料,並將資料回傳給電腦程式。
基本邏輯
處理此類的程式最簡單的做法就是將發送到回應的整個程序在一個執行緒中完成,如果你將發送和回應分在不同的執行緒,例如像使用 DataReceived Event、或是採用 [Serial Port 系列(11) 基本篇 -- 利用執行緒讀取資料] 這樣的做法來寫發送回應,除非你的程式只有對應一個設備且在兩次發送的間隔夠長,不然真的就是自找麻煩而已。幾個原因如下:
(1) 當你在一個執行緒完成傳送到接收的動作,可以完整的確保只有一個命令在進行中,這樣的作法會簡化分析回傳資料完整性的程序,因為不論分幾段你收到的資料都是同一次命令回傳的東西。
(2) 如果你把傳送和接收分開在兩個執行緒,以下的慘劇可能就會發生:
(2-1) 如果你發送的比接收的快 (這是極有可能的,通常靠序列埠在通訊的設備都不可能有太快的處理速度,再加上傳輸的延遲),而且是 RS232 或 RS422 這種全雙工的通訊下,你兩次命令的回應可能會交錯在一起 -- 別忘了有可能會分段傳回來,那你該如何處理回應的資料,根本無從分辨。
(2-2) 如果你的序列通訊上的設備是串接的,這在 RS485 或 RS422 的應用上常出現,就是一條線上有好多設備要輪詢,一樣會產生回應資料交錯的可能性。
當然如果你在程式上的控制夠得心應手,的確可以分成兩個執行緒分別傳送接收又能保持一對一的特性 (其實就是讓兩個執行緒之間可以保持同步),但幹嘛要自找麻煩呢?因為最終做出來的效果是一樣的。
通訊協定假設
在開始寫程式之前,先來假設一個通訊協定才有辦法模擬較為真實的狀況,這個模擬的通訊協定主要在模擬 Mifare 讀卡機的基本功能。這只是個簡化的例子用來做這系列文章的程式演練,千萬不要當真!
(1) 開頭碼:固定為十進位 249
(2) 長度碼:接收者+命令+資料內容+XOR 的長度
(3) 接收者:0 代表由設備傳資料給電腦;1代表由電腦傳給設備
(4) 命令:對發送者而言,這代表它要求接收端執行的動作;接收端執行完後回應相同的命令碼。
(5) 資料:對發送者而言是命令的參數;對設備端而言則是回傳的資料。
(6) XOR:255 Xor 開頭碼 Xor 長度碼 Xor 接收者 Xor 命令 Xor 資料1 Xor 資料2 Xor…Xor 資料n ;用來確認資料的正確性。
【讀取某一個區塊 (Block) 的資料】
● 發送端內容
(1) 命令:十進位 81
(2) 資料 (1 Byte):要讀取的區塊編號 0~63 (十進位)
● 回應端內容
(1) 命令:十進位 81
(2) 資料 (17 Bytes)
(2-1) 資料區塊編號 0~63 (十進位, 1Byte)
(2-2) 區塊內資料:16 Bytes
【寫入資料到某一個區塊 (Block) 】
● 發送端內容
(1) 命令:十進位 82
(2) 資料 (17 Bytes)
(2-1) 資料區塊編號 0~63 (十進位, 1Byte)
(2-2) 區塊內資料:16 Bytes
● 回應端內容
(1) 命令:十進位 82
(2) 資料 (1 Byte):寫入成功回應1,寫入失敗回應0
【開關燈號】
● 發送端內容
(1) 命令:十進位 83
(2) 資料 (1 Byte):亮燈 1,關燈 0
● 回應端內容
(1) 命令:十進位 83
(2) 資料 (1 Byte):成功回應 1,失敗回應 0
【錯誤回應】:當設備接收的資料不完整、無法辨識的命令或XOR檢查錯誤時回應
● 回應端內容
(1) 命令:十進位 99
發送回應的基本部份先介紹到此,下一篇會利用這個假設的通訊協定來演練。