柳 青
(北京電子科技職業(yè)學(xué)院, 北京 100176)
隨著工業(yè)物聯(lián)網(wǎng)、制造智能化進(jìn)程的推進(jìn),嵌入式設(shè)備之間能夠?qū)崿F(xiàn)簡單、 可靠的通信成為自動化領(lǐng)域的實(shí)際需要。 Modbus/TCP 將Modbus 協(xié)議嵌入到TCP 協(xié)議的應(yīng)用層,由于其具有開放的、標(biāo)準(zhǔn)的協(xié)議格式,廣泛應(yīng)用于工業(yè)通信。 而TCP/IP 協(xié)議結(jié)構(gòu)龐大,嵌入式系統(tǒng)的存儲計算資源有限,因此研究Modbus/TCP 在嵌入式系統(tǒng)上的設(shè)計方法很有必要。
渠薇等設(shè)計了基于W5500 的Modbus/TCP 服務(wù)器[1],這種方案需要采用專用的協(xié)議芯片完成TCP/IP 協(xié)議解析,不僅使電路設(shè)計復(fù)雜,而且受限于外圍芯片與處理器的通信帶寬,會影響系統(tǒng)的整體性能。劉大千等提出了一種μC / OS 實(shí)時操作系統(tǒng)、LWIP 輕型協(xié)議棧和MODBUS協(xié)議相結(jié)合的方法[2],這種方案需要對操作系統(tǒng)和協(xié)議棧進(jìn)行移植,軟件代碼量較大,對系統(tǒng)的維護(hù)升級提出很大挑戰(zhàn)。 綜合以上研究,設(shè)計了一種直接運(yùn)行于微處理器上的,精簡的Modbus/TCP 協(xié)議棧,避免了設(shè)計專用電路和代碼移植的工作,同時能夠改善通信的實(shí)時性能。
Modbus/TCP 協(xié)議底層以TCP/IP 協(xié)議為基礎(chǔ),在桌面系統(tǒng)中,該協(xié)議由操作系統(tǒng)提供的套接字接口來實(shí)現(xiàn),但是在嵌入式系統(tǒng)中,芯片驅(qū)動只包含最底層的以太網(wǎng)接收、發(fā)送數(shù)據(jù)的功能, 所以需要構(gòu)建TCP/IP協(xié)議。 另外,由于以太網(wǎng)數(shù)據(jù)包中必須包含硬件MAC 地址,所以需要實(shí)現(xiàn)ARP 協(xié)議[3]。
設(shè)計的協(xié)議棧整體流程如圖1 所示, 處理器不斷從網(wǎng)卡讀取數(shù)據(jù)包, 然后判斷該數(shù)據(jù)包是ARP 數(shù)據(jù)還是IP 數(shù)據(jù),如果是ARP 數(shù)據(jù),則對該數(shù)據(jù)包進(jìn)行地址解析;如果是IP 數(shù)據(jù)包,進(jìn)一步判斷是否是TCP 數(shù)據(jù)包,最后判斷是不是Modbus 協(xié)議數(shù)據(jù),如果全部成立則進(jìn)行Modbus 協(xié)議解析。
圖1 Modbus/TCP 協(xié)議棧流程
TCP 協(xié)議是面向連接的協(xié)議,在數(shù)據(jù)通信之前,必須要建立連接,否則通信的雙方不能交換數(shù)據(jù);在通信結(jié)束之前也必須關(guān)閉連接,以便節(jié)省系統(tǒng)資源,并且保證下次通信連接能夠正確建立。 建立連接的過程稱為 “三次握手”,關(guān)閉連接的過程稱為“四次揮手”[4]。通過判斷TCP 協(xié)議中的控制字字段來判斷該報文是請求連接報文還是關(guān)閉連接報文。
在TCP 協(xié)議解析中,會對SYN 標(biāo)志位和FIN 標(biāo)志位依次進(jìn)行判斷。如果數(shù)據(jù)包的SYN 位為1,則表示該數(shù)據(jù)包為請求連接數(shù)據(jù)包,協(xié)議棧將返回ACK 應(yīng)答包,通知客戶端本機(jī)已經(jīng)準(zhǔn)備好接收數(shù)據(jù), 客戶端收到收到應(yīng)答包后則通信連接完全建立,可以開始數(shù)據(jù)交換。 如果FIN標(biāo)志位為1,則表示該數(shù)據(jù)包為關(guān)閉連接數(shù)據(jù)包,協(xié)議棧等待發(fā)送緩沖區(qū)為空時,返回ACK 應(yīng)答包,通知服務(wù)器可以斷開連接,服務(wù)器收到應(yīng)打包后,斷開連接,數(shù)據(jù)交換終止。 TCP 協(xié)議解析代碼如下所示:
Modbus/TCP 是以標(biāo)準(zhǔn)modbus 作為用戶層協(xié)議,modbus 協(xié)議報文格式如下[5]:
首先計算寄存器的其實(shí)地址,由于Modbus 的數(shù)據(jù)順序與內(nèi)存存儲順序相反,因此地址的計算需要移位操作,然后用同樣的方法計算寄存器數(shù)量。 根據(jù)寄存器地址和數(shù)量可以計算出數(shù)據(jù)塊在內(nèi)存中的存儲地址以及長度,將內(nèi)存數(shù)據(jù)復(fù)制到數(shù)據(jù)包中,作為返回數(shù)據(jù)。最后再將實(shí)際讀取的數(shù)據(jù)長度更新到協(xié)議中的長度字段中, 作為數(shù)據(jù)包長度返回到客戶端。 第106 個數(shù)據(jù)包和第107 個數(shù)據(jù)包是一對Moubus/TCP 請求應(yīng)答數(shù)據(jù),可以看出從請求到應(yīng)答的時間間隔僅有132μs, 說明該協(xié)議棧具有一定的實(shí)時性。
客戶端第一次向服務(wù)器請求連接或者數(shù)據(jù)的時候,客戶端只知道服務(wù)器的IP 地址,并不知道客戶端的網(wǎng)卡設(shè)備硬件地址, 因此主機(jī)需要將詢問硬件地址的報文廣播到網(wǎng)絡(luò)上,具有匹配的IP 地址的服務(wù)器會將自己的網(wǎng)卡地址添加到返回數(shù)據(jù)包中發(fā)送回客戶端, 客戶端就得到了對應(yīng)服務(wù)器的網(wǎng)卡地址, 這個協(xié)議稱為地址解析協(xié)議(arp),地址解析協(xié)議的數(shù)據(jù)類型字段為0x0608,當(dāng)程序檢查出數(shù)據(jù)包具有該種類型是, 則跳轉(zhuǎn)至地址解析函數(shù)中。 地址解析協(xié)議源碼如下:
首先判斷該數(shù)據(jù)包的Message Type 字段是不是類型1,類型1 代表該數(shù)據(jù)包為地址請求操作,進(jìn)而判斷該數(shù)據(jù)包的目的IP 地址是否與本地IP 地址一致, 如果一致則說明該數(shù)據(jù)包即為請求本地IP 的網(wǎng)卡地址,本地機(jī)需要對該數(shù)據(jù)包進(jìn)行相應(yīng)。此時協(xié)議棧需要組裝響應(yīng)報文,將報文的Messege Type 字段設(shè)置為類型2, 表示返回數(shù)據(jù)包為ARP 響應(yīng)包;之后將源IP 和源MAC 地址均設(shè)置為本地地址,目標(biāo)地址則利用請求包中的源地址。
為了驗(yàn)證所設(shè)計的modbus/TCP 協(xié)議棧的正確性,搭建了如圖2 所示的通信實(shí)驗(yàn)平臺。 其中嵌入式板卡以xilinx 的zynq-7020 為 處 理器, 其上運(yùn)行了設(shè)計的協(xié)議棧,IP 設(shè)置為192.168.1.9。筆記本電腦上運(yùn)行測試程序,IP 設(shè)置為192.168.1.1, 并采用Wireshark 軟件進(jìn)行抓包,抓取的數(shù)據(jù)包如圖3 所示。
從圖3 中可以看出, 第101 個數(shù)據(jù)包為計算機(jī)發(fā)出的ARP 請求包, 詢問IP 地址為192.168.1.9 的主機(jī)的MAC 地址, 第102 個數(shù)據(jù)包是板卡返回的ARP 應(yīng)答包,報告了板卡的地址信息。 第103 個數(shù)據(jù)包為計算機(jī)發(fā)出的TCP 建立連接請求, 第104 個數(shù)據(jù)包為板卡返回的請求應(yīng)當(dāng), 第105 個數(shù)據(jù)包為計算機(jī)對應(yīng)答的確認(rèn), 至此TCP 連接建立完成。 從第105 個數(shù)據(jù)包開始,計算機(jī)和板卡開始利用Modbus/TCP 協(xié)議進(jìn)行數(shù)據(jù)交互。
圖2 Modbus/TCP 通信實(shí)驗(yàn)平臺
圖3 Wireshark 抓包數(shù)據(jù)
通過詳細(xì)分析TCP/IP 協(xié)議和Modbus 協(xié)議規(guī)范,并在此基礎(chǔ)上設(shè)計了Modbus/TCP 協(xié)議棧,實(shí)現(xiàn)了ARP 地址解析協(xié)議,最后將設(shè)計的協(xié)議棧代碼在xilinx 微處理器上運(yùn)行,與計算機(jī)進(jìn)行通信實(shí)驗(yàn)。 實(shí)驗(yàn)表明,協(xié)議棧能夠與計算機(jī)進(jìn)行數(shù)據(jù)交換,應(yīng)答時間小于1ms,實(shí)時性較好。