亚洲av成人精品日韩一区,97久久久精品综合88久久,玩弄japan白嫩少妇hd,亚洲av片不卡无码久久,玩弄人妻少妇500系列

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用協議棧實現Modbus TCP服務器應用

CHANBAEK ? 來源:木南創(chuàng)智 ? 作者:尹家軍 ? 2022-12-13 16:23 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

自從開源了我們自己開發(fā)的Modbus協議棧之后,有很多朋友建議我針對性的做幾個示例。所以我們就基于平時我們的應用整理了幾個簡單但可以說明基本的應用方法的示例,這一篇中我們來簡述如何使用協議棧實現一個Modbus TCP服務器應用。

1 、何為TCP服務器

Modbus協議是一個主從協議,那肯定就有主站和從站之分,在Modbus TCP中亦稱之為客戶端與服務器。所謂TCP客戶端其功能基本與RTU主站一樣,RTU主站會向從站發(fā)起數據請求,同樣的TCP客戶端也會向服務器發(fā)起請求。也就是說在Modbus TCP模式下客戶端亦是發(fā)起通訊的一方。

對于TCP客戶端來說,自己并不會產生數據,它的數據均是從服務器獲取,為了得到數據就必須向服務器發(fā)起數據請求。在Modbus TCP協議中,服務器一般也不會主動向外發(fā)送數據,服務器需要根據客戶端的數據請求來決定是否發(fā)送數據、發(fā)送哪些數據。這一過程如下圖所示:

從上圖我們不難看出,首先客戶端要主動發(fā)起數據請求,客戶端發(fā)起的數據請求需要告訴服務器它請求的數據有哪些。服務器收到這個數據請求后,服務器解析客戶端的請求并按照客戶端的請求返回數據??蛻舳耸盏綌祿憫蠼馕鰯祿@樣就完成了客戶端與服務器之間的一次數據通訊。

需要注意的是,Modbus TCP與Modbus RTU不同的是有一個專用的MBAP報文頭來識別Modbus應用數據單元。這一報文頭由7個字節(jié)組成:

這種MBAP報文頭雖然也是用來識別Modbus數據域,但還是與串行鏈路上使用的MODBUS RTU應用數據單元有一些差別,具體如下:

1 、用MBAP報文頭中的單個字節(jié)單元標識符取代MODBUS串行鏈路上通常使用的MODBUS從地址域。這個單元標識符用于設備的通信,這些設備使用單個 IP 地址支持多個獨立MODBUS 終端單元,例如:網橋、路由器和網關。

2 、使用接收者可以驗證的方式來構造所有MODBUS請求和響應。對于MODBUS PDU有固定長度的功能碼來說,僅功能碼就足夠了。對于在請求或響應中攜帶一個可變數據的功能碼來說,數據域包括字節(jié)數。

3 、使用TCP上傳送MODBUS數據域時,即使將報文分成多個信息包來傳輸,可在MBAP報文頭上攜帶附加長度信息,這樣接收者就能夠識別報文的完整性。

2 、如何實現TCP服務器

我們已經簡單的描述了基于TCP/IP的Modbus數據通訊,在此基礎上我們將進一步描述基于協議棧的Modbus TCP服務器的實現。

在協議棧中,我們已經實現了Modbus TCP服務器的基本功能,如數據的管理及響應客戶端的請求等。Modbus TCP服務器作為數據的生產者,管理者四類數據:線圈量、狀態(tài)量、輸入寄存器和保持寄存器。所以在Modbus TCP服務器中我們要為這四種數據定義相應的地址,以便客戶端能夠對應的訪問。所以設計一個Modbus TCP服務器我們先來設計它的數據地址。在我們的例子中,出于操作方便,我們規(guī)定了每類數據類型的數量為10,我們以用的最多的保持寄存器為例,定義寄存器地址為40001到40010。

