Modbus协议栈开发笔记之三:Modbus TCP Server开发
在完成了前面的工作后,我们就可以实现有针对性的应用了,首先我们来实现Modbus TCP的服务器端应用。当然我们不是做具体的应用,而是对Modbus TCP的服务器端应用进行封装以供有需要时调用。
这里我们不涉及TCP的协议,这部分与Modbus没有必然联系,我们只是在其应用层运行Modbus协议而已。
对于Modbus TCP的服务器我们需要实现几个功能:首先是对接收到客户端命令进行解析,我们只实现前面提到的8中常用的功能吗的支持。其次在解析完成后,我们要实现对应各种功能码的操作。具体架构如下:
1、命令解析
服务器作为被动端接收到客户端的请求后,安装请求进行处理。所以服务器接收到信息后首先对其进行解析,这里我们只需要一个解析函数就可以完成,当在具体应用中时只要将接收到的信息调用这个函数解析就可以了。
/*解析接收到的信息,返回响应命令的长度*/
uint16_t ParsingClientAccessCommand(uint8_t *receivedMessage,uint8_t *respondBytes)
其实对外来说只有这一个函数时可见的。当我们要开发一个TCP Server的应用时,就调用这个函数。
2、命令处理
命令解析出来了之后,按不同的功能码来进行不同的处理,我们支持8种功能码,每种功能吗都对应处理部分,很多时候大家都会在解析的时候根据解析结果处理,这势必需要一个很大的解析函数。为了简化操作,我们将每个功能码对应的处理部分都封装为一个函数。然后使用一个函数指针数组来动态调用这些函数,从而简化这些函数。
首先我们需要8个处理对应个功能码操作的函数:
/*处理读线圈状态命令*/
static uint16_t HandleReadCoilStatusCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理读输入状态命令*/
static uint16_t HandleReadInputStatusCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理读保持寄存器命令*/
static uint16_t HandleReadHoldingRegisterCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理读输入寄存器命令*/
static uint16_t HandleReadInputRegisterCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理写单个线圈命令*/
static uint16_t HandleWriteSingleCoilCommand(uint16_t coilAddress,uint16_t coilValue,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理写单个寄存器命令*/
static uint16_t HandleWriteSingleRegisterCommand(uint16_t registerAddress,uint16_t registerValue,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理写多个线圈状态*/
static uint16_t HandleWriteMultipleCoilCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理写多个寄存器状态*/
static uint16_t HandleWriteMultipleRegisterCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
然后我们定义一个函数指针数组来调用这下函数:
uint16_t (*HandleClientCommand[])(uint16_t,uint16_t,uint8_t *,uint8_t *)={HandleReadCoilStatusCommand,
HandleReadInputStatusCommand,
HandleReadHoldingRegisterCommand,
HandleReadInputRegisterCommand,
HandleWriteSingleCoilCommand,
HandleWriteSingleRegisterCommand,
HandleWriteMultipleCoilCommand,
HandleWriteMultipleRegisterCommand};
3、响应的生成
对于响应命令的生成其实在第二篇中已经说过了,需要说明的是各种写数据的具体数值以及获得读数据的各种具体数值我们将在单独的文件中去实现,因为这部分TCP和RTU是相同的,我们将在后续的篇章中说明。
源码网址是:https://github.com/foxclever/Modbus
欢迎关注:
Modbus协议栈开发笔记之三:Modbus TCP Server开发相关推荐
- ATECC508A芯片开发笔记(二):开发准备之 CryptoAuthLib 库简介与移植
目录 ATECC508A芯片开发笔记(二):开发准备之 CryptoAuthLib 库简介与移植 Atmel两个官方lib介绍 一.CryptoAuthLib简介 Lib中最主要的三种对象类型: 二. ...
- 硬件开发笔记(六): 硬件开发基本流程,制作一个USB转RS232的模块(五):创建USB封装库并关联原理图元器件
`该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/125369228 红胖子网络科技博文大全:开发技术集合( ...
- 硬件开发笔记(八): 硬件开发基本流程,制作一个USB转RS232的模块(七):创建基础DIP元器件(晶振)封装并关联原理图元器件
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/125370284 红胖子网络科技博文大全:开发技术集合( ...
- Modbus协议栈应用实例之三:Modbus TCP客户端应用
自从开源了我们自己开发的Modbus协议栈之后,有很多朋友建议我针对性的做几个示例.所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例,这一篇中我们将解说如何使用协议栈实现一个M ...
- 【 Visual C++】游戏开发笔记之三——绘制图元
使用Direct3D绘制图元 我们接下来的部分将介绍使用Direct3D在屏幕上绘图的图元.计算机图形学中的图元是可以渲染到屏幕上的基本形状.将图元组合在一起可以构成不同的形状和物体,诸如人物模型 ...
- 嵌入式系统开发笔记90:ALIENTEK MiniSTM32开发板原理图基本电路讲解
文章目录 前言 一.电源部分 1.USB输入 第一路通过CH340转换为串口信号,接MCU的串口1,该接口可以用于程序下载使用. 第二路直接与MCU的USB口相连接,用于USB通讯操作. 2.电源开关 ...
- SSD202开发笔记 | 01- 东山Pi壹号开发板快速上手(原厂SDK快速入门)
本文中我使用Ubuntu 18.04,阿里源. 一.东山Pi壹号开发板 东山Pi壹号开发板是联合芯片原厂星宸科技一起推的最小Linux开发板: 主控芯片: 星辰科技 SSD202D 内置128MB D ...
- Kinect开发笔记之三Kinect开发环境配置详解
0.前言: 首先说一下我的开发环境,Visual Studio是2013的,系统是win8的64位版本,SDK是Kinect for windows SDK 1.8版本. ...
- LwIP应用开发笔记之三:LwIP无操作系统UDP客户端
前一节我们实现了基于RAW API的UDP服务器,在接下来,我们进一步利用RAW API实现UDP客户端. 1.UDP协议简述 UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包 ...
最新文章
- 使用RNN神经网络自动生成名字 (不使用深度学习框架,源码)
- 开源框架 ImageLoader +ListView+GridView+RecyclerView 浅解
- SAP用户出口(exit)问题--数据源增强
- 初识Caffeine
- P7443-加边【博弈论】
- C++ Variadic Templates(可变参数模板)
- 查询出各个学科的前3名的同学信息的Sql
- simpledateformat格式_大厂都是怎么用Java8代替SimpleDateFormat?
- 安卓数据库的使用方式
- 和电商有关的词语_关于电商的一些词
- 假期最后一天,出差赶到天津
- word方框中打√符号的方法
- macbook配置java环境变量_MAC安装JDK及环境变量配置
- 投后电视显示无法连接服务器,苹果AirPlay怎么用:AirPlay在哪设置,无法连接电视怎么办?...
- 异常解决之——无法在Web服务器上启动调试。远程服务器返回错误:(405)
- BackTrack5 学习笔记5 扫描 Nmap
- 什么是计算机嵌套分类汇总,Excel中插入分类汇总的嵌套级别的方法图解详细教程...
- opencv inrange函数
- OCR应用:证件识别
- 进阶面试的必看的ORM架构之 ORM简介
热门文章
- VM虚拟机下配置centos linux系统
- oracle数据库启动
- Dynamics CRM 依赖组件类型为应用程序功能区导致的无法删除实体问题的解决方法...
- volatile关键字及编译器指令乱序总结
- 【转】如何让ucgui支持24位色(24bpp)
- [译]How to make searching faster
- 牛客13592 武藏牌牛奶促销
- 动态规划--Leetcode62--不同路径
- linux非权限安装bioperl,Bioperl的简单安装
- 桌面图标设计里的计算机是灰色的,小技巧教您如何将Windows 10上的桌面图标设置中的回收站为灰色!...