1. 程式人生 > >移植Modbus到STM32F103(3):考慮可能的通訊錯誤,保證控制命令的可靠傳輸

移植Modbus到STM32F103(3):考慮可能的通訊錯誤,保證控制命令的可靠傳輸

因為各種原因,傳輸過程中總會出現各種異常。Modbus有LRC/CRC校驗,有響應返回,還有異常碼,對於傳輸中出現的異常有一定的發現能力。但是Modbus本身不進行糾錯,糾錯和重傳由開發者定義。

根據通訊的原理,在一條不可靠的通道上傳輸的任何協議都不可能做到完全可靠。即使是一個比較可靠的協議,也會存在一些極端情況,這些情況一旦出現,會讓協議的糾錯機制完全失效。對此我們要小心謹慎,讓這些極端情況出現的概率儘可能小。

分析一下Modbus通訊協議可能出現的錯誤,發現主要有四個來源:

1)某個查詢/響應的協議幀錯誤,可能是PDU錯誤,也可能是ADU錯誤,對於ASCII模式,還有可能是引導符和結束符錯誤;

2)某個查詢/響應丟失,或者沒在約定時間內送達,導致超時;

3)主機發出了錯誤的查詢,如對不存在的暫存器進行讀/寫;

4)某個查詢/響應的協議PDU傳輸錯誤,而且錯誤的PDU是合法的,恰好LRC/CRC也發生錯誤,協議幀沒有報錯,導致錯誤的查詢/響應被接收。這種情況的概率比較低,但在噪音比較大的環境裡會出現。

對這些異常情況進行排列組合,得到協議的可能狀態:

1、主機的查詢從機正確收到,並做出了正常響應,主機接收到正常響應。

2、主機的查詢從機正確收到,並做出了正常響應,但從機返回的響應丟失或者被幹擾產生了幀錯誤,主機等待超時。

3、(概率較低,這種情況主機無法糾錯)主機的查詢從機正確收到,並做出了正常響應,但從機返回的響應PDU傳輸錯誤,而且錯誤的PDU是合法的,恰好LRC/CRC同時發生了錯誤,協議幀沒有報錯,導致主機接收到了錯誤但合法的響應。

4、主機的查詢從機正確收到,但是從機發現命令無法執行,返回異常響應,主機接收到包含異常碼的響應。

5、主機的查詢從機正確收到,但是從機發現命令無法執行,返回異常響應,但響應丟失或者包含幀錯誤,主機等待超時。

6、(概率極低,這種情況主機無法糾錯,屬於極端情況,不予考慮)主機的查詢從機正確收到,但是從機發現命令無法執行,返回異常響應,但從機返回的響應PDU傳輸錯誤,恰好LRC/CRC同時發生了錯誤,協議幀沒有報錯,導致主機接收到了錯誤但合法的響應。

7、主機的查詢從機沒有收到,或從機發現收到的查詢包含幀錯誤,從而不進行響應,主機等待超時。

8、(概率較低,但有可能導致從機執行錯誤的命令,對關鍵命令,需要小心這種情況的發生)主機的查詢PDU傳輸錯誤,而且錯誤的PDU是合法的,恰好LRC/CRC同時發生了錯誤,協議幀沒有報錯,導致從機接收了錯誤的命令。從機返回了響應,主機接收到響應,發現響應是錯誤的。

9、(概率極低,但有可能導致從機執行錯誤的命令,對關鍵命令,需要小心這種情況的發生)主機的查詢PDU傳輸錯誤,而且錯誤的PDU是合法的,恰好LRC/CRC同時發生了錯誤,協議幀沒有報錯,導致從機接收了錯誤的命令。從機返回了響應,但從機返回的響應丟失或者被幹擾產生了幀錯誤,主機等待超時。

10、(概率極低,這種情況主機無法糾錯,屬於極端情況,不予考慮)主機的查詢PDU傳輸錯誤,而且錯誤的PDU是合法的,恰好LRC/CRC同時發生了錯誤,協議幀沒有報錯,導致從機接收了錯誤的命令。從機返回了響應,但從機返回的響應PDU傳輸錯誤,而且錯誤的PDU是合法的,恰好LRC/CRC同時發生了錯誤,協議幀沒有報錯,導致主機接收到了“正確”的響應。

考慮對這些情況進行處理:

    情況1是正常通訊,情況4是主機的問題,這裡不考慮;

    情況6和10出現的概率極低,而且很難糾錯,這裡也不考慮。

    情況3出現的概率較低,但如果出現的話很難糾錯。所以如果從機的響應結果很重要,最好多次重複查詢,確保結果的準確。當然這屬於主機端的事情,所以這裡也不多說。

    情況2、5、7、9從機響應超時,情況8從機響應錯誤,這幾種情況主機都能發現錯誤,所以如果給主機增加重傳機制,就可以提高這幾種情況下的可靠性。但如果主機發送的是關鍵的控制命令,比如高壓脈衝的開關,剎車系統的啟動,這些命令如果傳輸錯誤,可能帶來無法挽回的損失。這些關鍵的控制命令,需要準確的送達,光靠主機的出錯重傳無法保證其可靠性。要提高這些命令傳輸的可靠性,必須對從機程式進行修改。

TCP/IP協議是一個經典的可靠協議,其三次握手四次揮手和給資料段進行編號的機制廣負盛名。這些機制,通過損失有限的速度,即可極大地提高可靠性。

控制命令在Modbus協議裡的傳輸,也可以採用類似的機制。比如,採用寫暫存器功能碼+控制暫存器地址+執行計數的格式傳輸控制命令,而不用寫暫存器功能碼+控制暫存器地址+固定控制程式碼的格式。從機端和主機端分別對控制命令的執行次數計數,只有從機發現自己的計數器等於收到的執行計數-1時,才會執行,否則返回異常碼0x03。主機收到異常後響應後,查詢從機的計數器。如果主機之前已經發過這個命令,這次是因為錯誤或超時重傳的,且從機的計數器等於於主機的計數器,說明從機已經執行過該命令了,主機結束這一次控制。如果從機的計數不等於主機的計數器或者主機的計數器-1,說明從機或主機可能發生了故障,這時可以通過寫從機裡的另一個暫存器來更新