关于freemodbus协议中eMBFuncReadHoldingRegister()函数的所谓错误
摘要:网上看到有好心的网友提示,freemodbus协议中的mbfuncholding.c 文件中eMBFuncReadHoldingRegister()函数,有一处错误,即:第185行的“usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );”应为“usRegCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );”,我认为这不能算是一个错误,且听我的分析。
关键词:freemodbus Modbus 保持寄存器 eMBFuncReadHoldingRegister
1.关于freemodbus协议栈的一点粗浅体会
Modbus通信协议,搞过工业控制的人,多多少少应该了解一点。其结构简单,应用广泛。几乎是很多PLC的标配接口。但其通信规约也有几十页之多,要在单片机上实现,如果自己写源代码,估计还是需要一些时间的,因为不光要实现常用的功能,还要保持协议的完整性和错误处理机制。
freemodbus是一个比较完整的协议栈,有机构在维护,并且开源。有点单片机基础得朋友,1个小时应该可以移植好(前提能参考一个不错的教程)。比自己撸代码快N倍。个人感觉这个协议栈还是很好用的,但免费的只支持从站,需要做主站就要自己再想办法了。
2.为什么说这不算个错误
首先要看这句代码是干什么用的?上下文如下:
usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
usRegAddress++;
usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 );
usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
pucFrame[MB_PDU_FUNC_READ_ADDR_OFF]存储的是Modbus数据帧中寄存器起始地址的高字节,pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] 存储的是Modbus数据帧中寄存器起始地址的低字节,pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] 存储的是Modbus数据帧中寄存器个数的高字节,pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] 存储的是Modbus数据帧中寄存器个数的低字节。
下面给一个实例,能更好理解,如图1。此帧数据是读取地址为1的从站的保持寄存器,寄存器起始地址为:18430(0x47FE),读取寄存器的个数为:101(0x0065),在这里:
pucFrame[MB_PDU_FUNC_READ_ADDR_OFF]的值为:0x47;
pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] 的值为:0xFE;
pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] 的值为:0x00;
pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] 的值为:0x65。
从这里也可以看出,Modbus在发送一个word(16bit)数据的时候,是高字节在前,低字节在后。

图1
既然pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] 表示的是寄存器个数的高字节,那么我们来查看一下Modbus协议,看一下这个参数的范围,如图2、图3所示。此两图是从Modbus协议文本中截出来的,0x03功能码是读保持寄存器,0x10功能码是写多个保持寄存器,这两个功能码会涉及到保持寄存器数量的问题,寄存器数量的范围一个是0x7D,一个是0x78,都在一个字节的范围内,因此,寄存器数量这个参数的高字节始终为0,也就是说pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF]是等于0的,可以不处理。

图2

