鄭 軼,楊明超
(武漢船用電力推進裝置研究所,武漢 430064)
隨著艦船設備的不斷更新換代,對艦船的操作與控制也在逐步向集中式的方向靠攏。艇員依靠集中控制室的計算機便可觀測艦船各設備的狀態,并可通過計算機向各設備發送指令。艦船設備的狀態參數的獲取與指令的發送,需要船用通信系統的良好支持。目前應用于艦船的通信方式主要包括CAN通信及以太網通信,其中,以太網通信速率較快,數據傳輸穩定,不易受到外部干擾,適合大量數據參數的循環上傳。
MODBUS協議由Modicon在1979年發明,是OSI模型第7層上的應用層報文傳輸協議,它定義了一個與基礎通信層無關的協議數據單元(PDU),即PDU=MODBUS功能碼+數據域。在某些特定總線或網絡上,MODBUS協議能夠映射在應用數據單元(ADU)上,即ADU=地址域+PDU+校驗碼,其通用幀格式如圖1所示。

圖1 MODBUS通用幀格式
目前MODBUS協議主要應用于以太網通信(MODBUS TCP)、串口通信(MODBUS RTU)及高速令牌傳遞網絡(MODBUS PLUS)。在不同類別的網絡中,對ADU的封裝也存在差異,以MODBUS TCP/IP為例,其ADU的組成如圖2所示。

圖2 MODBUSTCP/IP幀格式
可以看出,在MODBUS TCP協議中,ADU=MBAP+PDU。MBAP是TCP/IP協議上使用的一種專用報文頭,用以識別ADU。MBAP報文頭由7個字節組成,其格式如下表1所示。

表1 MBAP報文頭組成
從表格中可以看到,由于MBAP中含有長度信息,接收者能夠清晰的識別報文的邊界,因此在MODBUS TCP協議中,其ADU不再含有校驗碼。
MODBUS TCP通信系統模型一般基于客戶機/服務器模型搭建,如圖3所示。

圖3 MODBUS TCP通信系統客戶機/服務器模型
客戶機/服務器模型基于4種類型的報文:請求、指示、響應和證實。客戶機向服務器發送請求指令(MODBUS請求),服務器接收到來自客戶機的指令(MODBUS指示)后,對該指令進行響應(MODBUS響應),即按照約定的協議內容向客戶機發送數據,并由客戶機對發送的數據進行辨識和處理(MODBUS證實)。
MODBUS TCP通信系統可以包括多個MODBUS客戶機和服務器,其他互聯設備也可通過客戶機或服務器TCP/IP網關接入該通信系統,如圖4所示。

圖4 MODBUS TCP通信系統示意圖
目前廣泛使用的船用以太網通信系統多采用“一主多從”的構建思路,即由集中控制室的計算機擔任主機,依次向各設備輪詢數據,如圖5所示。

圖5 船用以太網通信系統結構示意圖
采用集中式輪詢方式的好處在于可以分時段向各設備發送數據請求,一來可以有效利用集控室計算機的系統資源,二來可以避免各設備同時返回數據造成通信線路堵塞。

圖6 船用MODBUS TCP通信系統結構
結合圖3、圖4和圖5可以看出,船用以太網通信系統可以按照MODBUS TCP通信系統結構進行搭建,如圖6所示。
將集控室計算機作為客戶機,各設備作為服務器,由集控室計算機向各設備發送輪詢請求,并接收返回數據。以客戶機與其中一臺服務器為例,其信息交換示意圖如圖7所示。
圖中,socket()函數用于創建套接字,bind()函數用來綁定一個端口號到該套接字,并在套接字與所指定的端口號之間建立一個連接。socket初始化完成后,服務器端需要使用listen()函數將狀態置為偵聽,才能夠接收到來自客戶機的連接請求。此時,若客戶機需要與服務器進行數據交換,則需要使用connect()函數來指定套接字號、服務器IP地址和端口號,服務器在接收到客戶機的連接請求后,需要使用accept()函數指定之前在listen()函數中所指定的套接字號,用以確定當前訪問的客戶機。在連接完成后,客戶機可以使用send()函數向服務器發送MODBUS請求,服務器需要使用recv()函數進行接收,再使用send()函數向客戶機發送MODBUS響應。值得注意的是,客戶機在發送一個MODBUS請求后,無需等待服務器端的響應便可以繼續發送下一個MODBUS請求。

圖7 MODBUS TCP通信系統信息交換示意圖
MODBUS服務器端的主要處理流程如圖8所示。
程序在初始化完成后即進入等待,在接收到來自客戶機的請求PDU后,對該PDU進行檢驗,根據檢驗情況決定生成MODBUS應答或是MODBUS異常,并將該應答或者異常作為響應發送給客戶機,其詳細設計分述如下:

