FreeModbus解析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

FreeModbus解析
简介:
Freemodbus是一个奥地利人写的modbus协议栈。

是针对通用的Modbus协议栈在嵌入式系统中应用的一个实现。

Modbus协议是一个在工业制造领域中得到广泛应用的一个网络协议。

一个Modbus通信协议栈包括两层:定义了数据结构和功能Modbus应用协议和网络层。

在FreeMODBUS的当前版本中,提供了Modbus Application Protocol v1.1a 的实现并且支持在Modbus over serial line specification 1.0中定义的RTU/ASCII传输模式。

从0.7版本开始,FreeModbus也支持在TCP defined in Modbus Messaging on TCP/IP Implementation Guide v1.0a 中定义的TCP传输。

Freemodbus遵循BSD[1] ,这意味着本协议栈的实现代码可以应用于商业用途。

目前版本的FreeModbus支持如下的功能码:
写单个线圈(0x05)
写多个线圈(0x0F)
读输入状态(0x02)
报告从机标识(0x11)
本实现基于最新的标准并且与标准完全兼容。

接收和传输Modbus RTU/ASCII数据帧是通过一个由硬件提取层的调用来驱动状态机来实现的。

这就使得该协议非常容易移植到其他的平台之上。

当收到一个完整的数据帧后,该数据帧被传入Modbus应用层,数据帧的内容在该层得到解析。

为例方便增加新的Modbus功能,Freemodbus在应用层通提供了Hooks。

如果用到了Modbus TCP协议,那么当准备处理一个新数据帧的时候,移植层就必须首先向协议栈发送一个事件标志。

然后,协议栈调用一个返回值为接收到的Modbus TCP数据帧的函数,并且开始处理这个数据帧。

如果数据有效,则相应的Modbus反馈帧将提供给移植层生成反馈帧。

最后,该反馈被发送到客户端。

Freemodbus软件结构
整个系统的移植可由通过定义port目录中的函数实现,如at91sam7x的实现中,主要是将modbus的物理层链路与具体平台的硬件驱动联系起来,以实现平台的移植性。

Freemodbus逻辑结构图
文档结构图
功能实现Mbproto.h
功能代码定义
异常代码定义
功能函数指针定义
Mbfunc.h
功能函数定义
分别定义在Mbfunccoils.c
eMBException
eMBFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen ) {
USHORT usRegAddress;
USHORT usCoilCnt;
UCHAR ucByteCount;
UCHAR ucByteCountVerify;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen > ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8 );
usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] );
usRegAddress++;
usCoilCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF] << 8 );
usCoilCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF + 1] );
ucByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];
/* Compute the number of expected bytes in the request. */
if( ( usCoilCnt & 0x0007 ) != 0 )
{
ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 + 1 );
}
else
{
ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 );
}
if( ( usCoilCnt >= 1 ) &&
( usCoilCnt <= MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX ) &&
( ucByteCountVerify == ucByteCount ) )
{
eRegStatus =
eMBRegCoilsCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF],
usRegAddress, usCoilCnt, MB_REG_WRITE );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
else
{
/* The response contains the function code, the starting address
* and the quantity of registers. We reuse the old values in the
* buffer because they are still valid. */
*usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
else
{
/* Can't be a valid write coil register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
此代码代中,调用了顶层的eMBRegCoilsCB实现了具体的功能,其他代码均为初始化及异常处理用。

该段代码的功能流程如下图所示:。

相关文档
最新文档