女人荫蒂被添全过程13种图片,亚洲+欧美+在线,欧洲精品无码一区二区三区 ,在厨房拨开内裤进入毛片

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

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

3天內不再提示

Modbus TCP的設計與實現

CHANBAEK ? 來源:木南創智 ? 作者:尹家軍 ? 2022-12-13 15:33 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

對于Modbus TCP來說與Modbus RTU和Modbus ASCII有比較大的區別,因為它是運行于以太網鏈路之上,是運行于TCP/IP協議之上的一種應用層協議。在協議棧的前兩個版本中,Modbus TCP作為客戶端時也存在一些局限性。我們將對這些不足作一定更新。

1 、存在的不足

在原有的協議棧中,我們所封裝的Modbus TCP客戶端一個特定的客戶端,即它只是一個客戶端實例。在通常的應用中不會有什么問題,但在有些應用場合就會顯現出它的局限性。

首先,作為一個特定的客戶端,若是連接多個服務器目標時,修改服務器參數值的處理變的非常復雜,需要分辨是不同的服務器,不同的變量。當需要從不同的網段操作數據時,我們甚至需要標記不同的網段。

其次,作為一個特定的客戶端,如果我們操作的服務器參數相似時,哪怕來自于不同的網段,我們也需要仔細分辨或者傳遞額外的參數。因為同一客戶端的解析函數是同一個。

最后,將多個Modbus TCP服務器通訊都作為唯一的一個特定的服務器來處理,使得各部分混雜在一起,程序結構很不清晰,對象也不明確。

2 、更新設計

考慮到前述的局限性,我們將Modbus TCP客戶端及其所訪問的Modbus TCP服務器定義為通用的對象,而當我們在具體應用中使用時,再將其特例化為特定的客戶端和服務器對象。

首先我們來考慮客戶端,原則上我們規劃的每一個客戶端對象管理我們設備上的一個IP網段的設備。那么在一個特定客戶端下,我們可以定義多達253個不同的服務器。如下圖所示:

從上圖中我們可以發現,我們的目的就是讓協議棧支持,多客戶端和多服務器,并且在不同客戶端下可以訪問同網段的多個服務器。接下來我們還需要考慮服務器對象。客戶端對服務器的操作無非兩類:讀服務器信息和寫服務器信息。

對于讀服務器信息來說,客戶端需要發送請求命令,等待服務器返回響應信息,然后客戶端解析收到的信息并更新對應的參數值。因為返回的響應消息是沒有對應的寄存器地址的,所以要想在解析的時候定位寄存器就必須知道發送的命令,為了便于分辨我們將命令存放在服務器對象中。

而對于寫服務器操作,無論寫的要求來自于哪里,對于協議棧來說肯定是其它的數據處理進程發過來的,所接到要求后我們需要記錄是哪一個客戶端管理的哪一個服務器的哪些參數。對于客戶端我們不需要分辨,因為每個客戶端都是獨立的處理進程,但是對于服務器和參數我們就需要分辨。每一個客戶端所管理的IP地址的最后一段為0到255,所以我們可以依據來分辨服務器端。而在每一個服務器節點中增加狀態標志,用以記錄請求狀態,而所有服務器端組成鏈表。

3 、編碼實現

我們已經設計了我們的更新,接下來我們就根據這一設計來實現它。我們主要從以下幾個方面來操作:第一,實現客戶端對象類型和服務器對象類型;第二,客戶端對象的實例化及服務器對象的實例化;第三,讀服務器參數的客戶端操作過程;第四,寫服務器參的數客戶端操作過程。接下來我們將一一描述之。

3.1 、定義對象類型

與在Modbus RTU和Modbus ASCII一樣,在Modbus TCP協議棧的封裝中,我們也需要定義客戶端對象和服務器對象,自然也免不了要定義這兩種類型。

