1、【增加】主机模式下从机节点相关数据模型;

2、【更新】Modbus主机模式下相关回调函数;
3、【更新】《FreeModbus 主机分析图》;
4、【增加】主机模式下支持的从机最大数宏定义,默认16;

Signed-off-by: armink <armink.ztl@gmail.com>
This commit is contained in:
armink 2013-08-27 18:08:31 +08:00
parent 20239198e5
commit e8c502eca6
11 changed files with 214 additions and 61 deletions

View File

@ -12,7 +12,7 @@
#include "bsp.h"
#include "delay_conf.h"
#include "cpuusage.h"
#include "user_app.h"
#include "user_mb_app.h"
/*******************************************************************************************************/
// DEFINES
@ -26,10 +26,10 @@
#define true 1
extern uint16_t usDiscreteInputBuf[] ;
extern uint16_t usCoilBuf[] ;
extern uint16_t usRegInputBuf[] ;
extern uint16_t usRegHoldingBuf[] ;
extern uint16_t ucSDiscInBuf[] ;
extern uint16_t ucSCoilBuf[] ;
extern uint16_t usSRegInBuf[] ;
extern uint16_t usSRegHoldBuf[] ;

View File

@ -32,8 +32,8 @@ void thread_entry_SysMonitor(void* parameter)
while (1)
{
cpu_usage_get(&CpuUsageMajor, &CpuUsageMinor);
usRegHoldingBuf[HD_CPU_USAGE_MAJOR] = CpuUsageMajor;
usRegHoldingBuf[HD_CPU_USAGE_MINOR] = CpuUsageMinor;
usSRegHoldBuf[S_HD_CPU_USAGE_MAJOR] = CpuUsageMajor;
usSRegHoldBuf[S_HD_CPU_USAGE_MINOR] = CpuUsageMinor;
LED_LED1_ON;
LED_LED2_ON;
rt_thread_delay(DELAY_SYS_RUN_LED);

View File

@ -23,7 +23,6 @@
#include <bsp.h>
#include <rthw.h>
#include <rtthread.h>
#include "user_app.h"
/*
*********************************************************************************************************
* LOCAL TABLES

Binary file not shown.

View File

@ -150,6 +150,9 @@ typedef enum
*/
eMBErrorCode eMBInit( eMBMode eMode, UCHAR ucSlaveAddress,
UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity );
/* This callback function will be use in Modbus Master mode.*/
eMBErrorCode eMBMasterInit( eMBMode eMode, UCHAR ucPort,
ULONG ulBaudRate, eMBParity eParity );
/*! \ingroup modbus
* \brief Initialize the Modbus protocol stack for Modbus TCP.
@ -182,6 +185,8 @@ eMBErrorCode eMBTCPInit( USHORT usTCPPort );
* eMBErrorCode::MB_EILLSTATE.
*/
eMBErrorCode eMBClose( void );
/* This callback function will be use in Modbus Master mode.*/
eMBErrorCode eMBMasterClose( void );
/*! \ingroup modbus
* \brief Enable the Modbus protocol stack.
@ -194,6 +199,8 @@ eMBErrorCode eMBClose( void );
* return eMBErrorCode::MB_EILLSTATE.
*/
eMBErrorCode eMBEnable( void );
/* This callback function will be use in Modbus Master mode.*/
eMBErrorCode eMBMasterEnable( void );
/*! \ingroup modbus
* \brief Disable the Modbus protocol stack.
@ -205,6 +212,8 @@ eMBErrorCode eMBEnable( void );
* eMBErrorCode::MB_EILLSTATE.
*/
eMBErrorCode eMBDisable( void );
/* This callback function will be use in Modbus Master mode.*/
eMBErrorCode eMBMasterDisable( void );
/*! \ingroup modbus
* \brief The main pooling loop of the Modbus protocol stack.
@ -219,6 +228,8 @@ eMBErrorCode eMBDisable( void );
* eMBErrorCode::MB_ENOERR.
*/
eMBErrorCode eMBPoll( void );
/* This callback function will be use in Modbus Master mode.*/
eMBErrorCode eMBMasterPoll( void );
/*! \ingroup modbus
* \brief Configure the slave id of the device.
@ -311,6 +322,9 @@ eMBErrorCode eMBRegisterCB( UCHAR ucFunctionCode,
*/
eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNRegs );
/* This callback function will be use in Modbus Master mode.*/
eMBErrorCode eMBRegMasterInputCB( UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNRegs );
/*! \ingroup modbus_registers
* \brief Callback function used if a <em>Holding Register</em> value is
@ -346,6 +360,9 @@ eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress,
*/
eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNRegs, eMBRegisterMode eMode );
/* This callback function will be use in Modbus Master mode.*/
eMBErrorCode eMBMasterRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNRegs, eMBRegisterMode eMode );
/*! \ingroup modbus_registers
* \brief Callback function used if a <em>Coil Register</em> value is
@ -381,6 +398,9 @@ eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress,
*/
eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNCoils, eMBRegisterMode eMode );
/* This callback function will be use in Modbus Master mode.*/
eMBErrorCode eMBMasterRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNCoils, eMBRegisterMode eMode );
/*! \ingroup modbus_registers
* \brief Callback function used if a <em>Input Discrete Register</em> value is
@ -410,6 +430,9 @@ eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress,
*/
eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNDiscrete );
/* This callback function will be use in Modbus Master mode.*/
eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNDiscrete );
#ifdef __cplusplus
PR_END_EXTERN_C

