From 478d15dc942f08c0733460209c92f8c1f57ce33a Mon Sep 17 00:00:00 2001 From: armink Date: Sat, 12 Oct 2013 15:05:42 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E3=80=90=E5=A2=9E=E5=8A=A0=E3=80=91F?= =?UTF-8?q?reeModbus=E4=B8=BB=E6=9C=BA=E8=AF=BB=E8=BE=93=E5=85=A5=E5=AF=84?= =?UTF-8?q?=E5=AD=98=E5=99=A8=E5=8A=9F=E8=83=BD=E7=9A=84=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=8F=8A=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: armink --- APP/src/app_task.c | 3 +- FreeModbus/modbus/functions/mbfuncinput_m.c | 130 ++++++++++++++++++++ FreeModbus/modbus/include/mb_m.h | 2 + FreeModbus/modbus/mb_m.c | 3 +- 4 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 FreeModbus/modbus/functions/mbfuncinput_m.c diff --git a/APP/src/app_task.c b/APP/src/app_task.c index 3c8fee7..2e9ea0f 100644 --- a/APP/src/app_task.c +++ b/APP/src/app_task.c @@ -48,7 +48,8 @@ void thread_entry_SysMonitor(void* parameter) //Test Modbus Master usModbusUserData[0] = (USHORT)(rt_tick_get()/10); usModbusUserData[1] = (USHORT)(rt_tick_get()%10); - eMBMasterReqWriteHoldingRegister(1,usModbusUserData,3); + eMBMasterReqReadInputRegister(1,3,2); +// eMBMasterReqWriteHoldingRegister(1,usModbusUserData,3); // eMBMasterReqWriteMultipleHoldingRegister(1,usModbusUserData,3,2); // eMBMasterReqReadHoldingRegister(1,3,2); // eMBMasterReqReadWriteMultipleHoldingRegister(1,usModbusUserData,3,2,5,2); diff --git a/FreeModbus/modbus/functions/mbfuncinput_m.c b/FreeModbus/modbus/functions/mbfuncinput_m.c new file mode 100644 index 0000000..0d89b5f --- /dev/null +++ b/FreeModbus/modbus/functions/mbfuncinput_m.c @@ -0,0 +1,130 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (C) 2013 Armink + * 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: mbfuncinput_m.c,v 1.60 2013/10/12 14:23: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_REQ_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0 ) +#define MB_PDU_REQ_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 ) +#define MB_PDU_REQ_READ_SIZE ( 4 ) +#define MB_PDU_FUNC_READ_BYTECNT_OFF ( MB_PDU_DATA_OFF + 0 ) +#define MB_PDU_FUNC_READ_VALUES_OFF ( MB_PDU_DATA_OFF + 1 ) +#define MB_PDU_FUNC_READ_SIZE_MIN ( 1 ) + +#define MB_PDU_FUNC_READ_RSP_BYTECNT_OFF ( MB_PDU_DATA_OFF ) + +/* ----------------------- Static functions ---------------------------------*/ +eMBException prveMBError2Exception( eMBErrorCode eErrorCode ); + +/* ----------------------- Start implementation -----------------------------*/ +#if MB_FUNC_READ_INPUT_ENABLED > 0 + +eMBMasterReqErrCode +eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs ) +{ + UCHAR *ucMBFrame; + eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR; + + if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY; + else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG; + else + { + vMBMasterGetPDUSndBuf(&ucMBFrame); + vMBMasterSetDestAddress(ucSndAddr); + ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_READ_INPUT_REGISTER; + ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] = usRegAddr >> 8; + ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] = usRegAddr; + ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] = usNRegs >> 8; + ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs; + vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE ); + ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT ); + } + return eErrStatus; +} + +eMBException +eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen ) +{ + UCHAR *ucMBFrame; + USHORT usRegAddress; + USHORT usRegCount; + + eMBException eStatus = MB_EX_NONE; + eMBErrorCode eRegStatus; + + if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN) + { + vMBMasterGetPDUSndBuf(&ucMBFrame); + usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 ); + usRegAddress |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] ); + usRegAddress++; + + usRegCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] << 8 ); + usRegCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_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 ) && ( 2 * usRegCount == pucFrame[MB_PDU_FUNC_READ_BYTECNT_OFF] ) ) + { + /* Make callback to fill the buffer. */ + eRegStatus = eMBRegInputCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usRegCount ); + /* If an error occured convert it into a Modbus exception. */ + if( eRegStatus != MB_ENOERR ) + { + eStatus = prveMBError2Exception( eRegStatus ); + } + } + 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 diff --git a/FreeModbus/modbus/include/mb_m.h b/FreeModbus/modbus/include/mb_m.h index 3db04e2..70115c2 100644 --- a/FreeModbus/modbus/include/mb_m.h +++ b/FreeModbus/modbus/include/mb_m.h @@ -194,6 +194,8 @@ eMBErrorCode eMBMasterPoll( void ); *\brief These Modbus functions are called for user when Modbus run in Master Mode. */ eMBMasterReqErrCode +eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs ); +eMBMasterReqErrCode eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT * pusDataBuffer, USHORT usRegAddr ); eMBMasterReqErrCode eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,USHORT * pusDataBuffer, USHORT usRegAddr, USHORT usNRegs ); diff --git a/FreeModbus/modbus/mb_m.c b/FreeModbus/modbus/mb_m.c index ee4cd38..d9e72a9 100644 --- a/FreeModbus/modbus/mb_m.c +++ b/FreeModbus/modbus/mb_m.c @@ -105,8 +105,7 @@ static xMBFunctionHandler xMasterFuncHandlers[MB_FUNC_HANDLERS_MAX] = { {MB_FUNC_OTHER_REPORT_SLAVEID, eMBFuncReportSlaveID}, #endif #if MB_FUNC_READ_INPUT_ENABLED > 0 - //TODO Add Master function define - {MB_FUNC_READ_INPUT_REGISTER, eMBFuncReadInputRegister}, + {MB_FUNC_READ_INPUT_REGISTER, eMBMasterFuncReadInputRegister}, #endif #if MB_FUNC_READ_HOLDING_ENABLED > 0 {MB_FUNC_READ_HOLDING_REGISTER, eMBMasterFuncReadHoldingRegister},