首先我們來定義本地客戶端的類型,其成員包括:一個uint32_t的寫服務器標志數組;服務器數量字段;服務器順序字段;本客戶端所管理的服務器列表;4個數據更新函數指針。具體定義如下:

1 /* 定義本地TCP客戶端對象類型 */
 2 typedef struct LocalTCPClientType{
 3   uint32_t transaction;                                 //事務標識符
 4   uint16_t cmdNumber;                                  //讀服務器命令的數量
 5   uint16_t cmdOrder;                                   //當前從站在從站列表中的位置
 6   uint8_t (*pReadCommand)[12];                         //讀命令列表
 7   ServerListHeadNode ServerHeadNode;                    //Server對象鏈表的頭節點
 8   UpdateCoilStatusType pUpdateCoilStatus;               //更新線圈量函數
 9   UpdateInputStatusType pUpdateInputStatus;             //更新輸入狀態量函數
10   UpdateHoldingRegisterType pUpdateHoldingRegister;     //更新保持寄存器量函數
11   UpdateInputResgisterType pUpdateInputResgister;       //更新輸入寄存器量函數
12 }TCPLocalClientType;

關于客戶端對象類型,在前面的更新設計中已經講的很清楚了,只有Server對象鏈表的頭節點字段需要說明一下。該字段包括兩個類容:第一,服務器鏈表的頭節點指針,用來記錄服務器對象列表。第二,記錄鏈表的長度,即服務器節點的數量。具體如下圖所示:

還需要定義服務器對象,此服務器對象只是便于客戶端而用于表示真是的服務器。客戶端的服務器列表中就是此對象。具體結構如下:

1 /* 定義被訪問TCP服務器對象類型 */
 2 typedef struct AccessedTCPServerType{
 3   union {
 4     uint32_t ipNumber;
 5     uint8_t ipSegment[4];
 6   }ipAddress;                                           //服務器的IP地址
 7   uint32_t flagPresetServer;                            //寫服務器請求標志
 8   WritedCoilListHeadNode pWritedCoilHeadNode;          //可寫的線圈量列表
 9   WritedRegisterListHeadNode pWritedRegisterHeadNode;  //可寫的保持寄存器列表
10   struct AccessedTCPServerType *pNextNode;              //下一個TCP服務器節點
11 }TCPAccessedServerType;

關于服務器對象有三個字段需要說明一下。首先我們來看一看“讀命令列表(uint8_t (*pReadCommand)[12])”字段,它是12個字節,這是由Modbus TCP消息格式決定的。如下:

我們看到協議標識符為0,是因為0就表示Modbus TCP。還有可寫的線圈量列表頭節點和可寫的保持寄存器列表頭節點。這兩個字段用來表示對線圈和保持寄存器的列表即數量。

3.2 、實例化對象

我們定義了客戶端即服務器對象類型,我們在使用時就需要實例化這些對象。一般來說一個IP網段我們將其實例化為一個客戶端對象。

TCPLocalClientType hgraClient;

/ 初始化TCP客戶端對象 /

InitializeTCPClientObject(&hgraClient,2,hgraServer,NULL,NULL,NULL,NULL);

而一個客戶端對象會管理1到253個服務器對象,所以我們可以將多個服務器對象實例組成數組,并將其賦予客戶端管理。

TCPAccessedServerType hgraServer[]={{{192,168,0,1},0x00,0x00},{{192,168,1,1},0x00,0x00}};

所以,根據客戶端和服務器實例化的條件,我們需要先實例化服務器對象才能完整實例化客戶端對象。在客戶端的初始化中,我們這里將4的數據處理函數指針初始化為NULL,有一個默認的處理函數會復制給它,該函數是上一版本的延續,在簡單應用時簡化操作。服務器的上一個發送的命令指針也被賦值為NULL,因為初始時還沒有命令發送。

3.3 、讀服務器操作