View File

@ -116,6 +116,9 @@ PR_BEGIN_EXTERN_C
* And if slaver is not respond in this time,the master will process this timeout error.
* Then master can send other frame */
#define MB_MASTER_TIMEOUT_MS_RESPOND (2000)
/*! \brief The total slaves in Modbus Master system.Default 16.
* Note : The slave ID must be continuous from 0.*/
#define MB_MASTER_TOTAL_SLAVE_NUM ( 16 )
#endif
#endif

View File

@ -62,7 +62,8 @@
/* ----------------------- Static variables ---------------------------------*/
static UCHAR ucMBMasterSendAddress;
volatile UCHAR ucMBMasterSendAddress;
volatile BOOL bMBRunInMasterMode = FALSE;
static eMBMode eMBCurrentMode;
static UCHAR ucMasterRTUBuf[MB_PDU_SIZE_MAX];
static UCHAR * pucMasterPUDBuf = ucMasterRTUBuf + 1;
@ -249,7 +250,8 @@ eMBMasterDisable( void )
return eStatus;
}
eMBErrorCode eMBMasterPoll( void )
eMBErrorCode
eMBMasterPoll( void )
{
static UCHAR ucRcvAddress;
static UCHAR ucFunctionCode;
@ -300,7 +302,9 @@ eMBErrorCode eMBMasterPoll( void )
}
else if( xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode )
{
bMBRunInMasterMode = TRUE;
eException = xMasterFuncHandlers[i].pxHandler( pucMasterPUDBuf, &usLength );
bMBRunInMasterMode = FALSE;
break;
}
}

View File

@ -188,6 +188,8 @@ eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength
eMBErrorCode eStatus = MB_ENOERR;
USHORT usCRC16;
if ( ucSlaveAddress > MB_MASTER_TOTAL_SLAVE_NUM ) return MB_EINVAL;
ENTER_CRITICAL_SECTION( );
/* Check if the receiver is still in idle state. If not we where to

View File

@ -1,34 +0,0 @@
#ifndef USER_APP
#define USER_APP
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
/* ----------------------- Defines ------------------------------------------*/
#define DISCRETE_INPUT_START 1
#define DISCRETE_INPUT_NDISCRETES 16
#define COIL_START 1
#define COIL_NCOILS 64
#define REG_INPUT_START 1
#define REG_INPUT_NREGS 100
#define REG_HOLDING_START 1
#define REG_HOLDING_NREGS 100
//===========================在保持寄存器中,各个地址对应的功能定义========================
#define HD_RESERVE 0 //保留
#define HD_CPU_USAGE_MAJOR 1 //当前CPU利用率的整数位
#define HD_CPU_USAGE_MINOR 2 //当前CPU利用率的小数位
//===========================在输入寄存器中,各个地址对应的功能定义========================
#define IN_RESERVE 0 //保留
//===========================在线圈中,各个地址对应的功能定义============================
#define CO_RESERVE 2 //保留
//===========================在离散输入中,各个地址对应的功能定义=========================
#define DI_RESERVE 1 //保留
/*--------------------------Extern Functions------------------------------------*/
extern UCHAR xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits );
extern void xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits,UCHAR ucValue );
#endif

View File