在我們的協議棧中實現了0x01、0x02、0x03、0x04、0x05、0x06、0x0F以及0x10等功能碼。也就是說客戶端對象會生成面向這些功能碼的Modbus TCP服務器數據請求。Modbus TCP服務器收到請求后,解析請求并根據請求生成響應的數據響應??梢员硎緸橄聢D所示:

從上圖我們明白協議棧中已經實現了對收到的主站數據請求進行解析以及根據解析生成對應的響應的函數。我們使用協議棧時,主要需要做兩個方面的事情:解析數據請求和生成數據響應。

在協議棧中定義了一個解析函數,該函數將收到的數據請求消息解析,并根據解析的結果生成返回的數據響應。該函數的原型如下:

/ 解析接收到的信息,返回響應命令的長度 /

uint16_t ParsingClientAccessCommand(uint8_t receivedMessage,uint8_trespondBytes)

這個函數有2個參數:uint8_t receivedMessage是收到的數據請求消息; uint8_trespondBytes是返回的數據響應消息,也是函數需要生成的;而函數的返回值則是生成的數據響應詳細的長度。

在解析的過程中,該函數判斷消息的完整性,并根據不同的功能碼調用不同的回調函數來實現,包括設置本地數據和獲取本地數據的相關回調函數,在后續(xù)將討論它們的實現。

3 、 TCP****服務器編碼

到這里其實我們已經很清楚,使用協議棧實現Modbus TCP服務器只需要在TCP/IP收到客戶端請求后調用sendLen = ParsingClientAccessCommand(buffer,sendBuf);函數解析收到的請求命令。并根據請求執(zhí)行相應的操作就可以了。那需要實現哪些操作呢?在協議棧中定義了8個回調函數,分別是獲取線圈量、獲取狀態(tài)量、獲取輸入寄存器和獲取保持寄存器,以及預置單個線圈量、預置多個線圈量、預置單個保持寄存器和預置多個保持寄存器。函數原型定義如下:

/*獲取想要讀取的Coil量的值*/
__weak void GetCoilStatus(uint16_t startAddress,uint16_t quantity,bool*statusList)
{
  //如果需要Modbus TCP Server/RTU Slave應用中實現具體內容
}
 
/*獲取想要讀取的InputStatus量的值*/
__weak void GetInputStatus(uint16_t startAddress,uint16_t quantity,bool*statusValue)
{
  //如果需要Modbus TCP Server/RTU Slave應用中實現具體內容
}
 
/*獲取想要讀取的保持寄存器的值*/
__weak void GetHoldingRegister(uint16_t startAddress,uint16_t quantity,uint16_t*registerValue)
{
  //如果需要Modbus TCP Server/RTU Slave應用中實現具體內容
}
 
/*獲取想要讀取的輸入寄存器的值*/
__weak void GetInputRegister(uint16_t startAddress,uint16_tquantity,uint16_t *registerValue)
{
  //如果需要Modbus TCP Server/RTU Slave應用中實現具體內容
}
 
/*設置單個線圈的值*/
__weak void SetSingleCoil(uint16_t coilAddress,bool coilValue)
{
  //如果需要Modbus TCP Server/RTU Slave應用中實現具體內容
}
 
/*設置單個寄存器的值*/
__weak void SetSingleRegister(uint16_t registerAddress,uint16_tregisterValue)
{
  //如果需要Modbus TCP Server/RTU Slave應用中實現具體內容
}
 
/*設置多個線圈的值*/
__weak void SetMultipleCoil(uint16_t startAddress,uint16_t quantity,bool*statusValue)
{
  //如果需要Modbus TCP Server/RTU Slave應用中實現具體內容
}
 
/*設置多個寄存器的值*/
__weak void SetMultipleRegister(uint16_t startAddress,uint16_tquantity,uint16_t *registerValue)
{
  //如果需要Modbus TCP Server/RTU Slave應用中實現具體內容
}

這些函數就是我們要根據我們的Modbus TCP服務器功能設計實現的。對于我們這個測試例子我們只需要實現讀取保持寄存器就可以了。具體實現如下:

