关于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个字节来表示寄存器数量,这个还没有做深入研究,可能是考虑协议的整体兼容性吧,有兴趣的朋友可以一起讨论。

文章在微信公众号同步推出,微信公众号:孔丙火,关注欣赏更多文章。

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在FreeRTOS使用FreeModbus协议,需要进行以下步骤: 1. 首先,下载并安装FreeModbus库。可以从官方网站或GitHub上获取最新的FreeModbus源代码。将下载的文件解压缩,并将库文件添加到FreeRTOS项目的源文件目录。 2. 在FreeRTOS的配置文件,启用串口或网络功能,以便使用FreeModbus协议。根据需要选择适当的通信接口,可以是RS485、TCP/IP等。 3. 创建一个任务来处理FreeModbus通信。在FreeRTOS,使用任务来实现并发操作。可以使用FreeRTOS的任务API来创建和管理任务。在创建任务时,指定任务函数,该函数将用于处理Modbus协议的通信。 4. 在任务函数,初始化Modbus实例。使用FreeModbus提供的初始化函数来配置适当的Modbus参数,如串口波特率、从机地址等。 5. 在任务函数,创建Modbus请求或响应。根据需要,使用FreeModbus API创建适当的Modbus请求或响应对象,并填充所需的信息,如功能码、寄存器地址、数据等。 6. 在任务函数,使用FreeModbus API发送和接收Modbus数据。根据需要,使用适当的FreeModbus函数发送Modbus请求或接收Modbus响应。这可以通过串口或网络进行。确保处理适当的错误检查和错误处理,以确保通信的可靠性和正确性。 7. 在任务函数,处理Modbus数据。使用接收到的Modbus响应数据或通过FreeModbus函数获取的Modbus数据,进行适当的处理。可以分析、转换、存储或显示数据,以满足应用程序的要求。 8. 根据需求和应用程序的要求,实现其他功能。可以添加其他任务、定时器、断处理等,以满足系统的需求。 总结来说,在FreeRTOS使用FreeModbus协议需要下载并安装FreeModbus库,创建一个任务来处理通信,初始化Modbus实例,在任务函数使用FreeModbus API发送和接收Modbus数据,并进行相应的处理。通过这些步骤,可以在FreeRTOS成功使用FreeModbus协议进行通信。 ### 回答2: FreeRTOS是一款用于嵌入式系统的实时操作系统,而FreeModbus是基于Modbus通信协议的开源库。在FreeRTOS使用FreeModbus可以实现在嵌入式系统上进行Modbus通信的功能。 首先,我们需要将FreeModbus库添加到FreeRTOS工程。可以从FreeModbus的官方网站下载最新的库文件,并将其包含到FreeRTOS项目。 接下来,我们需要创建一个Modbus任务来处理Modbus通信。在FreeRTOS可以使用任务(Task)来实现多线程的功能。可以使用FreeRTOS提供的任务创建函数来创建一个任务,将Modbus的处理函数作为任务的入口。 在Modbus任务的处理函数,我们可以调用FreeModbus库提供的函数来实现Modbus的功能,比如读取和写入寄存器等。可以根据具体的需求来调用不同的函数,完成对Modbus协议的支持。   需要注意的是,由于FreeRTOS是一个实时操作系统,任务之间的调度是由系统内核来完成的。因此,在使用FreeModbus时,我们需要合理地设置任务的优先级,以确保Modbus任务能够及时地响应Modbus通信请求。 另外,为了保证Modbus通信的可靠性,我们还可以使用FreeModbus提供的错误处理机制。通过设置错误处理回调函数,可以在出现错误时及时地捕获并处理异常情况,提高系统的可靠性。 总结来说,在FreeRTOS使用FreeModbus协议,我们需要将FreeModbus库添加到FreeRTOS项目,并创建一个Modbus任务来处理Modbus通信。通过合理设置任务的优先级和使用错误处理机制,可以实现在嵌入式系统Modbus通信的支持。 ### 回答3: FreeRTOS是一个开源的实时操作系统内核,可用于轻量级嵌入式系统。而FreeModbus是一个自由、开放的Modbus通信协议栈,用于实现Modbus协议的通信。 在FreeRTOS使用FreeModbus协议,可以实现在嵌入式系统使用Modbus通信协议进行数据交换。具体步骤如下: 1. 下载并导入FreeModbus通信协议栈的源代码文件,包括modbus.h和modbus.c等文件。 2. 在FreeRTOS的工程,通过引入相应的头文件,将FreeModbus的功能添加到应用程序。 3. 在FreeRTOS的任务,创建一个Modbus任务,该任务将负责执行Modbus协议的通信操作。 4. 在Modbus任务,使用FreeModbus提供的API函数,配置Modbus从站或主站的参数,例如串口的通信参数、Modbus地址等。 5. 在Modbus任务,编写处理Modbus通信的代码,包括接收和发送Modbus帧、解析和处理Modbus命令等。 6. 在FreeRTOS的其他任务,可以通过调用Modbus任务提供的API函数,实现与Modbus从站或主站的通信。 使用FreeRTOS和FreeModbus协议栈,我们可以实现Modbus通信的功能,例如在工业自动化系统,可以实现设备之间的数据交换和控制指令的传递。同时,由于FreeRTOS的实时性和可靠性,可以确保Modbus通信的可靠性和实时性。 需要注意的是,在使用FreeRTOS和FreeModbus时,需要根据具体的嵌入式硬件平台和通信需求进行相应的配置和调试。同时,还需要注意资源的管理和任务的优先级设置,以确保系统的稳定性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值