mirror of
https://github.com/armink/FreeModbus_Slave-Master-RTT-STM32.git
synced 2024-09-01 08:09:25 +08:00
1、【优化】FreeModbus主机框架,使其与应用软件及从机部分耦合度降低;
2、【增加】主机忙查询、目标从机地址、获取当前PDU总长度等实用Get及Set方法; 3、【修改】user_mb_app.c一处书写错误; 4、【增加】主机读单个及多个寄存器方法,位于mbfuncholding_m.c,目前只实现了异步发送命令,下一步准备实现同步方式; Signed-off-by: armink <armink.ztl@gmail.com>
This commit is contained in:
parent
3947c51e7b
commit
a115bbf3e3
289
FreeModbus/modbus/functions/mbfuncholding_m.c
Normal file
289
FreeModbus/modbus/functions/mbfuncholding_m.c
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
/*
|
||||||
|
* FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
|
||||||
|
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* File: $Id: mbfuncholding_m.c,v 1.60 2013/09/02 14:13:40 Armink Add Master Functions Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ----------------------- System includes ----------------------------------*/
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
/* ----------------------- Platform includes --------------------------------*/
|
||||||
|
#include "port.h"
|
||||||
|
|
||||||
|
/* ----------------------- Modbus includes ----------------------------------*/
|
||||||
|
#include "mb.h"
|
||||||
|
#include "mb_m.h"
|
||||||
|
#include "mbframe.h"
|
||||||
|
#include "mbproto.h"
|
||||||
|
#include "mbconfig.h"
|
||||||
|
|
||||||
|
/* ----------------------- Defines ------------------------------------------*/
|
||||||
|
#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0)
|
||||||
|
#define MB_PDU_FUNC_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
|
||||||
|
#define MB_PDU_FUNC_READ_SIZE ( 4 )
|
||||||
|
#define MB_PDU_FUNC_READ_REGCNT_MAX ( 0x007D )
|
||||||
|
|
||||||
|
#define MB_PDU_FUNC_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF + 0)
|
||||||
|
#define MB_PDU_FUNC_WRITE_VALUE_OFF ( MB_PDU_DATA_OFF + 2 )
|
||||||
|
#define MB_PDU_FUNC_WRITE_SIZE ( 4 )
|
||||||
|
|
||||||
|
#define MB_PDU_FUNC_WRITE_MUL_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
|
||||||
|
#define MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
|
||||||
|
#define MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF ( MB_PDU_DATA_OFF + 4 )
|
||||||
|
#define MB_PDU_FUNC_WRITE_MUL_VALUES_OFF ( MB_PDU_DATA_OFF + 5 )
|
||||||
|
#define MB_PDU_FUNC_WRITE_MUL_SIZE_MIN ( 5 )
|
||||||
|
#define MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX ( 0x0078 )
|
||||||
|
|
||||||
|
#define MB_PDU_FUNC_READWRITE_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
|
||||||
|
#define MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
|
||||||
|
#define MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF + 4 )
|
||||||
|
#define MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF ( MB_PDU_DATA_OFF + 6 )
|
||||||
|
#define MB_PDU_FUNC_READWRITE_BYTECNT_OFF ( MB_PDU_DATA_OFF + 8 )
|
||||||
|
#define MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF ( MB_PDU_DATA_OFF + 9 )
|
||||||
|
#define MB_PDU_FUNC_READWRITE_SIZE_MIN ( 9 )
|
||||||
|
|
||||||
|
/* ----------------------- Static functions ---------------------------------*/
|
||||||
|
eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
|
||||||
|
|
||||||
|
/* ----------------------- Start implementation -----------------------------*/
|
||||||
|
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
||||||
|
#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
|
||||||
|
|
||||||
|
eMBException
|
||||||
|
eMBMasterFuncWriteHoldingRegister( UCHAR ucSndAddr, USHORT * pusDataBuffer, USHORT usRegAddr)
|
||||||
|
{
|
||||||
|
UCHAR *ucMBFrame;
|
||||||
|
eMBException eExceStates = MB_EX_NONE;
|
||||||
|
eMBErrorCode eErrStatus;
|
||||||
|
|
||||||
|
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_ETIMEDOUT;
|
||||||
|
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM) eErrStatus = MB_EINVAL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
vMBMasterSetDestAddress(ucSndAddr);
|
||||||
|
ucMBFrame[MB_PDU_FUNC_OFF] = ( UCHAR ) MB_FUNC_WRITE_REGISTER;
|
||||||
|
ucMBFrame[MB_PDU_FUNC_READ_ADDR_OFF] = ( UCHAR ) usRegAddr >> 8;
|
||||||
|
ucMBFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] = ( UCHAR ) usRegAddr;
|
||||||
|
ucMBFrame[MB_PDU_FUNC_READ_REGCNT_OFF] = ( UCHAR ) pusDataBuffer[0] >> 8;
|
||||||
|
ucMBFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] = ( UCHAR ) pusDataBuffer[0] ;
|
||||||
|
vMBMasterSetRTUSndSndLength( MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE );
|
||||||
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
}
|
||||||
|
/* If an error occured convert it into a Modbus exception. */
|
||||||
|
if( eErrStatus != MB_ENOERR )
|
||||||
|
{
|
||||||
|
eExceStates = prveMBError2Exception( eErrStatus );
|
||||||
|
}
|
||||||
|
return eExceStates;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
|
||||||
|
eMBException
|
||||||
|
eMBMasterFuncWriteMultipleHoldingRegister( UCHAR ucSndAddr,USHORT * pusDataBuffer, USHORT usRegAddr, USHORT usNRegs)
|
||||||
|
{
|
||||||
|
UCHAR *ucMBFrame;
|
||||||
|
USHORT usRegIndex = 0;
|
||||||
|
eMBException eExceStatus = MB_EX_NONE;
|
||||||
|
eMBErrorCode eErrStatus;
|
||||||
|
|
||||||
|
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_ETIMEDOUT;
|
||||||
|
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM || usNRegs > MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX) eErrStatus = MB_EINVAL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
vMBMasterSetDestAddress(ucSndAddr);
|
||||||
|
ucMBFrame[MB_PDU_FUNC_OFF] = ( UCHAR ) MB_FUNC_WRITE_MULTIPLE_REGISTERS;
|
||||||
|
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] = ( UCHAR ) usRegAddr >> 8;
|
||||||
|
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] = ( UCHAR ) usRegAddr;
|
||||||
|
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF] = ( UCHAR ) usNRegs >> 8;
|
||||||
|
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF + 1] = ( UCHAR ) usNRegs ;
|
||||||
|
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF] = ( UCHAR ) usNRegs * 2;
|
||||||
|
ucMBFrame += MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF + 1;
|
||||||
|
while( usNRegs-- > 0)
|
||||||
|
{
|
||||||
|
*ucMBFrame++ = pusDataBuffer[usRegIndex] >> 8;
|
||||||
|
*ucMBFrame++ = pusDataBuffer[usRegIndex++] ;
|
||||||
|
}
|
||||||
|
vMBMasterSetRTUSndSndLength( MB_PDU_SIZE_MIN + MB_PDU_FUNC_WRITE_MUL_SIZE_MIN + 2*usNRegs );
|
||||||
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
}
|
||||||
|
/* If an error occured convert it into a Modbus exception. */
|
||||||
|
if( eErrStatus != MB_ENOERR )
|
||||||
|
{
|
||||||
|
eExceStatus = prveMBError2Exception( eErrStatus );
|
||||||
|
}
|
||||||
|
return eExceStatus;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MB_FUNC_READ_HOLDING_ENABLED > 0
|
||||||
|
|
||||||
|
eMBException
|
||||||
|
eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||||
|
{
|
||||||
|
USHORT usRegAddress;
|
||||||
|
USHORT usRegCount;
|
||||||
|
UCHAR *pucFrameCur;
|
||||||
|
|
||||||
|
eMBException eStatus = MB_EX_NONE;
|
||||||
|
eMBErrorCode eRegStatus;
|
||||||
|
|
||||||
|
if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
|
||||||
|
{
|
||||||
|
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] );
|
||||||
|
|
||||||
|
/* Check if the number of registers to read is valid. If not
|
||||||
|
* return Modbus illegal data value exception.
|
||||||
|
*/
|
||||||
|
if( ( usRegCount >= 1 ) && ( usRegCount <= MB_PDU_FUNC_READ_REGCNT_MAX ) )
|
||||||
|
{
|
||||||
|
/* Set the current PDU data pointer to the beginning. */
|
||||||
|
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
|
||||||
|
*usLen = MB_PDU_FUNC_OFF;
|
||||||
|
|
||||||
|
/* First byte contains the function code. */
|
||||||
|
*pucFrameCur++ = MB_FUNC_READ_HOLDING_REGISTER;
|
||||||
|
*usLen += 1;
|
||||||
|
|
||||||
|
/* Second byte in the response contain the number of bytes. */
|
||||||
|
*pucFrameCur++ = ( UCHAR ) ( usRegCount * 2 );
|
||||||
|
*usLen += 1;
|
||||||
|
|
||||||
|
/* Make callback to fill the buffer. */
|
||||||
|
eRegStatus = eMBRegHoldingCB( pucFrameCur, usRegAddress, usRegCount, MB_REG_READ );
|
||||||
|
/* If an error occured convert it into a Modbus exception. */
|
||||||
|
if( eRegStatus != MB_ENOERR )
|
||||||
|
{
|
||||||
|
eStatus = prveMBError2Exception( eRegStatus );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*usLen += usRegCount * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Can't be a valid request because the length is incorrect. */
|
||||||
|
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
|
||||||
|
}
|
||||||
|
return eStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
|
||||||
|
|
||||||
|
eMBException
|
||||||
|
eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||||
|
{
|
||||||
|
USHORT usRegReadAddress;
|
||||||
|
USHORT usRegReadCount;
|
||||||
|
USHORT usRegWriteAddress;
|
||||||
|
USHORT usRegWriteCount;
|
||||||
|
UCHAR ucRegWriteByteCount;
|
||||||
|
UCHAR *pucFrameCur;
|
||||||
|
|
||||||
|
eMBException eStatus = MB_EX_NONE;
|
||||||
|
eMBErrorCode eRegStatus;
|
||||||
|
|
||||||
|
if( *usLen >= ( MB_PDU_FUNC_READWRITE_SIZE_MIN + MB_PDU_SIZE_MIN ) )
|
||||||
|
{
|
||||||
|
usRegReadAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF] << 8U );
|
||||||
|
usRegReadAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF + 1] );
|
||||||
|
usRegReadAddress++;
|
||||||
|
|
||||||
|
usRegReadCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF] << 8U );
|
||||||
|
usRegReadCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF + 1] );
|
||||||
|
|
||||||
|
usRegWriteAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF] << 8U );
|
||||||
|
usRegWriteAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF + 1] );
|
||||||
|
usRegWriteAddress++;
|
||||||
|
|
||||||
|
usRegWriteCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF] << 8U );
|
||||||
|
usRegWriteCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF + 1] );
|
||||||
|
|
||||||
|
ucRegWriteByteCount = pucFrame[MB_PDU_FUNC_READWRITE_BYTECNT_OFF];
|
||||||
|
|
||||||
|
if( ( usRegReadCount >= 1 ) && ( usRegReadCount <= 0x7D ) &&
|
||||||
|
( usRegWriteCount >= 1 ) && ( usRegWriteCount <= 0x79 ) &&
|
||||||
|
( ( 2 * usRegWriteCount ) == ucRegWriteByteCount ) )
|
||||||
|
{
|
||||||
|
/* Make callback to update the register values. */
|
||||||
|
eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF],
|
||||||
|
usRegWriteAddress, usRegWriteCount, MB_REG_WRITE );
|
||||||
|
|
||||||
|
if( eRegStatus == MB_ENOERR )
|
||||||
|
{
|
||||||
|
/* Set the current PDU data pointer to the beginning. */
|
||||||
|
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
|
||||||
|
*usLen = MB_PDU_FUNC_OFF;
|
||||||
|
|
||||||
|
/* First byte contains the function code. */
|
||||||
|
*pucFrameCur++ = MB_FUNC_READWRITE_MULTIPLE_REGISTERS;
|
||||||
|
*usLen += 1;
|
||||||
|
|
||||||
|
/* Second byte in the response contain the number of bytes. */
|
||||||
|
*pucFrameCur++ = ( UCHAR ) ( usRegReadCount * 2 );
|
||||||
|
*usLen += 1;
|
||||||
|
|
||||||
|
/* Make the read callback. */
|
||||||
|
eRegStatus =
|
||||||
|
eMBRegHoldingCB( pucFrameCur, usRegReadAddress, usRegReadCount, MB_REG_READ );
|
||||||
|
if( eRegStatus == MB_ENOERR )
|
||||||
|
{
|
||||||
|
*usLen += 2 * usRegReadCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( eRegStatus != MB_ENOERR )
|
||||||
|
{
|
||||||
|
eStatus = prveMBError2Exception( eRegStatus );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return eStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
@ -150,9 +150,6 @@ typedef enum
|
|||||||
*/
|
*/
|
||||||
eMBErrorCode eMBInit( eMBMode eMode, UCHAR ucSlaveAddress,
|
eMBErrorCode eMBInit( eMBMode eMode, UCHAR ucSlaveAddress,
|
||||||
UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity );
|
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
|
/*! \ingroup modbus
|
||||||
* \brief Initialize the Modbus protocol stack for Modbus TCP.
|
* \brief Initialize the Modbus protocol stack for Modbus TCP.
|
||||||
@ -185,8 +182,6 @@ eMBErrorCode eMBTCPInit( USHORT usTCPPort );
|
|||||||
* eMBErrorCode::MB_EILLSTATE.
|
* eMBErrorCode::MB_EILLSTATE.
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBClose( void );
|
eMBErrorCode eMBClose( void );
|
||||||
/* This callback function will be use in Modbus Master mode.*/
|
|
||||||
eMBErrorCode eMBMasterClose( void );
|
|
||||||
|
|
||||||
/*! \ingroup modbus
|
/*! \ingroup modbus
|
||||||
* \brief Enable the Modbus protocol stack.
|
* \brief Enable the Modbus protocol stack.
|
||||||
@ -199,8 +194,6 @@ eMBErrorCode eMBMasterClose( void );
|
|||||||
* return eMBErrorCode::MB_EILLSTATE.
|
* return eMBErrorCode::MB_EILLSTATE.
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBEnable( void );
|
eMBErrorCode eMBEnable( void );
|
||||||
/* This callback function will be use in Modbus Master mode.*/
|
|
||||||
eMBErrorCode eMBMasterEnable( void );
|
|
||||||
|
|
||||||
/*! \ingroup modbus
|
/*! \ingroup modbus
|
||||||
* \brief Disable the Modbus protocol stack.
|
* \brief Disable the Modbus protocol stack.
|
||||||
@ -212,8 +205,6 @@ eMBErrorCode eMBMasterEnable( void );
|
|||||||
* eMBErrorCode::MB_EILLSTATE.
|
* eMBErrorCode::MB_EILLSTATE.
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBDisable( void );
|
eMBErrorCode eMBDisable( void );
|
||||||
/* This callback function will be use in Modbus Master mode.*/
|
|
||||||
eMBErrorCode eMBMasterDisable( void );
|
|
||||||
|
|
||||||
/*! \ingroup modbus
|
/*! \ingroup modbus
|
||||||
* \brief The main pooling loop of the Modbus protocol stack.
|
* \brief The main pooling loop of the Modbus protocol stack.
|
||||||
@ -228,8 +219,6 @@ eMBErrorCode eMBMasterDisable( void );
|
|||||||
* eMBErrorCode::MB_ENOERR.
|
* eMBErrorCode::MB_ENOERR.
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBPoll( void );
|
eMBErrorCode eMBPoll( void );
|
||||||
/* This callback function will be use in Modbus Master mode.*/
|
|
||||||
eMBErrorCode eMBMasterPoll( void );
|
|
||||||
|
|
||||||
/*! \ingroup modbus
|
/*! \ingroup modbus
|
||||||
* \brief Configure the slave id of the device.
|
* \brief Configure the slave id of the device.
|
||||||
|
187
FreeModbus/modbus/include/mb_m.h
Normal file
187
FreeModbus/modbus/include/mb_m.h
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
|
||||||
|
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* File: $Id: mb_m.h,v 1.60 2013/09/03 10:20:05 Armink Add Master Functions $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MB_M_H
|
||||||
|
#define _MB_M_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
PR_BEGIN_EXTERN_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! \defgroup modbus Modbus
|
||||||
|
* \code #include "mb_m.h" \endcode
|
||||||
|
*
|
||||||
|
* This module defines the interface for the application. It contains
|
||||||
|
* the basic functions and types required to use the Modbus Master protocol stack.
|
||||||
|
* A typical application will want to call eMBMasterInit() first. If the device
|
||||||
|
* is ready to answer network requests it must then call eMBEnable() to activate
|
||||||
|
* the protocol stack. In the main loop the function eMBMasterPoll() must be called
|
||||||
|
* periodically. The time interval between pooling depends on the configured
|
||||||
|
* Modbus timeout. If an RTOS is available a separate task should be created
|
||||||
|
* and the task should always call the function eMBMasterPoll().
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* // Initialize protocol stack in RTU mode for a Master
|
||||||
|
* eMBMasterInit( MB_RTU, 38400, MB_PAR_EVEN );
|
||||||
|
* // Enable the Modbus Protocol Stack.
|
||||||
|
* eMBMasterEnable( );
|
||||||
|
* for( ;; )
|
||||||
|
* {
|
||||||
|
* // Call the main polling loop of the Modbus Master protocol stack.
|
||||||
|
* eMBMasterPoll( );
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ----------------------- Defines ------------------------------------------*/
|
||||||
|
|
||||||
|
/*! \ingroup modbus
|
||||||
|
* \brief Use the default Modbus Master TCP port (502)
|
||||||
|
*/
|
||||||
|
#define MB_MASTER_TCP_PORT_USE_DEFAULT 0
|
||||||
|
|
||||||
|
/* ----------------------- Type definitions ---------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------- Function prototypes ------------------------------*/
|
||||||
|
/*! \ingroup modbus
|
||||||
|
* \brief Initialize the Modbus Master protocol stack.
|
||||||
|
*
|
||||||
|
* This functions initializes the ASCII or RTU module and calls the
|
||||||
|
* init functions of the porting layer to prepare the hardware. Please
|
||||||
|
* note that the receiver is still disabled and no Modbus frames are
|
||||||
|
* processed until eMBMasterEnable( ) has been called.
|
||||||
|
*
|
||||||
|
* \param eMode If ASCII or RTU mode should be used.
|
||||||
|
* \param ucPort The port to use. E.g. 1 for COM1 on windows. This value
|
||||||
|
* is platform dependent and some ports simply choose to ignore it.
|
||||||
|
* \param ulBaudRate The baudrate. E.g. 19200. Supported baudrates depend
|
||||||
|
* on the porting layer.
|
||||||
|
* \param eParity Parity used for serial transmission.
|
||||||
|
*
|
||||||
|
* \return If no error occurs the function returns eMBErrorCode::MB_ENOERR.
|
||||||
|
* The protocol is then in the disabled state and ready for activation
|
||||||
|
* by calling eMBMasterEnable( ). Otherwise one of the following error codes
|
||||||
|
* is returned:
|
||||||
|
* - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error.
|
||||||
|
*/
|
||||||
|
eMBErrorCode eMBMasterInit( eMBMode eMode, UCHAR ucPort,
|
||||||
|
ULONG ulBaudRate, eMBParity eParity );
|
||||||
|
|
||||||
|
/*! \ingroup modbus
|
||||||
|
* \brief Initialize the Modbus Master protocol stack for Modbus TCP.
|
||||||
|
*
|
||||||
|
* This function initializes the Modbus TCP Module. Please note that
|
||||||
|
* frame processing is still disabled until eMBEnable( ) is called.
|
||||||
|
*
|
||||||
|
* \param usTCPPort The TCP port to listen on.
|
||||||
|
* \return If the protocol stack has been initialized correctly the function
|
||||||
|
* returns eMBErrorCode::MB_ENOERR. Otherwise one of the following error
|
||||||
|
* codes is returned:
|
||||||
|
* - eMBErrorCode::MB_EINVAL If the slave address was not valid. Valid
|
||||||
|
* slave addresses are in the range 1 - 247.
|
||||||
|
* - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error.
|
||||||
|
*/
|
||||||
|
eMBErrorCode eMBMasterTCPInit( USHORT usTCPPort );
|
||||||
|
|
||||||
|
/*! \ingroup modbus
|
||||||
|
* \brief Release resources used by the protocol stack.
|
||||||
|
*
|
||||||
|
* This function disables the Modbus Master protocol stack and release all
|
||||||
|
* hardware resources. It must only be called when the protocol stack
|
||||||
|
* is disabled.
|
||||||
|
*
|
||||||
|
* \note Note all ports implement this function. A port which wants to
|
||||||
|
* get an callback must define the macro MB_PORT_HAS_CLOSE to 1.
|
||||||
|
*
|
||||||
|
* \return If the resources where released it return eMBErrorCode::MB_ENOERR.
|
||||||
|
* If the protocol stack is not in the disabled state it returns
|
||||||
|
* eMBErrorCode::MB_EILLSTATE.
|
||||||
|
*/
|
||||||
|
eMBErrorCode eMBMasterClose( void );
|
||||||
|
|
||||||
|
/*! \ingroup modbus
|
||||||
|
* \brief Enable the Modbus Master protocol stack.
|
||||||
|
*
|
||||||
|
* This function enables processing of Modbus Master frames. Enabling the protocol
|
||||||
|
* stack is only possible if it is in the disabled state.
|
||||||
|
*
|
||||||
|
* \return If the protocol stack is now in the state enabled it returns
|
||||||
|
* eMBErrorCode::MB_ENOERR. If it was not in the disabled state it
|
||||||
|
* return eMBErrorCode::MB_EILLSTATE.
|
||||||
|
*/
|
||||||
|
eMBErrorCode eMBMasterEnable( void );
|
||||||
|
|
||||||
|
/*! \ingroup modbus
|
||||||
|
* \brief Disable the Modbus Master protocol stack.
|
||||||
|
*
|
||||||
|
* This function disables processing of Modbus frames.
|
||||||
|
*
|
||||||
|
* \return If the protocol stack has been disabled it returns
|
||||||
|
* eMBErrorCode::MB_ENOERR. If it was not in the enabled state it returns
|
||||||
|
* eMBErrorCode::MB_EILLSTATE.
|
||||||
|
*/
|
||||||
|
eMBErrorCode eMBMasterDisable( void );
|
||||||
|
|
||||||
|
/*! \ingroup modbus
|
||||||
|
* \brief The main pooling loop of the Modbus Master protocol stack.
|
||||||
|
*
|
||||||
|
* This function must be called periodically. The timer interval required
|
||||||
|
* is given by the application dependent Modbus slave timeout. Internally the
|
||||||
|
* function calls xMBMasterPortEventGet() and waits for an event from the receiver or
|
||||||
|
* transmitter state machines.
|
||||||
|
*
|
||||||
|
* \return If the protocol stack is not in the enabled state the function
|
||||||
|
* returns eMBErrorCode::MB_EILLSTATE. Otherwise it returns
|
||||||
|
* eMBErrorCode::MB_ENOERR.
|
||||||
|
*/
|
||||||
|
eMBErrorCode eMBMasterPoll( void );
|
||||||
|
|
||||||
|
/* Get Modbus Master busy flag,It will return TRUE when Master is busy. */
|
||||||
|
BOOL xMBMasterGetIsBusy( void );
|
||||||
|
|
||||||
|
void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame );
|
||||||
|
UCHAR ucMBMasterGetDestAddress( void );
|
||||||
|
void vMBMasterSetDestAddress( UCHAR Address );
|
||||||
|
void vMBMasterSetIsBusy( BOOL IsBusy );
|
||||||
|
BOOL xMBMasterGetCBRunInMasterMode( void );
|
||||||
|
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode );
|
||||||
|
/* Get Modbus Master send PDU's buffer length.*/
|
||||||
|
UCHAR ucMBMasterGetPDUSndLength( void );
|
||||||
|
/* Set Modbus Master send PDU's buffer length.*/
|
||||||
|
void vMBMasterSetRTUSndSndLength( UCHAR SendPDULength );
|
||||||
|
|
||||||
|
/* ----------------------- Callback -----------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
PR_END_EXTERN_C
|
||||||
|
#endif
|
||||||
|
#endif
|
@ -25,7 +25,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* File: $Id: mbrtu_m.c,v 1.60 2013/08/20 11:18:10 Armink Add Master Functions , $
|
* File: $Id: mbrtu_m.c,v 1.60 2013/08/20 11:18:10 Armink Add Master Functions $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------- System includes ----------------------------------*/
|
/* ----------------------- System includes ----------------------------------*/
|
||||||
@ -38,6 +38,7 @@
|
|||||||
/* ----------------------- Modbus includes ----------------------------------*/
|
/* ----------------------- Modbus includes ----------------------------------*/
|
||||||
|
|
||||||
#include "mb.h"
|
#include "mb.h"
|
||||||
|
#include "mb_m.h"
|
||||||
#include "mbconfig.h"
|
#include "mbconfig.h"
|
||||||
#include "mbframe.h"
|
#include "mbframe.h"
|
||||||
#include "mbproto.h"
|
#include "mbproto.h"
|
||||||
@ -62,12 +63,9 @@
|
|||||||
|
|
||||||
/* ----------------------- Static variables ---------------------------------*/
|
/* ----------------------- Static variables ---------------------------------*/
|
||||||
|
|
||||||
volatile UCHAR ucMBMasterSndAddress;
|
static UCHAR ucMBMasterDestAddress;
|
||||||
volatile BOOL bMBRunInMasterMode = FALSE;
|
static BOOL xMBRunInMasterMode = FALSE;
|
||||||
UCHAR ucMasterRTUSndBuf[MB_PDU_SIZE_MAX];
|
static BOOL xMasterIsBusy = FALSE;
|
||||||
BOOL bMasterIsBusy = FALSE;
|
|
||||||
static UCHAR * pucMasterPUDSndBuf = ucMasterRTUSndBuf + 1;
|
|
||||||
static UCHAR ucMasterSendPDULength;
|
|
||||||
|
|
||||||
static enum
|
static enum
|
||||||
{
|
{
|
||||||
@ -280,7 +278,7 @@ eMBMasterPoll( void )
|
|||||||
case EV_MASTER_FRAME_RECEIVED:
|
case EV_MASTER_FRAME_RECEIVED:
|
||||||
eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength );
|
eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength );
|
||||||
/* Check if the frame is for us. If not ,send an error process event. */
|
/* Check if the frame is for us. If not ,send an error process event. */
|
||||||
if ( ( eStatus == MB_ENOERR ) && ( ucRcvAddress == ucMBMasterSndAddress ) )
|
if ( ( eStatus == MB_ENOERR ) && ( ucRcvAddress == ucMBMasterGetDestAddress() ) )
|
||||||
{
|
{
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_EXECUTE );
|
( void ) xMBMasterPortEventPost( EV_MASTER_EXECUTE );
|
||||||
}
|
}
|
||||||
@ -302,9 +300,9 @@ eMBMasterPoll( void )
|
|||||||
}
|
}
|
||||||
else if( xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode )
|
else if( xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode )
|
||||||
{
|
{
|
||||||
bMBRunInMasterMode = TRUE;
|
vMBMasterSetCBRunInMasterMode(TRUE);
|
||||||
eException = xMasterFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
|
eException = xMasterFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
|
||||||
bMBRunInMasterMode = FALSE;
|
vMBMasterSetCBRunInMasterMode(FALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -315,8 +313,9 @@ eMBMasterPoll( void )
|
|||||||
|
|
||||||
case EV_MASTER_FRAME_SENT:
|
case EV_MASTER_FRAME_SENT:
|
||||||
/* Master is busy now. */
|
/* Master is busy now. */
|
||||||
bMasterIsBusy = TRUE;
|
vMBMasterSetIsBusy( TRUE );
|
||||||
eStatus = peMBMasterFrameSendCur( ucMBMasterSndAddress, pucMasterPUDSndBuf, ucMasterSendPDULength );
|
vMBMasterGetPDUSndBuf( &ucMBFrame );
|
||||||
|
eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBFrame, ucMBMasterGetPDUSndLength() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_MASTER_ERROR_PROCESS:
|
case EV_MASTER_ERROR_PROCESS:
|
||||||
@ -326,21 +325,48 @@ eMBMasterPoll( void )
|
|||||||
return MB_ENOERR;
|
return MB_ENOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL bMBMasterGetIsBusy( void )
|
BOOL xMBMasterGetIsBusy( void )
|
||||||
{
|
{
|
||||||
return bMasterIsBusy;
|
return xMasterIsBusy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vMBMasterSetIsBusy( BOOL IsBusy )
|
||||||
|
{
|
||||||
|
xMasterIsBusy = IsBusy;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL xMBMasterGetCBRunInMasterMode( void )
|
||||||
|
{
|
||||||
|
return xMBRunInMasterMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
|
||||||
|
{
|
||||||
|
xMBRunInMasterMode = IsMasterMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
UCHAR ucMBMasterGetDestAddress( void )
|
||||||
|
{
|
||||||
|
return ucMBMasterDestAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vMBMasterSetDestAddress( UCHAR Address )
|
||||||
|
{
|
||||||
|
ucMBMasterDestAddress = Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Test Modbus Master
|
//Test Modbus Master
|
||||||
void vMBMasterWriteHoldReg(UCHAR ucSlaveAddress, USHORT usRegAddress, USHORT ucRegValue)
|
void vMBMasterWriteHoldReg(UCHAR ucSlaveAddress, USHORT usRegAddress, USHORT ucRegValue)
|
||||||
{
|
{
|
||||||
ucMBMasterSndAddress = ucSlaveAddress;
|
static UCHAR *ucMBFrame;
|
||||||
pucMasterPUDSndBuf[MB_PDU_FUNC_OFF] = MB_FUNC_WRITE_REGISTER;
|
vMBMasterGetPDUSndBuf( &ucMBFrame );
|
||||||
pucMasterPUDSndBuf[MB_PDU_DATA_OFF + 0] = usRegAddress >> 8;
|
vMBMasterSetDestAddress(ucSlaveAddress);
|
||||||
pucMasterPUDSndBuf[MB_PDU_DATA_OFF + 1] = usRegAddress;
|
ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_WRITE_REGISTER;
|
||||||
pucMasterPUDSndBuf[MB_PDU_DATA_OFF + 2] = ucRegValue >> 8;
|
ucMBFrame[MB_PDU_DATA_OFF + 0] = usRegAddress >> 8;
|
||||||
pucMasterPUDSndBuf[MB_PDU_DATA_OFF + 3] = ucRegValue ;
|
ucMBFrame[MB_PDU_DATA_OFF + 1] = usRegAddress;
|
||||||
ucMasterSendPDULength = 5;
|
ucMBFrame[MB_PDU_DATA_OFF + 2] = ucRegValue >> 8;
|
||||||
|
ucMBFrame[MB_PDU_DATA_OFF + 3] = ucRegValue ;
|
||||||
|
vMBMasterSetRTUSndSndLength(5);
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* File: $Id: mbrtu_m.c,v 1.60 2013/08/17 11:42:56 Armink Add Master Functions , $
|
* File: $Id: mbrtu_m.c,v 1.60 2013/08/17 11:42:56 Armink Add Master Functions $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------- System includes ----------------------------------*/
|
/* ----------------------- System includes ----------------------------------*/
|
||||||
@ -71,15 +71,15 @@ typedef enum
|
|||||||
static volatile eMBMasterSndState eSndState;
|
static volatile eMBMasterSndState eSndState;
|
||||||
static volatile eMBMasterRcvState eRcvState;
|
static volatile eMBMasterRcvState eRcvState;
|
||||||
|
|
||||||
extern BOOL bMasterIsBusy;
|
static volatile UCHAR ucMasterRTUSndBuf[MB_PDU_SIZE_MAX];
|
||||||
extern UCHAR ucMasterRTUSndBuf[MB_PDU_SIZE_MAX];
|
static volatile UCHAR ucMasterRTURcvBuf[MB_SER_PDU_SIZE_MAX];
|
||||||
volatile UCHAR ucMasterRTURcvBuf[MB_SER_PDU_SIZE_MAX];
|
static volatile UCHAR ucMasterSendPDULength;
|
||||||
|
|
||||||
static volatile UCHAR *pucMasterSndBufferCur;
|
static volatile UCHAR *pucMasterSndBufferCur;
|
||||||
static volatile USHORT usMasterSndBufferCount;
|
static volatile USHORT usMasterSndBufferCount;
|
||||||
|
|
||||||
static volatile USHORT usMasterRcvBufferPos;
|
static volatile USHORT usMasterRcvBufferPos;
|
||||||
static volatile BOOL bFrameIsBroadcast = FALSE;
|
static volatile BOOL xFrameIsBroadcast = FALSE;
|
||||||
/* ----------------------- Start implementation -----------------------------*/
|
/* ----------------------- Start implementation -----------------------------*/
|
||||||
eMBErrorCode
|
eMBErrorCode
|
||||||
eMBMasterRTUInit(UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
|
eMBMasterRTUInit(UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
|
||||||
@ -318,14 +318,14 @@ xMBMasterRTUTransmitFSM( void )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bFrameIsBroadcast = ( ucMasterRTUSndBuf[MB_SER_PDU_ADDR_OFF] == MB_ADDRESS_BROADCAST ) ? TRUE : FALSE;
|
xFrameIsBroadcast = ( ucMasterRTUSndBuf[MB_SER_PDU_ADDR_OFF] == MB_ADDRESS_BROADCAST ) ? TRUE : FALSE;
|
||||||
/* Disable transmitter. This prevents another transmit buffer
|
/* Disable transmitter. This prevents another transmit buffer
|
||||||
* empty interrupt. */
|
* empty interrupt. */
|
||||||
vMBMasterPortSerialEnable( TRUE, FALSE );
|
vMBMasterPortSerialEnable( TRUE, FALSE );
|
||||||
eSndState = STATE_M_TX_XFWR;
|
eSndState = STATE_M_TX_XFWR;
|
||||||
/* If the frame is broadcast ,master will enable timer of convert delay,
|
/* If the frame is broadcast ,master will enable timer of convert delay,
|
||||||
* else master will enable timer of respond timeout. */
|
* else master will enable timer of respond timeout. */
|
||||||
if ( bFrameIsBroadcast == TRUE ) vMBMasterPortTimersConvertDelayEnable( );
|
if ( xFrameIsBroadcast == TRUE ) vMBMasterPortTimersConvertDelayEnable( );
|
||||||
else vMBMasterPortTimersRespondTimeoutEnable( );
|
else vMBMasterPortTimersRespondTimeoutEnable( );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -370,7 +370,7 @@ xMBMasterRTUTimerExpired(void)
|
|||||||
* If the frame is broadcast,The master will idle,and if the frame is not
|
* If the frame is broadcast,The master will idle,and if the frame is not
|
||||||
* broadcast.Notify the listener process error.*/
|
* broadcast.Notify the listener process error.*/
|
||||||
case STATE_M_TX_XFWR:
|
case STATE_M_TX_XFWR:
|
||||||
if ( bFrameIsBroadcast == FALSE ) xNeedPoll = xMBMasterPortEventPost(EV_MASTER_ERROR_PROCESS);
|
if ( xFrameIsBroadcast == FALSE ) xNeedPoll = xMBMasterPortEventPost(EV_MASTER_ERROR_PROCESS);
|
||||||
break;
|
break;
|
||||||
/* Function called in an illegal state. */
|
/* Function called in an illegal state. */
|
||||||
default:
|
default:
|
||||||
@ -381,9 +381,33 @@ xMBMasterRTUTimerExpired(void)
|
|||||||
|
|
||||||
vMBMasterPortTimersDisable();
|
vMBMasterPortTimersDisable();
|
||||||
/* Master is idel now. */
|
/* Master is idel now. */
|
||||||
bMasterIsBusy = FALSE;
|
vMBMasterSetIsBusy(FALSE);
|
||||||
|
|
||||||
return xNeedPoll;
|
return xNeedPoll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get Modbus Master send RTU's buffer address pointer.*/
|
||||||
|
void vMBMasterGetRTUSndBuf( UCHAR ** pucFrame )
|
||||||
|
{
|
||||||
|
*pucFrame = ( UCHAR * ) ucMasterRTUSndBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Modbus Master send PDU's buffer address pointer.*/
|
||||||
|
void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame )
|
||||||
|
{
|
||||||
|
*pucFrame = ( UCHAR * ) ucMasterRTUSndBuf[MB_SER_PDU_PDU_OFF];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Modbus Master send PDU's buffer length.*/
|
||||||
|
void vMBMasterSetRTUSndSndLength( UCHAR SendPDULength )
|
||||||
|
{
|
||||||
|
ucMasterSendPDULength = SendPDULength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Modbus Master send PDU's buffer length.*/
|
||||||
|
UCHAR ucMBMasterGetPDUSndLength( void )
|
||||||
|
{
|
||||||
|
return ucMasterSendPDULength;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*
|
*
|
||||||
* File: $Id: portevent_m.c v 1.60 2013/08/13 15:07:05 Armink add Master Functions, $
|
* File: $Id: portevent_m.c v 1.60 2013/08/13 15:07:05 Armink add Master Functions$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------- Modbus includes ----------------------------------*/
|
/* ----------------------- Modbus includes ----------------------------------*/
|
||||||
|
@ -20,8 +20,6 @@ USHORT usMRegInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_INPUT_NREGS];
|
|||||||
USHORT usMRegHoldStart = M_REG_HOLDING_START;
|
USHORT usMRegHoldStart = M_REG_HOLDING_START;
|
||||||
USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
|
USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
|
||||||
|
|
||||||
extern volatile UCHAR ucMBMasterSndAddress;
|
|
||||||
extern volatile BOOL bMBRunInMasterMode;
|
|
||||||
#endif
|
#endif
|
||||||
//******************************<2A><><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>**********************************
|
//******************************<2A><><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>**********************************
|
||||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
|
||||||
@ -43,9 +41,9 @@ eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
|
|||||||
UCHAR usRegInStart;
|
UCHAR usRegInStart;
|
||||||
|
|
||||||
//Determine the master or slave
|
//Determine the master or slave
|
||||||
if (bMBRunInMasterMode)
|
if (xMBMasterGetCBRunInMasterMode())
|
||||||
{
|
{
|
||||||
pusRegInputBuf = usMRegInBuf[ucMBMasterSndAddress];
|
pusRegInputBuf = usMRegInBuf[ucMBMasterGetDestAddress()];
|
||||||
REG_INPUT_START = M_REG_INPUT_START;
|
REG_INPUT_START = M_REG_INPUT_START;
|
||||||
REG_INPUT_NREGS = M_REG_INPUT_NREGS;
|
REG_INPUT_NREGS = M_REG_INPUT_NREGS;
|
||||||
usRegInStart = usMRegInStart;
|
usRegInStart = usMRegInStart;
|
||||||
@ -65,7 +63,7 @@ eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
|
|||||||
while( usNRegs > 0 )
|
while( usNRegs > 0 )
|
||||||
{
|
{
|
||||||
//Determine the master or slave
|
//Determine the master or slave
|
||||||
if (bMBRunInMasterMode)
|
if (xMBMasterGetCBRunInMasterMode())
|
||||||
{
|
{
|
||||||
pusRegInputBuf[iRegIndex] = *pucRegBuffer++ << 8;
|
pusRegInputBuf[iRegIndex] = *pucRegBuffer++ << 8;
|
||||||
pusRegInputBuf[iRegIndex] |= *pucRegBuffer++;
|
pusRegInputBuf[iRegIndex] |= *pucRegBuffer++;
|
||||||
@ -109,9 +107,9 @@ eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegi
|
|||||||
UCHAR usRegHoldStart;
|
UCHAR usRegHoldStart;
|
||||||
|
|
||||||
//Determine the master or slave
|
//Determine the master or slave
|
||||||
if (bMBRunInMasterMode)
|
if (xMBMasterGetCBRunInMasterMode())
|
||||||
{
|
{
|
||||||
pusRegHoldingBuf = usMRegHoldBuf[ucMBMasterSndAddress];
|
pusRegHoldingBuf = usMRegHoldBuf[ucMBMasterGetDestAddress()];
|
||||||
REG_HOLDING_START = M_REG_HOLDING_START;
|
REG_HOLDING_START = M_REG_HOLDING_START;
|
||||||
REG_HOLDING_NREGS = M_REG_HOLDING_NREGS;
|
REG_HOLDING_NREGS = M_REG_HOLDING_NREGS;
|
||||||
usRegHoldStart = usMRegHoldStart;
|
usRegHoldStart = usMRegHoldStart;
|
||||||
@ -123,7 +121,7 @@ eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegi
|
|||||||
pusRegHoldingBuf = usSRegHoldBuf;
|
pusRegHoldingBuf = usSRegHoldBuf;
|
||||||
REG_HOLDING_START = S_REG_INPUT_START;
|
REG_HOLDING_START = S_REG_INPUT_START;
|
||||||
REG_HOLDING_NREGS = S_REG_INPUT_NREGS;
|
REG_HOLDING_NREGS = S_REG_INPUT_NREGS;
|
||||||
usRegHoldStart = usSRegInStart;
|
usRegHoldStart = usSRegHoldStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( usAddress >= REG_HOLDING_START ) &&
|
if( ( usAddress >= REG_HOLDING_START ) &&
|
||||||
@ -187,9 +185,9 @@ eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegis
|
|||||||
|
|
||||||
|
|
||||||
//Determine the master or slave
|
//Determine the master or slave
|
||||||
if (bMBRunInMasterMode)
|
if (xMBMasterGetCBRunInMasterMode())
|
||||||
{
|
{
|
||||||
pucCoilBuf = ucMCoilBuf[ucMBMasterSndAddress];
|
pucCoilBuf = ucMCoilBuf[ucMBMasterGetDestAddress()];
|
||||||
COIL_START = M_COIL_START;
|
COIL_START = M_COIL_START;
|
||||||
COIL_NCOILS = M_COIL_NCOILS;
|
COIL_NCOILS = M_COIL_NCOILS;
|
||||||
usCoilStart = usMCoilStart;
|
usCoilStart = usMCoilStart;
|
||||||
@ -265,9 +263,9 @@ eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
|
|||||||
iNReg = usNDiscrete / 8 + 1; //ռ<>üĴ<C3BC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
iNReg = usNDiscrete / 8 + 1; //ռ<>üĴ<C3BC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
//Determine the master or slave
|
//Determine the master or slave
|
||||||
if (bMBRunInMasterMode)
|
if (xMBMasterGetCBRunInMasterMode())
|
||||||
{
|
{
|
||||||
pucDiscreteInputBuf = ucMDiscInBuf[ucMBMasterSndAddress];
|
pucDiscreteInputBuf = ucMDiscInBuf[ucMBMasterGetDestAddress()];
|
||||||
DISCRETE_INPUT_START = M_DISCRETE_INPUT_START;
|
DISCRETE_INPUT_START = M_DISCRETE_INPUT_START;
|
||||||
DISCRETE_INPUT_NDISCRETES = M_DISCRETE_INPUT_NDISCRETES;
|
DISCRETE_INPUT_NDISCRETES = M_DISCRETE_INPUT_NDISCRETES;
|
||||||
usDiscreteInputStart = usMDiscInStart;
|
usDiscreteInputStart = usMDiscInStart;
|
||||||
@ -287,7 +285,7 @@ eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
|
|||||||
iRegBitIndex = ( int )( usAddress - usDiscreteInputStart ) % 8 ; //<2F><><EFBFBD><EFBFBD><EFBFBD>ڼĴ<DABC><C4B4><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>λ<EFBFBD><CEBB>ַ
|
iRegBitIndex = ( int )( usAddress - usDiscreteInputStart ) % 8 ; //<2F><><EFBFBD><EFBFBD><EFBFBD>ڼĴ<DABC><C4B4><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>λ<EFBFBD><CEBB>ַ
|
||||||
|
|
||||||
//Determine the master or slave
|
//Determine the master or slave
|
||||||
if (bMBRunInMasterMode)
|
if (xMBMasterGetCBRunInMasterMode())
|
||||||
{
|
{
|
||||||
/* Update current coil values with new values from the
|
/* Update current coil values with new values from the
|
||||||
* protocol stack. */
|
* protocol stack. */
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
#define USER_APP
|
#define USER_APP
|
||||||
/* ----------------------- Modbus includes ----------------------------------*/
|
/* ----------------------- Modbus includes ----------------------------------*/
|
||||||
#include "mb.h"
|
#include "mb.h"
|
||||||
#include "mbport.h"
|
#include "mb_m.h"
|
||||||
#include "mbconfig.h"
|
#include "mbconfig.h"
|
||||||
|
#include "mbframe.h"
|
||||||
|
#include "mbutils.h"
|
||||||
|
|
||||||
/* -----------------------Slave Defines -------------------------------------*/
|
/* -----------------------Slave Defines -------------------------------------*/
|
||||||
#define S_DISCRETE_INPUT_START 1
|
#define S_DISCRETE_INPUT_START 1
|
||||||
@ -49,10 +51,4 @@
|
|||||||
//<2F><><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɢ<EFBFBD><C9A2><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>Ӧ<EFBFBD>Ĺ<EFBFBD><C4B9>ܶ<EFBFBD><DCB6><EFBFBD>
|
//<2F><><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɢ<EFBFBD><C9A2><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>Ӧ<EFBFBD>Ĺ<EFBFBD><C4B9>ܶ<EFBFBD><DCB6><EFBFBD>
|
||||||
#define M_DI_RESERVE 1 //<2F><><EFBFBD><EFBFBD>
|
#define M_DI_RESERVE 1 //<2F><><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------Extern Functions------------------------------------*/
|
|
||||||
extern UCHAR xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits );
|
|
||||||
extern void xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits,UCHAR ucValue );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user