/*獲取想要讀取的保持寄存器的值*/
void GetHoldingRegister(uint16_t startAddress,uint16_t quantity, uint16_t* registerValue)
{
   uint16_t start;
   uint16_t count;
   
    /*先判斷地址是否處于合法范圍*/
    start =(startAddress > 0) ? ((startAddress <= 9) ? startAddress : 9) : 0;
    count =((start + quantity - 1) <= 9) ? quantity : (9 - start);
 
    for(int i = 0; i < count; i++)
    {
       registerValue[i] = holdingRegister[start + i];
    }
}

這個例子中我們實現了讀取40001到40010保持寄存器的值。

4 、 TCP****服務器小結

我們在TCP服務器的基礎上使用我們的協議棧實現一個Modbus TCP服務器應用。其實使用協議棧實現Modbus TCP服務器應用是很簡單的,我們需要使用如ModPoll這樣的軟件來測試一下它。

我們讀取10個保持寄存器,值分別為對應位固定的1到10,如上圖讀出的結果與預期一致。我們還可以采用TCP&UDP測試工具來看一下報文,具體如下:

同樣的,在同一臺設備上只需實現一個Modbus TCP服務器,哪怕是通過不同的網絡端口來訪問。這一點與客戶端是不一樣的,原因是Modbus TCP服務器的數據是自己產生,而且只需被動響應客戶端的數據請求。

接下來我們來總結一下使用協議棧實現Modbus TCP服務器的工作流程,或者說實現的步驟。首先Modbus TCP服務器要解析從客戶端送來的數據請求。在協議棧中已經封裝了數據請求的解析函數、所以我們實現Modbus TCP服務器時首先就是調用這一函數來解析接收到的數據請求消息。

然后將解析函數返回的數據響應消息發(fā)送到客戶端就可以了。也就是說使用協議棧,只需要調用一下這個函數Modbus TCP服務器功能就實現了。這是因為這個函數實現了整個Modbus TCP服務器的響應過程,大致分三個步驟:第一步,解析收到的客戶端數據請求消息;第二步,根據解析的結果預置數據或者獲取數據,預置和獲取數據由8個回調函數實現;第三步,生成Modbus TCP服務器數據響應消息。說到這里我們已經清楚,Modbus TCP服務器必須實現這些回調函數,其它工作則全由協議棧完成。