讀服務器操作原理上與以前的版本是一樣的。按照一定的順序給服務器發送命令再對收到的消息進行解析。我們對客戶端及其所管理的服務器進行了定義,將發送命令保存于服務器對象,將服務器列表保存于客戶端對象,所以我們需要對解析函數進行修改。

1 /*解析收到的服務器相應信息*/
 2 void ParsingServerRespondMessage(TCPLocalClientType *client,uint8_t *recievedMessage)
 3 {
 4   /*判斷接收到的信息是否有相應的命令*/
 5   int cmdIndex=FindCommandForRecievedMessage(client,recievedMessage);
 6  
 7   if((cmdIndex<0))      //沒有對應的請求命令,事務號不相符
 8   {
 9     return;
10   }
11  
12   if((recievedMessage[2]!=0x00)||(recievedMessage[3]!=0x00)) //不是Modbus TCP協議
13   {
14     return;
15   }
16  
17   if(recievedMessage[7]>0x04)   //功能碼大于0x04則不是讀命令返回
18   {
19     return;
20   }
21  
22   uint16_t mLength=(recievedMessage[4]<<8)+recievedMessage[4];
23   uint16_t dLength=(uint16_t)recievedMessage[8];
24   if(mLength!=dLength+3)        //數據長度不一致
25   {
26     return;
27   }
28  
29   FunctionCode fuctionCode=(FunctionCode)recievedMessage[7];
30  
31   if(fuctionCode!=client->pReadCommand[cmdIndex][7])
32   {
33     return;
34   }
35  
36   uint16_t startAddress=(uint16_t)client->pReadCommand[cmdIndex][8];
37   startAddress=(startAddress<<8)+(uint16_t)client->pReadCommand[cmdIndex][9];
38   uint16_t quantity=(uint16_t)client->pReadCommand[cmdIndex][10];
39   quantity=(quantity<<8)+(uint16_t)client->pReadCommand[cmdIndex][11];
40  
41   if(quantity*2!=dLength)       //請求的數據長度與返回的數據長度不一致
42   {
43     return;
44   }
45  
46   if((fuctionCode>=ReadCoilStatus)&&(fuctionCode<=ReadInputRegister))
47   {
48     HandleServerRespond[fuctionCode-1](client,recievedMessage,startAddress,quantity);
49   }
50 }

解析函數的主要部分是在檢查接收到的消息是否是合法的Modbus TCP消息。檢查沒問題則調用協議站解析。而最后調用的數據處理函數則是我們需要在具體應用中編寫。在前面客戶端初始化時,回調函數我們初始化為NULL,實際在協議占中有弱化的函數定義,需要針對具體的寄存器和變量地址實現操作。

3.4 、寫服務器操作

寫服務器操作則是在其它進程請求后,我們標識需要寫的對象再統一處理。對具體哪個服務器的寫標識存于客戶端實例。而該服務器的哪些變量需要寫則記錄在服務器實例中。

所以在進程檢測到需要寫一個服務器時則置位對應的位,即改變flagWriteServer中的對應位。而需要寫該服務器的哪些變量則標記flagPresetCoil和flagPresetReg的對應位。修改這些標識都在其它請求更改的進程中實現,而具體的寫操作則在本客戶端進程中,檢測到標志位的變化統一執行。

這部分不修改協議棧的代碼,因為各服務器及各變量都只與具體對象相關聯,所以在具體的應用中修改。

4 、回歸驗證

借鑒前面Modbus ASCII和Modbus RTU的回歸測試經驗,我們設計兩個網段、每網段包括一個客戶端及兩個服務器的網絡結構。但考慮到我們只是功能性驗證,所以我們設計相對簡單的服務器。所以我們設計的網絡為:協議棧建立2個客戶端,每個客戶端管理同一網段的2個服務器,每個服務器有8個線圈及2個保持寄存器。具體結構如圖:

從上圖我們知道,該Modbus網關需要實現一個Modbus服務器用于和上位的通訊;需要實現兩個Modbus客戶端用于和下位的通訊。