图3
3.总结及讨论
综上,我认为这个不能算是个错误,不影响程序的正常结果,只是写法不够严谨。但有一个极端情况,是有影响的,Modbus主站读写寄存器的数量超过协议规定的数量的时候,本应该返回错误码,但这种写法由于只处理了低字节,就有可能认为没有错误,而对数据进行处理。为了安全起见,大家还是把这句代码改掉吧,改为“usRegCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );”,以防止极端情况的发生。
还有一个问题,Modbus协议规定的读写保持寄存器的数量都在一个字节的范围内,发送数据的时候为什么要用2个字节来表示寄存器数量,这个还没有做深入研究,可能是考虑协议的整体兼容性吧,有兴趣的朋友可以一起讨论。
关于freemodbus协议中eMBFuncReadHoldingRegister()函数的所谓错误的更多相关文章
- 《APUE》中的函数整理
第1章 unix基础知识 1. char *strerror(int errnum) 该函数将errnum(就是errno值)映射为一个出错信息字符串,返回该字符串指针.声明在string.h文件中. ...
- [VBA]用一个简单例子说明如何在Excel中自定义函数
Excel中的函数无疑是强大的,但是再强大的战士也有他脆弱的脚后跟[1].这两天在使用Excel的时候遇到了一个需求,要在某一个单元格里面自动计算今天是星期几(如显示 Today is Tuesday ...
- Socks5协议中文文档
译者:Radeon(Radeon bise@cmmail.com) 译文公布时间:2001-6-18 文件夹 1.介绍 2.现有的协议 3.基于TCP协议的客户 4.请求 5.地址 6.应答 7.基于 ...
- TCP/IP协议中backlog参数
TCP建立连接是要进行三次握手,但是否完成三次握手后,服务器就处理(accept)呢? backlog其实是一个连接队列,在Linux内核2.2之前,backlog大小包括半连接状态和全连接状态两种队 ...
- JS中的函数、Bom、DOM及JS事件
本期博主给大家带来JS的函数.Bom.DOM操作,以及JS各种常用的数据类型的相关知识,同时,这也是JavaScript极其重要的部分,博主将详细介绍各种属性的用法和方法. 一.JS中的函数 [函数的 ...
- JS中的函数、BOM和DOM操作
一.JS中的函数 [关于注释] /** [文档注释]:开头两个*.写在函数上方,在调用函数时可以看到文档上方的描述信息. */ // 单行注释 /* 多行注释 */ 1.函数的声明及调用 (1) ...
- DTLS协议中client/server的认证过程和密钥协商过程
我的总结:DTLS的握手就是协商出一个对称加密的秘钥(每个客户端的秘钥都会不一样),之后的通信就要这个秘钥进行加密通信.协商的过程要么使用非对称加密算法进行签名校验身份,要么通过客户端和服务器各自存对 ...
- Http协议中Get和Post的浅谈
起名困难户,每次写文章最愁的就是不知道该如何起个稍具内涵的名字,如果这篇文章我只是写写Get和Post的区别,我可以起个名字“Get和Post的那点事”,如果打算阐述一下Http协议原理性内容,那该叫 ...
- 从TCP三次握手说起–浅析TCP协议中的疑难杂症(2)
版权声明:本文由黄日成原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/108 来源:腾云阁 https://www.qclo ...
随机推荐
- MySQL互联网业务使用建议
一.基础规范 表存储引擎必须使用InnoDB 表字符集默认使用utf8,必要时候使用utf8mb4 解读: (1)通用,无乱码风险,汉字3字节,英文1字节 (2)utf8mb4是utf8的超集,有存储 ...
- AP、AC、无线路由器
起因 AP.AC.无线路由器 一直都傻傻的分不清,今天就好好的研究一下他们之间到底有什么联系和区别~ AP 什么是AP? 无线AP(Access Point):即无线接入点,它用于无线网络的无线交换机 ...
- linux基础:控制台
图形界面切换至命令行界面:ctrl+alt+F1~F6 命令行界面切换至图形界面:startx linux一共有7个运行级别,可查看/etc/inittab文件: 0:停机(记住不要把initdefa ...
- 还不懂Redis?看完这个故事就明白了!
我是Redis 你好,我是Redis,一个叫Antirez的男人把我带到了这个世界上. 说起我的诞生,跟关系数据库MySQL还挺有渊源的. 在我还没来到这个世界上的时候,MySQL过的很辛苦,互联网发 ...
- Georgia and Bob(POJ 1704)
原题如下: Georgia and Bob Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12712 Accepted: ...
- JS -- DOM(文档对象模型)
认识DOM(文档对象模型) DOM(Document Object Model):定义访问和处理HTML文档的标准方法. DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). < ...
- ⏰ Moment.js 宣布停止开发,现在该用什么?
本文整理自 Monent.js 官方英文公告 https://momentjs.com/docs/#/-project-status/ Moment.js 宣布停止开发,进入维护状态. 这是一个大而全 ...
- 文件存到aws的S3后, 调用getimagesize失败分析
一.问题 将图片在windows下用图片查看器修改后,上传到s3中,调用getimagesize获取图片信息总是返回false,其它图片正常: 代码如下: $fileName = 's3://sdk1 ...
- Redis散列(Hash)的相关命令
散列 就像一个减配的Redis 内部及其类似Java的Map 内容就是key:value结构 hash类型在面向对象编程的运用中及其适合,因为它可以直接保存编程语言中的实体类关系 增 hset hse ...
- dubbo学习(五)注册中心zookeeper
初识zookeeper 下载地址:https://archive.apache.org/dist/zookeeper/ 详细的ZooKeeper教程戳这里~ PS: 建议目前选择3.4的稳定版本进行使 ...