源碼下載:https://download.csdn.net/download/foxclever/12838885

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • MODBUS
    +關注

    關注

    28

    文章

    2118

    瀏覽量

    79548
  • 服務器
    +關注

    關注

    13

    文章

    9793

    瀏覽量

    87950
  • TCP
    TCP
    +關注

    關注

    8

    文章

    1402

    瀏覽量

    81028
  • 協議棧
    +關注

    關注

    2

    文章

    145

    瀏覽量

    34102
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    使用協議實現Modbus TCP客戶端應用

    自從開源了我們自己開發(fā)的Modbus協議之后,有很多朋友建議我針對性的做幾個示例。所以我們就基于平時我們的應用整理了幾個簡單但可以說明基本的應用方法的示例,這一篇中我們將解說如何使用協議
    的頭像 發(fā)表于 12-13 16:18 ?2254次閱讀
    使用<b class='flag-5'>協議</b><b class='flag-5'>棧</b><b class='flag-5'>實現</b><b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>客戶端應用

    linux平臺實現modbus主機協議的動態(tài)庫libMbpoll

    libMbopll動態(tài)庫是面向linux平臺設計的modbus主機協議,可以運行在x86平臺以及各種嵌入式linux平臺;協議提供了簡單
    發(fā)表于 05-28 14:55

    協議介紹--TCP/IP

    ,和SOCKET API。以及DNS,PING等直接調用的函數。5)本協議可以完成客戶機,服務器,UDP客戶機,UDP服務器。還可以方便完成DNS客戶端功能,PING客戶端功能。6)
    發(fā)表于 09-03 15:03

    Modbus庫開發(fā)筆記之九:利用協議開發(fā)Modbus TCP Server應用

    。接下來我們討論Modbus TCP Server的實現過程。根據前面對協議的封裝,我們需要引用ModbusTCP Server的相關封裝
    發(fā)表于 08-26 15:56

    Modbus協議中文版

    不同類型的總線或網絡連接的設備之間的客 戶機/服務器通信。 目前,使用下列情況實現 MODBUS: 以太網上的TCP/IP。 各種媒體(有線:EIA/TIA-232-E、EIA
    發(fā)表于 07-09 07:16

    在uIP協議實現基于AJAX和CGI的動態(tài)Web服務器

    和應用。為了滿足資源有限的嵌入式系統的需要,本文采用微型TCP/IP協議uIP,在協議之上設計實現
    發(fā)表于 05-28 05:00

    怎么實現的基于TCP/IP協議的簡易服務器?

    本文以SPCE061A為主控制,DM9000為以太網MAC控制,配合一定的外圍電路而實現的基于TCP/IP協議
    發(fā)表于 05-31 06:34

    如何快速實現Modbus RTU和Modbus TCP協議轉換?

    整合起來監(jiān)控管理,目前上位機大部分用的Modbus TCP協議,而現場設備有大批量使用的是Modbus RTU協議,要
    發(fā)表于 08-18 18:36

    基于RT-Thread實現的Agile Modbus協議

    基于 RT-Thread 實現的支持 Modbus 固件升級的 Bootloader:HPM6750_Boot  特性  支持 rtu 及 tcp 協議,使用純 C 開發(fā),不涉及任何硬
    發(fā)表于 10-08 15:04

    Modbus通訊協議的幾種實現方式

    量避免采用OPC。   OPC協議實現要通過兩部分完成。首先是OPC服務器,這是軟件程序與不同協議下工業(yè)設備通訊的中間件,相當于網關。在OPC服務
    發(fā)表于 05-05 16:19

    嵌入式WEB服務器TCP/IP協議的設計與實現

    嵌入式TCP/IP 協議能擴展非智能設備的網絡功能,是信息智能化的一種有效手段。 本文從嵌入式WEB 服務器入手,分析了嵌入式TCP
    發(fā)表于 06-19 09:03 ?35次下載

    Microchip TCP/IP協議

    的開發(fā)人員可以很容易找到許多Microchip產品的商業(yè)和非商業(yè)的TC P/IP實現方案。本應用筆記詳細說明了Microchip公司自己免費提供的TC P/IP協議。 Microchip T
    發(fā)表于 04-20 16:04 ?5次下載
     Microchip <b class='flag-5'>TCP</b>/IP<b class='flag-5'>協議</b><b class='flag-5'>棧</b>

    STM32+ENC28J60+UIP協議實現WEB服務器示例

    STM32+ENC28J60+UIP協議實現WEB服務器示例
    發(fā)表于 12-06 09:21 ?34次下載
    STM32+ENC28J60+UIP<b class='flag-5'>協議</b><b class='flag-5'>棧</b><b class='flag-5'>實現</b>WEB<b class='flag-5'>服務器</b>示例

    Arduino供電的I/O Modbus/TCP設備服務器

    電子發(fā)燒友網站提供《Arduino供電的I/O Modbus/TCP設備服務器.zip》資料免費下載
    發(fā)表于 11-24 14:27 ?0次下載
    Arduino供電的I/O <b class='flag-5'>Modbus</b>/<b class='flag-5'>TCP</b>設備<b class='flag-5'>服務器</b>

    串口服務器TCP/IP協議是什么關系

    串口服務器TCP/IP協議之間存在著緊密而復雜的關系。這種關系主要體現在串口服務器如何利用TCP
    的頭像 發(fā)表于 08-25 17:35 ?2126次閱讀