@ -1,14 +1,28 @@
#include "user_app.h"
#include "user_mb_app.h"
/* ----------------------- Variables ---------------------------------*/
USHORT usDiscreteInputStart = DISCRETE_INPUT_START;
UCHAR usDiscreteInputBuf[DISCRETE_INPUT_NDISCRETES/8] ;
USHORT usCoilStart = COIL_START;
UCHAR usCoilBuf[COIL_NCOILS/8] ;
USHORT usRegInputStart = REG_INPUT_START;
USHORT usRegInputBuf[REG_INPUT_NREGS] ;
USHORT usRegHoldingStart = REG_HOLDING_START;
USHORT usRegHoldingBuf[REG_HOLDING_NREGS] ;
//Slave mode use these variables
USHORT usSDiscInStart = S_DISCRETE_INPUT_START;
UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8];
USHORT usSCoilStart = S_COIL_START;
UCHAR ucSCoilBuf[S_COIL_NCOILS/8] ;
USHORT usSRegInStart = S_REG_INPUT_START;
USHORT usSRegInBuf[S_REG_INPUT_NREGS] ;
USHORT usSRegHoldStart = S_REG_HOLDING_START;
USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS] ;
//Master mode use these variables
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
USHORT usMDiscInStart = M_DISCRETE_INPUT_START;
UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8];
USHORT usMCoilStart = M_COIL_START;
UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8];
USHORT usMRegInStart = M_REG_INPUT_START;
USHORT usMRegInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_INPUT_NREGS];
USHORT usMRegHoldStart = M_REG_HOLDING_START;
USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
extern volatile UCHAR ucMBMasterSendAddress;
extern volatile BOOL bMBRunInMasterMode;
#endif
//******************************输入寄存器回调函数**********************************
//函数定义: eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
//描 述:输入寄存器相关的功能(读、连续读)
@ -23,14 +37,35 @@ eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
eMBErrorCode eStatus = MB_ENOERR;
int iRegIndex;
USHORT * pusRegInputBuf;
UCHAR REG_INPUT_START;
UCHAR REG_INPUT_NREGS;
UCHAR usRegInStart;
//Determine the master or slave
if (bMBRunInMasterMode)
{
pusRegInputBuf = usMRegInBuf[ucMBMasterSendAddress];
REG_INPUT_START = M_REG_INPUT_START;
REG_INPUT_NREGS = M_REG_INPUT_NREGS;
usRegInStart = usMRegInStart;
}
else
{
pusRegInputBuf = usSRegInBuf;
REG_INPUT_START = S_REG_INPUT_START;
REG_INPUT_NREGS = S_REG_INPUT_NREGS;
usRegInStart = usSRegInStart;
}
if( ( usAddress >= REG_INPUT_START )
&& ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
{
iRegIndex = ( int )( usAddress - usRegInputStart );
iRegIndex = ( int )( usAddress - usRegInStart );
while( usNRegs > 0 )
{
*pucRegBuffer++ = ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 );
*pucRegBuffer++ = ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );
*pucRegBuffer++ = ( unsigned char )( pusRegInputBuf[iRegIndex] >> 8 );
*pucRegBuffer++ = ( unsigned char )( pusRegInputBuf[iRegIndex] & 0xFF );
iRegIndex++;
usNRegs--;
}
@ -59,10 +94,31 @@ eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegi
{
eMBErrorCode eStatus = MB_ENOERR;
int iRegIndex;
USHORT * usRegHoldingBuf;
UCHAR REG_HOLDING_START;
UCHAR REG_HOLDING_NREGS;
UCHAR usRegHoldStart;
//Determine the master or slave
if (bMBRunInMasterMode)
{
usRegHoldingBuf = usMRegHoldBuf[ucMBMasterSendAddress];
REG_HOLDING_START = M_REG_HOLDING_START;
REG_HOLDING_NREGS = M_REG_HOLDING_NREGS;
usRegHoldStart = usMRegHoldStart;
}
else
{
usRegHoldingBuf = usSRegInBuf;
REG_HOLDING_START = S_REG_INPUT_START;
REG_HOLDING_NREGS = S_REG_INPUT_NREGS;
usRegHoldStart = usSRegInStart;
}
if( ( usAddress >= REG_HOLDING_START ) &&
( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) )
{
iRegIndex = ( int )( usAddress - usRegHoldingStart );
iRegIndex = ( int )( usAddress - usRegHoldStart );
switch ( eMode )
{
/* Pass current register values to the protocol stack. */
@ -113,6 +169,27 @@ eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegis
eMBErrorCode eStatus = MB_ENOERR;
int iRegIndex , iRegBitIndex , iNReg;
iNReg = usNCoils / 8 + 1; //占用寄存器数量
UCHAR * ucCoilBuf;
UCHAR COIL_START;
UCHAR COIL_NCOILS;
UCHAR usCoilStart;
//Determine the master or slave
if (bMBRunInMasterMode)
{
ucCoilBuf = ucMCoilBuf[ucMBMasterSendAddress];
COIL_START = M_COIL_START;
COIL_NCOILS = M_COIL_NCOILS;
usCoilStart = usMCoilStart;
}
else
{
ucCoilBuf = ucSCoilBuf;
COIL_START = S_COIL_START;
COIL_NCOILS = S_COIL_NCOILS;
usCoilStart = usSCoilStart;
}
if( ( usAddress >= COIL_START ) &&
( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) )
{
@ -124,7 +201,7 @@ eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegis
case MB_REG_READ:
while( iNReg > 0 )
{
*pucRegBuffer++ = xMBUtilGetBits(&usCoilBuf[iRegIndex++] , iRegBitIndex , 8);
*pucRegBuffer++ = xMBUtilGetBits(&ucCoilBuf[iRegIndex++] , iRegBitIndex , 8);
iNReg --;
}
pucRegBuffer --;
@ -138,11 +215,11 @@ eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegis
case MB_REG_WRITE:
while(iNReg > 1) //最后面余下来的数单独算
{
xMBUtilSetBits(&usCoilBuf[iRegIndex++] , iRegBitIndex , 8 , *pucRegBuffer++);
xMBUtilSetBits(&ucCoilBuf[iRegIndex++] , iRegBitIndex , 8 , *pucRegBuffer++);
iNReg--;
}
usNCoils = usNCoils % 8; //余下的线圈数
xMBUtilSetBits(&usCoilBuf[iRegIndex++] , iRegBitIndex , usNCoils , *pucRegBuffer++);
xMBUtilSetBits(&ucCoilBuf[iRegIndex++] , iRegBitIndex , usNCoils , *pucRegBuffer++);
break;
}
}
@ -168,6 +245,27 @@ eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
eMBErrorCode eStatus = MB_ENOERR;
int iRegIndex , iRegBitIndex , iNReg;
iNReg = usNDiscrete / 8 + 1; //占用寄存器数量
UCHAR * ucDiscreteInputBuf;
UCHAR DISCRETE_INPUT_START;
UCHAR DISCRETE_INPUT_NDISCRETES;
UCHAR usDiscreteInputStart;
//Determine the master or slave
if (bMBRunInMasterMode)
{
ucDiscreteInputBuf = ucMDiscInBuf[ucMBMasterSendAddress];
DISCRETE_INPUT_START = M_DISCRETE_INPUT_START;
DISCRETE_INPUT_NDISCRETES = M_DISCRETE_INPUT_NDISCRETES;
usDiscreteInputStart = usMDiscInStart;
}
else
{
ucDiscreteInputBuf = ucSDiscInBuf;
DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;
DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;
usDiscreteInputStart = usSDiscInStart;
}
if( ( usAddress >= DISCRETE_INPUT_START )
&& ( usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES ) )
{
@ -175,7 +273,7 @@ eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
iRegBitIndex = ( int )( usAddress - usDiscreteInputStart ) % 8 ; //相对于寄存器内部的位地址
while( iNReg > 0 )
{
*pucRegBuffer++ = xMBUtilGetBits(&usDiscreteInputBuf[iRegIndex++] , iRegBitIndex , 8);
*pucRegBuffer++ = xMBUtilGetBits(&ucDiscreteInputBuf[iRegIndex++] , iRegBitIndex , 8);
iNReg --;
}
pucRegBuffer --;

View File

@ -0,0 +1,58 @@
#ifndef USER_APP
#define USER_APP
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "mbconfig.h"
/* -----------------------Slave Defines -------------------------------------*/
#define S_DISCRETE_INPUT_START 1
#define S_DISCRETE_INPUT_NDISCRETES 16
#define S_COIL_START 1
#define S_COIL_NCOILS 64
#define S_REG_INPUT_START 1
#define S_REG_INPUT_NREGS 100
#define S_REG_HOLDING_START 1
#define S_REG_HOLDING_NREGS 100
//从机模式:在保持寄存器中,各个地址对应的功能定义
#define S_HD_RESERVE 0 //保留
#define S_HD_CPU_USAGE_MAJOR 1 //当前CPU利用率的整数位
#define S_HD_CPU_USAGE_MINOR 2 //当前CPU利用率的小数位
//从机模式:在输入寄存器中,各个地址对应的功能定义
#define S_IN_RESERVE 0 //保留
//从机模式:在线圈中,各个地址对应的功能定义
#define S_CO_RESERVE 2 //保留
//从机模式:在离散输入中,各个地址对应的功能定义
#define S_DI_RESERVE 1 //保留
/* -----------------------Master Defines -------------------------------------*/
#define M_DISCRETE_INPUT_START 1
#define M_DISCRETE_INPUT_NDISCRETES 16
#define M_COIL_START 1
#define M_COIL_NCOILS 64
#define M_REG_INPUT_START 1
#define M_REG_INPUT_NREGS 100
#define M_REG_HOLDING_START 1
#define M_REG_HOLDING_NREGS 100
//主机模式:在保持寄存器中,各个地址对应的功能定义
#define M_HD_RESERVE 0 //保留
//主机模式:在输入寄存器中,各个地址对应的功能定义
#define M_IN_RESERVE 0 //保留
//主机模式:在线圈中,各个地址对应的功能定义
#define M_CO_RESERVE 2 //保留
//主机模式:在离散输入中,各个地址对应的功能定义
#define M_DI_RESERVE 1 //保留
/*--------------------------Extern Functions------------------------------------*/
extern UCHAR xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits );
extern void xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits,UCHAR ucValue );
#endif