圖8 MODBUS服務器端信息處理流程圖
1)初始化
與其他基于TCP/IP協議的設備類似,作為服務器端程序,MODBUS服務器端首先需要進行初始化,其核心內容是設置并綁定自身IP。建立服務器函數CreateServer()的核心代碼如下:
接下來需要將服務器置于偵聽狀態。MODBUS服務器端應支持多個并發的客戶機同時連接。在設計時,采用多線程策略可以實現該項功能,即每當偵聽到新的連接請求時,便建立一個新的線程來進行操作。偵聽函數TcpListen()的核心代碼如下:


2)生成MODBUS應答/異常
對于并發的連接,在接收到來自客戶機的請求時,服務器端將在對應的線程內對請求進行處理。根據MODBUS協議的MBAP報文頭判斷請求類別,再按照約定的協議內容向客戶機返回數據。響應函數ClientService()的核心代碼如下:


MODBUS客戶端的主要處理流程如圖9所示。

圖9 MODBUS客戶端信息處理流程圖
程序在初始化完成后即進入等待,根據需求發送請求PDU,同時監測是否收到響應PDU,根據檢驗情況決定生成MODBUS肯定證實或是MODBUS否定證實,并將該證實發送給用戶應用,其詳細設計分述如下:
1)初始化
MODBUS客戶端初始化的主要內容是建立客戶機與服務器端的連接。使用Socket類中的Connect函數可以完成這一目標。連接函數TcpConnect()的核心代碼如下:

2)發送MODBUS請求
可采用多種策略發送MODBUS請求,最為常用的是使用timer定時器作為觸發,定時發送。發送函數timersend_Tick()的核心代碼如下:

3)處理數據并生成肯定/否定證實
與服務器端的處理方式類似,接收函數根據MODBUS協議的MBAP報文頭判斷數據類別,再按照約定的協議內容解析數據。接收函數ReceiveMsg()的核心代碼如下:

根據第二章的內容,采用C#編寫MODBUS服務器端測試程序,使用0x03功能碼進行測試,起始地址為40101,大端模式。其主界面如圖10所示。
測試時使用TCP/UDP調試工具模擬MODBUS客戶端。運行MODBUS服務器端測試程序,單擊程序中的“開啟服務器”按鈕,并在TCP/UDP調試工具中設置本機IP為192.168.163.1,端口為9000,連接類型為TCP,單擊“連接”按鈕。此時調試工具已與本機連接。按照MODBUS協議,其MODBUS請求格式及數值如表2所示。

圖10 MODBUS服務器端測試程序
單擊TCP/UDP調試工具中“發送”按鈕,可在接收欄中看到數據序列如圖11所示。
將該數據序列進行解析,如表3所示。
可見調試工具接收到的報文信息完整、正確,通信正常。

表2 MODBUS請求格式及數值
根據第二章的內容,采用C#編寫MODBUS客戶端測試程序,使用0x03功能碼進行測試,起始地址為40101,大端模式,采用定時器觸發方式向服務器發送MODBUS請求。使用Modbus Slave調試工具模擬MODBUS服務器端,設置如圖12所示。

圖11 TCP/UDP調試工具結果

表3 調試結果解析

圖12 Modbus Slave調試工具設置
運行MODBUS客戶端測試程序,單擊“連接服務器”按鈕,得到的結果如圖13所示。

圖13 MODBUS客戶端測試程序結果
對比圖12和圖13可以看出,客戶端收到服務器端數據,且數據完整、正確,通信正常。
本文結合MODBUS TCP通信系統與船用以太網通信系統的結構特征,設計了基于MODBUS TCP協議的船用以太網通信系統,采用C#開發環境對通信系統的服務器端和客戶端進行了編程設計并進行了通信測試。測試結果表明,該編程設計正確,能夠有效進行數據交互。
參考文獻:
[1] 張小川.Modbus設備嵌入式網頁控制方法的研究與實現[J].科技風,2014,(20):26-27.
[2] 黃波.虛擬儀器技術在電力諧波分析系統中的應用[D].華中科技大學,2014.
[3] 史妍.基于Modbus的人防工程能源監控系統研究[D].哈爾濱工業大學,2012.
[4] 張芳.網絡控制系統時延分析、控制器設計及仿真研究[D].北京交通大學,2007.
[5] 郝曉弘,祖守圓,徐維濤.基于VC的Modbus/TCP協議模型通信測試軟件的實現[J].微計算機信息,2006,(07):64-67.