在這個實驗中,讀操作沒有什么需要說的,只需要發送命令解析返回消息即可。所以我們中點描述一下為了方便操作,在需要寫的連續段,我們只要找到第一個請求寫的位置后,就將后續連續可寫數據一次性寫入。

告之: 源代碼可上Github下載:https://github.com/foxclever/Modbus

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

    關注

    28

    文章

    2091

    瀏覽量

    79325
  • TCP
    TCP
    +關注

    關注

    8

    文章

    1401

    瀏覽量

    80751
  • RTU
    RTU
    +關注

    關注

    0

    文章

    435

    瀏覽量

    29434
  • 協議棧
    +關注

    關注

    2

    文章

    145

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Modbus TCP通信報文解析

    Modbus TCP是在TCP/IP網絡上運行的Modbus實現,旨在允許Modbus ASC
    發表于 09-20 15:55 ?3.9w次閱讀
    <b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>通信報文解析

    Modbus TCPModbus RTU的實現

    使用ZLSN2040、NETCOM2040實現Modbus TCPModbus RTU的轉化。1.Modbus
    發表于 08-10 10:04

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

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

    基于Modbus TCP協議實現PC機與PLC的串行通信

    本文對modbus tcp協議以及modbus tcp串行通信在智能樓宇工程中的應用作了簡單介紹,重點分析研究了modbus
    發表于 08-13 14:47 ?7201次閱讀
    基于<b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>協議<b class='flag-5'>實現</b>PC機與PLC的串行通信

    匯川PLC AM401以太網通訊ModBus TCP實現

    本人近十年的工作都與工業軟件相關、其中工控系統開發過程中有一個必要環節就是跟各大廠商的PLC進行通訊,而對于從互聯網行業跨入工業互聯網行業的從業人員來說要實現各型號PLC通訊還是需要 一個過程的,隨著PLC的需求和應用越來越廣泛,本文就介紹一下上位機軟件與匯川PLC-AM401的通訊
    發表于 04-17 15:55 ?5次下載
    匯川PLC AM401以太網通訊<b class='flag-5'>ModBus</b> <b class='flag-5'>TCP</b><b class='flag-5'>實現</b>

    PLC轉MQTT OPC UA網關實現工業設備與阿里云平臺的互聯互通

    、MQTT、Modbus?TCP實現高效上行和下行通信,同時滿足PLC遠程上傳下載和遠程編程需求。 其硬件接口包括2路或6路RS485/RS232串口、網口、4G/WiFi接口,靈活適配各設備,與阿里云
    的頭像 發表于 08-01 11:57 ?648次閱讀
    PLC轉MQTT OPC UA網關<b class='flag-5'>實現</b>工業設備與阿里云平臺的互聯互通

    CAN從站轉Modbus TCP主站協議網關配置詳情

    ? CAN轉Modbus TCP 如何實現高效且穩定的連接與通信,這一問題常常讓眾多業內人士感到困惑不已。在此,為大家專門解讀這個難題。 遠創智控YC-CCLKIE-RTU 型設備有著極為卓越的表現
    的頭像 發表于 08-28 11:28 ?560次閱讀
    CAN從站轉<b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>主站協議網關配置詳情

    Profibus-DP主站轉Modbus-TCP協議網關(YC-DPM-TCP

    Profibus-DP轉Modbus-TCP如何實現高效且穩定的連接與通信,很多朋友想要知道這個問題的答案。現在作者為大家詳細解讀這一難題。遠創智控YC-DPM-TCP型設備可以幫助大家很好
    的頭像 發表于 08-30 10:23 ?472次閱讀
    Profibus-DP主站轉<b class='flag-5'>Modbus-TCP</b>協議網關(YC-DPM-<b class='flag-5'>TCP</b>)

    EtherCAT轉Modbus-TCP協議網關(Modbus-TCP轉EtherCAT)

    EtherCAT轉Modbus-TCP實現網絡協議互通是眾人關注焦點,遠創智控YC-ECT-TCP能夠很輕松解決這個問題。在這里作者將從該設備的主要功能、技術參數、性能優勢、配置方法等幾個方面詳細
    的頭像 發表于 09-04 09:59 ?576次閱讀
    EtherCAT轉<b class='flag-5'>Modbus-TCP</b>協議網關(<b class='flag-5'>Modbus-TCP</b>轉EtherCAT)

    Profibus DP轉Modbus TCP協議網關

    Profibus DP轉Modbus TCP 實現網絡協議互通這一問題備受眾人矚目,而 遠創智控YC-DPM-TCP 可以輕松化解這一難題。接下來,作者將從該設備的主要功能、技術參數、
    的頭像 發表于 09-04 21:54 ?442次閱讀
    Profibus DP轉<b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>協議網關

    EtherCAT轉Modbus TCP協議網關(JM-ECT-TCP

    JM-ECT-TCP網關實現EtherCAT網絡與Modbus TCP網絡之間的數據通訊,即將Modbus
    的頭像 發表于 09-07 17:05 ?624次閱讀
    EtherCAT轉<b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>協議網關(JM-ECT-<b class='flag-5'>TCP</b>)

    MODBUS TCP 轉 CANOpen

    產品概述 SG-TCP-COE-210 網關可以實現將 CANOpen 接口設備連接到 MODBUS TCP 網絡中。用戶不需要了解具體的 CANOpen 和
    的頭像 發表于 09-24 13:59 ?515次閱讀
    <b class='flag-5'>MODBUS</b> <b class='flag-5'>TCP</b> 轉 CANOpen

    EtherNet/IP-Modbus TCP轉換秘籍:三菱變頻器牽手西門子PLC配置全解

    EtherNet/IP轉Modbus TCP實現三菱變頻器與西門子PLC通訊的配置案例 一、案例背景 某汽車制造公司擁有一條高度自動化的生產線,該生產線集成了來自不同品牌的機器人、傳感器和檢測設備
    的頭像 發表于 02-10 14:28 ?467次閱讀
    EtherNet/IP-<b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>轉換秘籍:三菱變頻器牽手西門子PLC配置全解

    EtherNet/IP轉Modbus TCP實現三菱變頻器與制造執行系統連接通訊的配置案例

    EtherNet/IP轉Modbus TCP實現三菱變頻器與制造執行系統連接通訊的配置案例 一、案例背景 在一家汽車零部件生產工廠,有一批三菱變頻器用于控制生產設備的電機轉速,如車床、銑床等設備
    的頭像 發表于 02-11 10:26 ?510次閱讀
    EtherNet/IP轉<b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b><b class='flag-5'>實現</b>三菱變頻器與制造執行系統連接通訊的配置案例

    IEC104轉Modbus網關

    、DLT645-1997/2007數據采集,可接IEC104設備、電表等,將采集到的數據轉換為Modbus TCP協議數據或MQTT連接云平臺。IEC104實現客戶端功能,可接入IEC104網絡,對接IEC104
    的頭像 發表于 06-13 10:35 ?195次閱讀
    IEC104轉<b class='flag-5'>Modbus</b>網關
    主站蜘蛛池模板: 西畴县| 玉山县| 凉山| 嘉峪关市| 渭源县| 太谷县| 西宁市| 孝昌县| 资兴市| 洱源县| 赤壁市| 永春县| 合阳县| 元氏县| 邵阳市| 沅江市| 内乡县| 耒阳市| 泽普县| 大余县| 托里县| 水富县| 吉林省| 台南县| 陵水| 舞阳县| 临猗县| 灌云县| 浪卡子县| 内丘县| 区。| 东乡| 岐山县| 武穴市| 内黄县| 长葛市| 建湖县| 元氏县| 札达县| 全椒县| 乐陵市|