
from Cam Marshall original modbus
Fork of Modbus by
Revision 8:924d128c1722, committed 2017-03-31
- Comitter:
- stanley1228
- Date:
- Fri Mar 31 01:35:28 2017 +0000
- Parent:
- 7:44579368875a
- Child:
- 9:0fb2f20a1451
- Commit message:
- 1.change Modbus folder into function,rtu,port,include
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/functions/mbfunccoils.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,270 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbfunccoils.c,v 1.8 2007/02/18 23:47:16 wolti Exp $ + */ + +/* ----------------------- System includes ----------------------------------*/ +#include "stdlib.h" +#include "string.h" + +/* ----------------------- Platform includes --------------------------------*/ +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbframe.h" +#include "mbproto.h" +#include "mbconfig.h" + +/* ----------------------- Defines ------------------------------------------*/ +#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF ) +#define MB_PDU_FUNC_READ_COILCNT_OFF ( MB_PDU_DATA_OFF + 2 ) +#define MB_PDU_FUNC_READ_SIZE ( 4 ) +#define MB_PDU_FUNC_READ_COILCNT_MAX ( 0x07D0 ) + +#define MB_PDU_FUNC_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF ) +#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 ) +#define MB_PDU_FUNC_WRITE_MUL_COILCNT_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_COILCNT_MAX ( 0x07B0 ) + +/* ----------------------- Static functions ---------------------------------*/ +eMBException prveMBError2Exception( eMBErrorCode eErrorCode ); + +/* ----------------------- Start implementation -----------------------------*/ + +#if MB_FUNC_READ_COILS_ENABLED > 0 + +eMBException +eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen ) +{ + USHORT usRegAddress; + USHORT usCoilCount; + UCHAR ucNBytes; + 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++; + + usCoilCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] << 8 ); + usCoilCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF + 1] ); + + /* Check if the number of registers to read is valid. If not + * return Modbus illegal data value exception. + */ + if( ( usCoilCount >= 1 ) && + ( usCoilCount < MB_PDU_FUNC_READ_COILCNT_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_COILS; + *usLen += 1; + + /* Test if the quantity of coils is a multiple of 8. If not last + * byte is only partially field with unused coils set to zero. */ + if( ( usCoilCount & 0x0007 ) != 0 ) + { + ucNBytes = ( UCHAR )( usCoilCount / 8 + 1 ); + } + else + { + ucNBytes = ( UCHAR )( usCoilCount / 8 ); + } + *pucFrameCur++ = ucNBytes; + *usLen += 1; + + eRegStatus = + eMBRegCoilsCB( pucFrameCur, usRegAddress, usCoilCount, + MB_REG_READ ); + + /* 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 += ucNBytes;; + } + } + else + { + eStatus = MB_EX_ILLEGAL_DATA_VALUE; + } + } + else + { + /* Can't be a valid read coil register request because the length + * is incorrect. */ + eStatus = MB_EX_ILLEGAL_DATA_VALUE; + } + return eStatus; +} + +#if MB_FUNC_WRITE_COIL_ENABLED > 0 +eMBException +eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen ) +{ + USHORT usRegAddress; + UCHAR ucBuf[2]; + + 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_ADDR_OFF] << 8 ); + usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] ); + usRegAddress++; + + if( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF + 1] == 0x00 ) && + ( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF ) || + ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0x00 ) ) ) + { + ucBuf[1] = 0; + if( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF ) + { + ucBuf[0] = 1; + } + else + { + ucBuf[0] = 0; + } + eRegStatus = + eMBRegCoilsCB( &ucBuf[0], usRegAddress, 1, MB_REG_WRITE ); + + /* 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 write coil register request because the length + * is incorrect. */ + eStatus = MB_EX_ILLEGAL_DATA_VALUE; + } + return eStatus; +} + +#endif + +#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0 +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; +} + +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/functions/mbfuncdiag.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,29 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbfuncdiag.c,v 1.3 2006/12/07 22:10:34 wolti Exp $ + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/functions/mbfuncdisc.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,125 @@ + /* + * FreeRTOS Modbus Libary: A Modbus serial implementation for FreeRTOS + * Copyright (C) 2006 Christian Walter <wolti@sil.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +/* ----------------------- System includes ----------------------------------*/ +#include "stdlib.h" +#include "string.h" + +/* ----------------------- Platform includes --------------------------------*/ +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbframe.h" +#include "mbproto.h" +#include "mbconfig.h" + +/* ----------------------- Defines ------------------------------------------*/ +#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF ) +#define MB_PDU_FUNC_READ_DISCCNT_OFF ( MB_PDU_DATA_OFF + 2 ) +#define MB_PDU_FUNC_READ_SIZE ( 4 ) +#define MB_PDU_FUNC_READ_DISCCNT_MAX ( 0x07D0 ) + +/* ----------------------- Static functions ---------------------------------*/ +eMBException prveMBError2Exception( eMBErrorCode eErrorCode ); + +/* ----------------------- Start implementation -----------------------------*/ + +#if MB_FUNC_READ_COILS_ENABLED > 0 + +eMBException +eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen ) +{ + USHORT usRegAddress; + USHORT usDiscreteCnt; + UCHAR ucNBytes; + 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++; + + usDiscreteCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF] << 8 ); + usDiscreteCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF + 1] ); + + /* Check if the number of registers to read is valid. If not + * return Modbus illegal data value exception. + */ + if( ( usDiscreteCnt >= 1 ) && + ( usDiscreteCnt < MB_PDU_FUNC_READ_DISCCNT_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_DISCRETE_INPUTS; + *usLen += 1; + + /* Test if the quantity of coils is a multiple of 8. If not last + * byte is only partially field with unused coils set to zero. */ + if( ( usDiscreteCnt & 0x0007 ) != 0 ) + { + ucNBytes = ( UCHAR ) ( usDiscreteCnt / 8 + 1 ); + } + else + { + ucNBytes = ( UCHAR ) ( usDiscreteCnt / 8 ); + } + *pucFrameCur++ = ucNBytes; + *usLen += 1; + + eRegStatus = + eMBRegDiscreteCB( pucFrameCur, usRegAddress, usDiscreteCnt ); + + /* 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 += ucNBytes;; + } + } + else + { + eStatus = MB_EX_ILLEGAL_DATA_VALUE; + } + } + else + { + /* Can't be a valid read coil register request because the length + * is incorrect. */ + eStatus = MB_EX_ILLEGAL_DATA_VALUE; + } + return eStatus; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/functions/mbfuncholding.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,308 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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.c,v 1.12 2007/02/18 23:48:22 wolti Exp $ + */ + +/* ----------------------- System includes ----------------------------------*/ +#include "stdlib.h" +#include "string.h" + +/* ----------------------- Platform includes --------------------------------*/ +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.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_FUNC_WRITE_HOLDING_ENABLED > 0 + +eMBException +eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen ) +{ + USHORT usRegAddress; + 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_ADDR_OFF] << 8 ); + usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] ); + usRegAddress++; + + /* Make callback to update the value. */ + eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF], + usRegAddress, 1, MB_REG_WRITE ); + + /* If an error occured convert it into a Modbus exception. */ + if( eRegStatus != MB_ENOERR ) + { + eStatus = prveMBError2Exception( eRegStatus ); + } + } + else + { + /* Can't be a valid request because the length is incorrect. */ + eStatus = MB_EX_ILLEGAL_DATA_VALUE; + } + return eStatus; +} +#endif + +#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0 +eMBException +eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen ) +{ + USHORT usRegAddress; + USHORT usRegCount; + UCHAR ucRegByteCount; + + eMBException eStatus = MB_EX_NONE; + eMBErrorCode eRegStatus; + + if( *usLen >= ( MB_PDU_FUNC_WRITE_MUL_SIZE_MIN + 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++; + + usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF] << 8 ); + usRegCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF + 1] ); + + ucRegByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF]; + + if( ( usRegCount >= 1 ) && + ( usRegCount <= MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX ) && + ( ucRegByteCount == ( UCHAR ) ( 2 * usRegCount ) ) ) + { + /* Make callback to update the register values. */ + eRegStatus = + eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF], + usRegAddress, usRegCount, 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 request because the length is incorrect. */ + eStatus = MB_EX_ILLEGAL_DATA_VALUE; + } + return eStatus; +} +#endif + +#if MB_FUNC_READ_HOLDING_ENABLED > 0 + +eMBException +eMBFuncReadHoldingRegister( 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 +eMBFuncReadWriteMultipleHoldingRegister( 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/functions/mbfuncinput.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,121 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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.c,v 1.10 2007/09/12 10:15:56 wolti Exp $ + */ + +/* ----------------------- System includes ----------------------------------*/ +#include "stdlib.h" +#include "string.h" + +/* ----------------------- Platform includes --------------------------------*/ +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbframe.h" +#include "mbproto.h" +#include "mbconfig.h" + +/* ----------------------- Defines ------------------------------------------*/ +#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF ) +#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_READ_RSP_BYTECNT_OFF ( MB_PDU_DATA_OFF ) + +/* ----------------------- Static functions ---------------------------------*/ +eMBException prveMBError2Exception( eMBErrorCode eErrorCode ); + +/* ----------------------- Start implementation -----------------------------*/ +#if MB_FUNC_READ_INPUT_ENABLED > 0 + +eMBException +eMBFuncReadInputRegister( 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_INPUT_REGISTER; + *usLen += 1; + + /* Second byte in the response contain the number of bytes. */ + *pucFrameCur++ = ( UCHAR )( usRegCount * 2 ); + *usLen += 1; + + eRegStatus = eMBRegInputCB( pucFrameCur, usRegAddress, usRegCount ); + + /* 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 read input register request because the length + * is incorrect. */ + eStatus = MB_EX_ILLEGAL_DATA_VALUE; + } + return eStatus; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/functions/mbfuncother.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,88 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbfuncother.c,v 1.8 2006/12/07 22:10:34 wolti Exp $ + */ + +/* ----------------------- System includes ----------------------------------*/ +#include "stdlib.h" +#include "string.h" + +/* ----------------------- Platform includes --------------------------------*/ +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbframe.h" +#include "mbproto.h" +#include "mbconfig.h" + +#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0 + +/* ----------------------- Static variables ---------------------------------*/ +static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF]; +static USHORT usMBSlaveIDLen; + +/* ----------------------- Start implementation -----------------------------*/ + +eMBErrorCode +eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning, + UCHAR const *pucAdditional, USHORT usAdditionalLen ) +{ + eMBErrorCode eStatus = MB_ENOERR; + + /* the first byte and second byte in the buffer is reserved for + * the parameter ucSlaveID and the running flag. The rest of + * the buffer is available for additional data. */ + if( usAdditionalLen + 2 < MB_FUNC_OTHER_REP_SLAVEID_BUF ) + { + usMBSlaveIDLen = 0; + ucMBSlaveID[usMBSlaveIDLen++] = ucSlaveID; + ucMBSlaveID[usMBSlaveIDLen++] = ( UCHAR )( xIsRunning ? 0xFF : 0x00 ); + if( usAdditionalLen > 0 ) + { + memcpy( &ucMBSlaveID[usMBSlaveIDLen], pucAdditional, + ( size_t )usAdditionalLen ); + usMBSlaveIDLen += usAdditionalLen; + } + } + else + { + eStatus = MB_ENORES; + } + return eStatus; +} + +eMBException +eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen ) +{ + memcpy( &pucFrame[MB_PDU_DATA_OFF], &ucMBSlaveID[0], ( size_t )usMBSlaveIDLen ); + *usLen = ( USHORT )( MB_PDU_DATA_OFF + usMBSlaveIDLen ); + return MB_EX_NONE; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/functions/mbutils.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,141 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbutils.c,v 1.6 2007/02/18 23:49:07 wolti Exp $ + */ + +/* ----------------------- System includes ----------------------------------*/ +#include "stdlib.h" +#include "string.h" + +/* ----------------------- Platform includes --------------------------------*/ +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbproto.h" + +/* ----------------------- Defines ------------------------------------------*/ +#define BITS_UCHAR 8U + +/* ----------------------- Start implementation -----------------------------*/ +void +xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits, + UCHAR ucValue ) +{ + USHORT usWordBuf; + USHORT usMask; + USHORT usByteOffset; + USHORT usNPreBits; + USHORT usValue = ucValue; + + assert( ucNBits <= 8 ); + assert( ( size_t )BITS_UCHAR == sizeof( UCHAR ) * 8 ); + + /* Calculate byte offset for first byte containing the bit values starting + * at usBitOffset. */ + usByteOffset = ( USHORT )( ( usBitOffset ) / BITS_UCHAR ); + + /* How many bits precede our bits to set. */ + usNPreBits = ( USHORT )( usBitOffset - usByteOffset * BITS_UCHAR ); + + /* Move bit field into position over bits to set */ + usValue <<= usNPreBits; + + /* Prepare a mask for setting the new bits. */ + usMask = ( USHORT )( ( 1 << ( USHORT ) ucNBits ) - 1 ); + usMask <<= usBitOffset - usByteOffset * BITS_UCHAR; + + /* copy bits into temporary storage. */ + usWordBuf = ucByteBuf[usByteOffset]; + usWordBuf |= ucByteBuf[usByteOffset + 1] << BITS_UCHAR; + + /* Zero out bit field bits and then or value bits into them. */ + usWordBuf = ( USHORT )( ( usWordBuf & ( ~usMask ) ) | usValue ); + + /* move bits back into storage */ + ucByteBuf[usByteOffset] = ( UCHAR )( usWordBuf & 0xFF ); + ucByteBuf[usByteOffset + 1] = ( UCHAR )( usWordBuf >> BITS_UCHAR ); +} + +UCHAR +xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits ) +{ + USHORT usWordBuf; + USHORT usMask; + USHORT usByteOffset; + USHORT usNPreBits; + + /* Calculate byte offset for first byte containing the bit values starting + * at usBitOffset. */ + usByteOffset = ( USHORT )( ( usBitOffset ) / BITS_UCHAR ); + + /* How many bits precede our bits to set. */ + usNPreBits = ( USHORT )( usBitOffset - usByteOffset * BITS_UCHAR ); + + /* Prepare a mask for setting the new bits. */ + usMask = ( USHORT )( ( 1 << ( USHORT ) ucNBits ) - 1 ); + + /* copy bits into temporary storage. */ + usWordBuf = ucByteBuf[usByteOffset]; + usWordBuf |= ucByteBuf[usByteOffset + 1] << BITS_UCHAR; + + /* throw away unneeded bits. */ + usWordBuf >>= usNPreBits; + + /* mask away bits above the requested bitfield. */ + usWordBuf &= usMask; + + return ( UCHAR ) usWordBuf; +} + +eMBException +prveMBError2Exception( eMBErrorCode eErrorCode ) +{ + eMBException eStatus; + + switch ( eErrorCode ) + { + case MB_ENOERR: + eStatus = MB_EX_NONE; + break; + + case MB_ENOREG: + eStatus = MB_EX_ILLEGAL_DATA_ADDRESS; + break; + + case MB_ETIMEDOUT: + eStatus = MB_EX_SLAVE_BUSY; + break; + + default: + eStatus = MB_EX_SLAVE_DEVICE_FAILURE; + break; + } + + return eStatus; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/include/mb.h Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,417 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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.h,v 1.17 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_H +#define _MB_H + +#include "port.h" + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif + +#include "mbport.h" +#include "mbproto.h" + +/*! \defgroup modbus Modbus + * \code #include "mb.h" \endcode + * + * This module defines the interface for the application. It contains + * the basic functions and types required to use the Modbus protocol stack. + * A typical application will want to call eMBInit() 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 eMBPoll() 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 eMBPoll(). + * + * \code + * // Initialize protocol stack in RTU mode for a slave with address 10 = 0x0A + * eMBInit( MB_RTU, 0x0A, 38400, MB_PAR_EVEN ); + * // Enable the Modbus Protocol Stack. + * eMBEnable( ); + * for( ;; ) + * { + * // Call the main polling loop of the Modbus protocol stack. + * eMBPoll( ); + * ... + * } + * \endcode + */ + +/* ----------------------- Defines ------------------------------------------*/ + +/*! \ingroup modbus + * \brief Use the default Modbus TCP port (502) + */ +#define MB_TCP_PORT_USE_DEFAULT 0 + +/* ----------------------- Type definitions ---------------------------------*/ + +/*! \ingroup modbus + * \brief Modbus serial transmission modes (RTU/ASCII). + * + * Modbus serial supports two transmission modes. Either ASCII or RTU. RTU + * is faster but has more hardware requirements and requires a network with + * a low jitter. ASCII is slower and more reliable on slower links (E.g. modems) + */ + typedef enum +{ + MB_RTU, /*!< RTU transmission mode. */ + MB_ASCII, /*!< ASCII transmission mode. */ + MB_TCP /*!< TCP mode. */ +} eMBMode; + +/*! \ingroup modbus + * \brief If register should be written or read. + * + * This value is passed to the callback functions which support either + * reading or writing register values. Writing means that the application + * registers should be updated and reading means that the modbus protocol + * stack needs to know the current register values. + * + * \see eMBRegHoldingCB( ), eMBRegCoilsCB( ), eMBRegDiscreteCB( ) and + * eMBRegInputCB( ). + */ +typedef enum +{ + MB_REG_READ, /*!< Read register values and pass to protocol stack. */ + MB_REG_WRITE /*!< Update register values. */ +} eMBRegisterMode; + +/*! \ingroup modbus + * \brief Errorcodes used by all function in the protocol stack. + */ +typedef enum +{ + MB_ENOERR, /*!< no error. */ + MB_ENOREG, /*!< illegal register address. */ + MB_EINVAL, /*!< illegal argument. */ + MB_EPORTERR, /*!< porting layer error. */ + MB_ENORES, /*!< insufficient resources. */ + MB_EIO, /*!< I/O error. */ + MB_EILLSTATE, /*!< protocol stack in illegal state. */ + MB_ETIMEDOUT /*!< timeout error occurred. */ +} eMBErrorCode; + + +/* ----------------------- Function prototypes ------------------------------*/ +/*! \ingroup modbus + * \brief Initialize the Modbus 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 eMBEnable( ) has been called. + * + * \param eMode If ASCII or RTU mode should be used. + * \param ucSlaveAddress The slave address. Only frames sent to this + * address or to the broadcast address are processed. + * \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 eMBEnable( ). 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 eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, + UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ); + +/*! \ingroup modbus + * \brief Initialize the Modbus 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 eMBTCPInit( USHORT usTCPPort ); + +/*! \ingroup modbus + * \brief Release resources used by the protocol stack. + * + * This function disables the Modbus 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 eMBClose( void ); + +/*! \ingroup modbus + * \brief Enable the Modbus protocol stack. + * + * This function enables processing of Modbus 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 eMBEnable( void ); + +/*! \ingroup modbus + * \brief Disable the Modbus 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 eMBDisable( void ); + +/*! \ingroup modbus + * \brief The main pooling loop of the Modbus 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 xMBPortEventGet() 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 eMBPoll( void ); + +/*! \ingroup modbus + * \brief Configure the slave id of the device. + * + * This function should be called when the Modbus function <em>Report Slave ID</em> + * is enabled ( By defining MB_FUNC_OTHER_REP_SLAVEID_ENABLED in mbconfig.h ). + * + * \param ucSlaveID Values is returned in the <em>Slave ID</em> byte of the + * <em>Report Slave ID</em> response. + * \param xIsRunning If TRUE the <em>Run Indicator Status</em> byte is set to 0xFF. + * otherwise the <em>Run Indicator Status</em> is 0x00. + * \param pucAdditional Values which should be returned in the <em>Additional</em> + * bytes of the <em> Report Slave ID</em> response. + * \param usAdditionalLen Length of the buffer <code>pucAdditonal</code>. + * + * \return If the static buffer defined by MB_FUNC_OTHER_REP_SLAVEID_BUF in + * mbconfig.h is to small it returns eMBErrorCode::MB_ENORES. Otherwise + * it returns eMBErrorCode::MB_ENOERR. + */ +eMBErrorCode eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning, + UCHAR const *pucAdditional, + USHORT usAdditionalLen ); + +/*! \ingroup modbus + * \brief Registers a callback handler for a given function code. + * + * This function registers a new callback handler for a given function code. + * The callback handler supplied is responsible for interpreting the Modbus PDU and + * the creation of an appropriate response. In case of an error it should return + * one of the possible Modbus exceptions which results in a Modbus exception frame + * sent by the protocol stack. + * + * \param ucFunctionCode The Modbus function code for which this handler should + * be registers. Valid function codes are in the range 1 to 127. + * \param pxHandler The function handler which should be called in case + * such a frame is received. If \c NULL a previously registered function handler + * for this function code is removed. + * + * \return eMBErrorCode::MB_ENOERR if the handler has been installed. If no + * more resources are available it returns eMBErrorCode::MB_ENORES. In this + * case the values in mbconfig.h should be adjusted. If the argument was not + * valid it returns eMBErrorCode::MB_EINVAL. + */ +eMBErrorCode eMBRegisterCB( UCHAR ucFunctionCode, + pxMBFunctionHandler pxHandler ); + +/* ----------------------- Callback -----------------------------------------*/ + +/*! \defgroup modbus_registers Modbus Registers + * \code #include "mb.h" \endcode + * The protocol stack does not internally allocate any memory for the + * registers. This makes the protocol stack very small and also usable on + * low end targets. In addition the values don't have to be in the memory + * and could for example be stored in a flash.<br> + * Whenever the protocol stack requires a value it calls one of the callback + * function with the register address and the number of registers to read + * as an argument. The application should then read the actual register values + * (for example the ADC voltage) and should store the result in the supplied + * buffer.<br> + * If the protocol stack wants to update a register value because a write + * register function was received a buffer with the new register values is + * passed to the callback function. The function should then use these values + * to update the application register values. + */ + +/*! \ingroup modbus_registers + * \brief Callback function used if the value of a <em>Input Register</em> + * is required by the protocol stack. The starting register address is given + * by \c usAddress and the last register is given by <tt>usAddress + + * usNRegs - 1</tt>. + * + * \param pucRegBuffer A buffer where the callback function should write + * the current value of the modbus registers to. + * \param usAddress The starting address of the register. Input registers + * are in the range 1 - 65535. + * \param usNRegs Number of registers the callback function must supply. + * + * \return The function must return one of the following error codes: + * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal + * Modbus response is sent. + * - eMBErrorCode::MB_ENOREG If the application can not supply values + * for registers within this range. In this case a + * <b>ILLEGAL DATA ADDRESS</b> exception frame is sent as a response. + * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is + * currently not available and the application dependent response + * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b> + * exception is sent as a response. + * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case + * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response. + */ +eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, + USHORT usNRegs ); + +/*! \ingroup modbus_registers + * \brief Callback function used if a <em>Holding Register</em> value is + * read or written by the protocol stack. The starting register address + * is given by \c usAddress and the last register is given by + * <tt>usAddress + usNRegs - 1</tt>. + * + * \param pucRegBuffer If the application registers values should be updated the + * buffer points to the new registers values. If the protocol stack needs + * to now the current values the callback function should write them into + * this buffer. + * \param usAddress The starting address of the register. + * \param usNRegs Number of registers to read or write. + * \param eMode If eMBRegisterMode::MB_REG_WRITE the application register + * values should be updated from the values in the buffer. For example + * this would be the case when the Modbus master has issued an + * <b>WRITE SINGLE REGISTER</b> command. + * If the value eMBRegisterMode::MB_REG_READ the application should copy + * the current values into the buffer \c pucRegBuffer. + * + * \return The function must return one of the following error codes: + * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal + * Modbus response is sent. + * - eMBErrorCode::MB_ENOREG If the application can not supply values + * for registers within this range. In this case a + * <b>ILLEGAL DATA ADDRESS</b> exception frame is sent as a response. + * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is + * currently not available and the application dependent response + * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b> + * exception is sent as a response. + * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case + * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response. + */ +eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, + USHORT usNRegs, eMBRegisterMode eMode ); + +/*! \ingroup modbus_registers + * \brief Callback function used if a <em>Coil Register</em> value is + * read or written by the protocol stack. If you are going to use + * this function you might use the functions xMBUtilSetBits( ) and + * xMBUtilGetBits( ) for working with bitfields. + * + * \param pucRegBuffer The bits are packed in bytes where the first coil + * starting at address \c usAddress is stored in the LSB of the + * first byte in the buffer <code>pucRegBuffer</code>. + * If the buffer should be written by the callback function unused + * coil values (I.e. if not a multiple of eight coils is used) should be set + * to zero. + * \param usAddress The first coil number. + * \param usNCoils Number of coil values requested. + * \param eMode If eMBRegisterMode::MB_REG_WRITE the application values should + * be updated from the values supplied in the buffer \c pucRegBuffer. + * If eMBRegisterMode::MB_REG_READ the application should store the current + * values in the buffer \c pucRegBuffer. + * + * \return The function must return one of the following error codes: + * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal + * Modbus response is sent. + * - eMBErrorCode::MB_ENOREG If the application does not map an coils + * within the requested address range. In this case a + * <b>ILLEGAL DATA ADDRESS</b> is sent as a response. + * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is + * currently not available and the application dependent response + * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b> + * exception is sent as a response. + * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case + * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response. + */ +eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, + USHORT usNCoils, eMBRegisterMode eMode ); + +/*! \ingroup modbus_registers + * \brief Callback function used if a <em>Input Discrete Register</em> value is + * read by the protocol stack. + * + * If you are going to use his function you might use the functions + * xMBUtilSetBits( ) and xMBUtilGetBits( ) for working with bitfields. + * + * \param pucRegBuffer The buffer should be updated with the current + * coil values. The first discrete input starting at \c usAddress must be + * stored at the LSB of the first byte in the buffer. If the requested number + * is not a multiple of eight the remaining bits should be set to zero. + * \param usAddress The starting address of the first discrete input. + * \param usNDiscrete Number of discrete input values. + * \return The function must return one of the following error codes: + * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal + * Modbus response is sent. + * - eMBErrorCode::MB_ENOREG If no such discrete inputs exists. + * In this case a <b>ILLEGAL DATA ADDRESS</b> exception frame is sent + * as a response. + * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is + * currently not available and the application dependent response + * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b> + * exception is sent as a response. + * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case + * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response. + */ +eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, + USHORT usNDiscrete ); + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/include/mbconfig.h Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,103 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbconfig.h,v 1.14 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_CONFIG_H +#define _MB_CONFIG_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif +/* ----------------------- Defines ------------------------------------------*/ +/*! \defgroup modbus_cfg Modbus Configuration + * + * Most modules in the protocol stack are completly optional and can be + * excluded. This is specially important if target resources are very small + * and program memory space should be saved.<br> + * + * All of these settings are available in the file <code>mbconfig.h</code> + */ +/*! \addtogroup modbus_cfg + * @{ + */ +/*! \brief If Modbus ASCII support is enabled. */ +#define MB_ASCII_ENABLED ( 0 ) +/*! \brief If Modbus RTU support is enabled. */ +#define MB_RTU_ENABLED ( 1 ) +/*! \brief If Modbus TCP support is enabled. */ +#define MB_TCP_ENABLED ( 0 ) +/*! \brief The character timeout value for Modbus ASCII. + * + * The character timeout value is not fixed for Modbus ASCII and is therefore + * a configuration option. It should be set to the maximum expected delay + * time of the network. + */ +#define MB_ASCII_TIMEOUT_SEC ( 0 ) +/*! \brief Maximum number of Modbus functions codes the protocol stack + * should support. + * + * The maximum number of supported Modbus functions must be greater than + * the sum of all enabled functions in this file and custom function + * handlers. If set to small adding more functions will fail. + */ +#define MB_FUNC_HANDLERS_MAX ( 16 ) +/*! \brief Number of bytes which should be allocated for the <em>Report Slave ID + * </em>command. + * + * This number limits the maximum size of the additional segment in the + * report slave id function. See eMBSetSlaveID( ) for more information on + * how to set this value. It is only used if MB_FUNC_OTHER_REP_SLAVEID_ENABLED + * is set to <code>1</code>. + */ +#define MB_FUNC_OTHER_REP_SLAVEID_BUF ( 32 ) +/*! \brief If the <em>Report Slave ID</em> function should be enabled. */ +#define MB_FUNC_OTHER_REP_SLAVEID_ENABLED ( 1 ) +/*! \brief If the <em>Read Input Registers</em> function should be enabled. */ +#define MB_FUNC_READ_INPUT_ENABLED ( 1 ) +/*! \brief If the <em>Read Holding Registers</em> function should be enabled. */ +#define MB_FUNC_READ_HOLDING_ENABLED ( 1 ) +/*! \brief If the <em>Write Single Register</em> function should be enabled. */ +#define MB_FUNC_WRITE_HOLDING_ENABLED ( 1 ) +/*! \brief If the <em>Write Multiple registers</em> function should be enabled. */ +#define MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED ( 1 ) +/*! \brief If the <em>Read Coils</em> function should be enabled. */ +#define MB_FUNC_READ_COILS_ENABLED ( 1 ) +/*! \brief If the <em>Write Coils</em> function should be enabled. */ +#define MB_FUNC_WRITE_COIL_ENABLED ( 1 ) +/*! \brief If the <em>Write Multiple Coils</em> function should be enabled. */ +#define MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED ( 1 ) +/*! \brief If the <em>Read Discrete Inputs</em> function should be enabled. */ +#define MB_FUNC_READ_DISCRETE_INPUTS_ENABLED ( 1 ) +/*! \brief If the <em>Read/Write Multiple Registers</em> function should be enabled. */ +#define MB_FUNC_READWRITE_HOLDING_ENABLED ( 1 ) +/*! @} */ +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/include/mbframe.h Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,87 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbframe.h,v 1.9 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_FRAME_H +#define _MB_FRAME_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif + +/*! + * Constants which defines the format of a modbus frame. The example is + * shown for a Modbus RTU/ASCII frame. Note that the Modbus PDU is not + * dependent on the underlying transport. + * + * <code> + * <------------------------ MODBUS SERIAL LINE PDU (1) -------------------> + * <----------- MODBUS PDU (1') ----------------> + * +-----------+---------------+----------------------------+-------------+ + * | Address | Function Code | Data | CRC/LRC | + * +-----------+---------------+----------------------------+-------------+ + * | | | | + * (2) (3/2') (3') (4) + * + * (1) ... MB_SER_PDU_SIZE_MAX = 256 + * (2) ... MB_SER_PDU_ADDR_OFF = 0 + * (3) ... MB_SER_PDU_PDU_OFF = 1 + * (4) ... MB_SER_PDU_SIZE_CRC = 2 + * + * (1') ... MB_PDU_SIZE_MAX = 253 + * (2') ... MB_PDU_FUNC_OFF = 0 + * (3') ... MB_PDU_DATA_OFF = 1 + * </code> + */ + +/* ----------------------- Defines ------------------------------------------*/ +#define MB_PDU_SIZE_MAX 253 /*!< Maximum size of a PDU. */ +#define MB_PDU_SIZE_MIN 1 /*!< Function Code */ +#define MB_PDU_FUNC_OFF 0 /*!< Offset of function code in PDU. */ +#define MB_PDU_DATA_OFF 1 /*!< Offset for response data in PDU. */ + +/* ----------------------- Prototypes 0-------------------------------------*/ +typedef void ( *pvMBFrameStart ) ( void ); + +typedef void ( *pvMBFrameStop ) ( void ); + +typedef eMBErrorCode( *peMBFrameReceive ) ( UCHAR * pucRcvAddress, + UCHAR ** pucFrame, + USHORT * pusLength ); + +typedef eMBErrorCode( *peMBFrameSend ) ( UCHAR slaveAddress, + const UCHAR * pucFrame, + USHORT usLength ); + +typedef void( *pvMBFrameClose ) ( void ); + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/include/mbfunc.h Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,80 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbfunc.h,v 1.12 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_FUNC_H +#define _MB_FUNC_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif +#if MB_FUNC_OTHER_REP_SLAVEID_BUF > 0 + eMBException eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_READ_INPUT_ENABLED > 0 +eMBException eMBFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_READ_HOLDING_ENABLED > 0 +eMBException eMBFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_WRITE_HOLDING_ENABLED > 0 +eMBException eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0 +eMBException eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_READ_COILS_ENABLED > 0 +eMBException eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_WRITE_COIL_ENABLED > 0 +eMBException eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0 +eMBException eMBFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0 +eMBException eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0 +eMBException eMBFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); +#endif + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/include/mbport.h Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,127 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbport.h,v 1.17 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_PORT_H +#define _MB_PORT_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif + +/* ----------------------- Type definitions ---------------------------------*/ + +typedef enum +{ + EV_READY, /*!< Startup finished. */ + EV_FRAME_RECEIVED, /*!< Frame received. */ + EV_EXECUTE, /*!< Execute function. */ + EV_FRAME_SENT /*!< Frame sent. */ +} eMBEventType; + +/*! \ingroup modbus + * \brief Parity used for characters in serial mode. + * + * The parity which should be applied to the characters sent over the serial + * link. Please note that this values are actually passed to the porting + * layer and therefore not all parity modes might be available. + */ +typedef enum +{ + MB_PAR_NONE, /*!< No parity. */ + MB_PAR_ODD, /*!< Odd parity. */ + MB_PAR_EVEN /*!< Even parity. */ +} eMBParity; + +/* ----------------------- Supporting functions -----------------------------*/ +BOOL xMBPortEventInit( void ); + +BOOL xMBPortEventPost( eMBEventType eEvent ); + +BOOL xMBPortEventGet( /*@out@ */ eMBEventType * eEvent ); + +/* ----------------------- Serial port functions ----------------------------*/ + +BOOL xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate, + UCHAR ucDataBits, eMBParity eParity ); + +void vMBPortClose( void ); + +void xMBPortSerialClose( void ); + +void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ); + +INLINE BOOL xMBPortSerialGetByte( CHAR * pucByte ); + +INLINE BOOL xMBPortSerialPutByte( CHAR ucByte ); + +/* ----------------------- Timers functions ---------------------------------*/ +BOOL xMBPortTimersInit( USHORT usTimeOut50us ); + +void xMBPortTimersClose( void ); + +INLINE void vMBPortTimersEnable( void ); + +INLINE void vMBPortTimersDisable( void ); + +/* ----------------------- Callback for the protocol stack ------------------*/ + +/*! + * \brief Callback function for the porting layer when a new byte is + * available. + * + * Depending upon the mode this callback function is used by the RTU or + * ASCII transmission layers. In any case a call to xMBPortSerialGetByte() + * must immediately return a new character. + * + * \return <code>TRUE</code> if a event was posted to the queue because + * a new byte was received. The port implementation should wake up the + * tasks which are currently blocked on the eventqueue. + */ +extern BOOL( *pxMBFrameCBByteReceived ) ( void ); + +extern BOOL( *pxMBFrameCBTransmitterEmpty ) ( void ); + +extern BOOL( *pxMBPortCBTimerExpired ) ( void ); + +/* ----------------------- TCP port functions -------------------------------*/ +BOOL xMBTCPPortInit( USHORT usTCPPort ); + +void vMBTCPPortClose( void ); + +void vMBTCPPortDisable( void ); + +BOOL xMBTCPPortGetRequest( UCHAR **ppucMBTCPFrame, USHORT * usTCPLength ); + +BOOL xMBTCPPortSendResponse( const UCHAR *pucMBTCPFrame, USHORT usTCPLength ); + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/include/mbproto.h Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,83 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbproto.h,v 1.14 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_PROTO_H +#define _MB_PROTO_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif +/* ----------------------- Defines ------------------------------------------*/ +#define MB_ADDRESS_BROADCAST ( 0 ) /*! Modbus broadcast address. */ +#define MB_ADDRESS_MIN ( 1 ) /*! Smallest possible slave address. */ +#define MB_ADDRESS_MAX ( 247 ) /*! Biggest possible slave address. */ +#define MB_FUNC_NONE ( 0 ) +#define MB_FUNC_READ_COILS ( 1 ) +#define MB_FUNC_READ_DISCRETE_INPUTS ( 2 ) +#define MB_FUNC_WRITE_SINGLE_COIL ( 5 ) +#define MB_FUNC_WRITE_MULTIPLE_COILS ( 15 ) +#define MB_FUNC_READ_HOLDING_REGISTER ( 3 ) +#define MB_FUNC_READ_INPUT_REGISTER ( 4 ) +#define MB_FUNC_WRITE_REGISTER ( 6 ) +#define MB_FUNC_WRITE_MULTIPLE_REGISTERS ( 16 ) +#define MB_FUNC_READWRITE_MULTIPLE_REGISTERS ( 23 ) +#define MB_FUNC_DIAG_READ_EXCEPTION ( 7 ) +#define MB_FUNC_DIAG_DIAGNOSTIC ( 8 ) +#define MB_FUNC_DIAG_GET_COM_EVENT_CNT ( 11 ) +#define MB_FUNC_DIAG_GET_COM_EVENT_LOG ( 12 ) +#define MB_FUNC_OTHER_REPORT_SLAVEID ( 17 ) +#define MB_FUNC_ERROR ( 128 ) +/* ----------------------- Type definitions ---------------------------------*/ + typedef enum +{ + MB_EX_NONE = 0x00, + MB_EX_ILLEGAL_FUNCTION = 0x01, + MB_EX_ILLEGAL_DATA_ADDRESS = 0x02, + MB_EX_ILLEGAL_DATA_VALUE = 0x03, + MB_EX_SLAVE_DEVICE_FAILURE = 0x04, + MB_EX_ACKNOWLEDGE = 0x05, + MB_EX_SLAVE_BUSY = 0x06, + MB_EX_MEMORY_PARITY_ERROR = 0x08, + MB_EX_GATEWAY_PATH_FAILED = 0x0A, + MB_EX_GATEWAY_TGT_FAILED = 0x0B +} eMBException; + +typedef eMBException( *pxMBFunctionHandler ) ( UCHAR * pucFrame, USHORT * pusLength ); + +typedef struct +{ + UCHAR ucFunctionCode; + pxMBFunctionHandler pxHandler; +} xMBFunctionHandler; + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/include/mbutils.h Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,108 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbutils.h,v 1.5 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_UTILS_H +#define _MB_UTILS_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif +/*! \defgroup modbus_utils Utilities + * + * This module contains some utility functions which can be used by + * the application. It includes some special functions for working with + * bitfields backed by a character array buffer. + * + */ +/*! \addtogroup modbus_utils + * @{ + */ +/*! \brief Function to set bits in a byte buffer. + * + * This function allows the efficient use of an array to implement bitfields. + * The array used for storing the bits must always be a multiple of two + * bytes. Up to eight bits can be set or cleared in one operation. + * + * \param ucByteBuf A buffer where the bit values are stored. Must be a + * multiple of 2 bytes. No length checking is performed and if + * usBitOffset / 8 is greater than the size of the buffer memory contents + * is overwritten. + * \param usBitOffset The starting address of the bits to set. The first + * bit has the offset 0. + * \param ucNBits Number of bits to modify. The value must always be smaller + * than 8. + * \param ucValues Thew new values for the bits. The value for the first bit + * starting at <code>usBitOffset</code> is the LSB of the value + * <code>ucValues</code> + * + * \code + * ucBits[2] = {0, 0}; + * + * // Set bit 4 to 1 (read: set 1 bit starting at bit offset 4 to value 1) + * xMBUtilSetBits( ucBits, 4, 1, 1 ); + * + * // Set bit 7 to 1 and bit 8 to 0. + * xMBUtilSetBits( ucBits, 7, 2, 0x01 ); + * + * // Set bits 8 - 11 to 0x05 and bits 12 - 15 to 0x0A; + * xMBUtilSetBits( ucBits, 8, 8, 0x5A); + * \endcode + */ +void xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset, + UCHAR ucNBits, UCHAR ucValues ); + +/*! \brief Function to read bits in a byte buffer. + * + * This function is used to extract up bit values from an array. Up to eight + * bit values can be extracted in one step. + * + * \param ucByteBuf A buffer where the bit values are stored. + * \param usBitOffset The starting address of the bits to set. The first + * bit has the offset 0. + * \param ucNBits Number of bits to modify. The value must always be smaller + * than 8. + * + * \code + * UCHAR ucBits[2] = {0, 0}; + * UCHAR ucResult; + * + * // Extract the bits 3 - 10. + * ucResult = xMBUtilGetBits( ucBits, 3, 8 ); + * \endcode + */ +UCHAR xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset, + UCHAR ucNBits ); + +/*! @} */ + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif
--- a/Modbus/mb.h Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,417 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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.h,v 1.17 2006/12/07 22:10:34 wolti Exp $ - */ - -#ifndef _MB_H -#define _MB_H - -#include "port.h" - -#ifdef __cplusplus -PR_BEGIN_EXTERN_C -#endif - -#include "mbport.h" -#include "mbproto.h" - -/*! \defgroup modbus Modbus - * \code #include "mb.h" \endcode - * - * This module defines the interface for the application. It contains - * the basic functions and types required to use the Modbus protocol stack. - * A typical application will want to call eMBInit() 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 eMBPoll() 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 eMBPoll(). - * - * \code - * // Initialize protocol stack in RTU mode for a slave with address 10 = 0x0A - * eMBInit( MB_RTU, 0x0A, 38400, MB_PAR_EVEN ); - * // Enable the Modbus Protocol Stack. - * eMBEnable( ); - * for( ;; ) - * { - * // Call the main polling loop of the Modbus protocol stack. - * eMBPoll( ); - * ... - * } - * \endcode - */ - -/* ----------------------- Defines ------------------------------------------*/ - -/*! \ingroup modbus - * \brief Use the default Modbus TCP port (502) - */ -#define MB_TCP_PORT_USE_DEFAULT 0 - -/* ----------------------- Type definitions ---------------------------------*/ - -/*! \ingroup modbus - * \brief Modbus serial transmission modes (RTU/ASCII). - * - * Modbus serial supports two transmission modes. Either ASCII or RTU. RTU - * is faster but has more hardware requirements and requires a network with - * a low jitter. ASCII is slower and more reliable on slower links (E.g. modems) - */ - typedef enum -{ - MB_RTU, /*!< RTU transmission mode. */ - MB_ASCII, /*!< ASCII transmission mode. */ - MB_TCP /*!< TCP mode. */ -} eMBMode; - -/*! \ingroup modbus - * \brief If register should be written or read. - * - * This value is passed to the callback functions which support either - * reading or writing register values. Writing means that the application - * registers should be updated and reading means that the modbus protocol - * stack needs to know the current register values. - * - * \see eMBRegHoldingCB( ), eMBRegCoilsCB( ), eMBRegDiscreteCB( ) and - * eMBRegInputCB( ). - */ -typedef enum -{ - MB_REG_READ, /*!< Read register values and pass to protocol stack. */ - MB_REG_WRITE /*!< Update register values. */ -} eMBRegisterMode; - -/*! \ingroup modbus - * \brief Errorcodes used by all function in the protocol stack. - */ -typedef enum -{ - MB_ENOERR, /*!< no error. */ - MB_ENOREG, /*!< illegal register address. */ - MB_EINVAL, /*!< illegal argument. */ - MB_EPORTERR, /*!< porting layer error. */ - MB_ENORES, /*!< insufficient resources. */ - MB_EIO, /*!< I/O error. */ - MB_EILLSTATE, /*!< protocol stack in illegal state. */ - MB_ETIMEDOUT /*!< timeout error occurred. */ -} eMBErrorCode; - - -/* ----------------------- Function prototypes ------------------------------*/ -/*! \ingroup modbus - * \brief Initialize the Modbus 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 eMBEnable( ) has been called. - * - * \param eMode If ASCII or RTU mode should be used. - * \param ucSlaveAddress The slave address. Only frames sent to this - * address or to the broadcast address are processed. - * \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 eMBEnable( ). 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 eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, - UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ); - -/*! \ingroup modbus - * \brief Initialize the Modbus 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 eMBTCPInit( USHORT usTCPPort ); - -/*! \ingroup modbus - * \brief Release resources used by the protocol stack. - * - * This function disables the Modbus 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 eMBClose( void ); - -/*! \ingroup modbus - * \brief Enable the Modbus protocol stack. - * - * This function enables processing of Modbus 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 eMBEnable( void ); - -/*! \ingroup modbus - * \brief Disable the Modbus 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 eMBDisable( void ); - -/*! \ingroup modbus - * \brief The main pooling loop of the Modbus 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 xMBPortEventGet() 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 eMBPoll( void ); - -/*! \ingroup modbus - * \brief Configure the slave id of the device. - * - * This function should be called when the Modbus function <em>Report Slave ID</em> - * is enabled ( By defining MB_FUNC_OTHER_REP_SLAVEID_ENABLED in mbconfig.h ). - * - * \param ucSlaveID Values is returned in the <em>Slave ID</em> byte of the - * <em>Report Slave ID</em> response. - * \param xIsRunning If TRUE the <em>Run Indicator Status</em> byte is set to 0xFF. - * otherwise the <em>Run Indicator Status</em> is 0x00. - * \param pucAdditional Values which should be returned in the <em>Additional</em> - * bytes of the <em> Report Slave ID</em> response. - * \param usAdditionalLen Length of the buffer <code>pucAdditonal</code>. - * - * \return If the static buffer defined by MB_FUNC_OTHER_REP_SLAVEID_BUF in - * mbconfig.h is to small it returns eMBErrorCode::MB_ENORES. Otherwise - * it returns eMBErrorCode::MB_ENOERR. - */ -eMBErrorCode eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning, - UCHAR const *pucAdditional, - USHORT usAdditionalLen ); - -/*! \ingroup modbus - * \brief Registers a callback handler for a given function code. - * - * This function registers a new callback handler for a given function code. - * The callback handler supplied is responsible for interpreting the Modbus PDU and - * the creation of an appropriate response. In case of an error it should return - * one of the possible Modbus exceptions which results in a Modbus exception frame - * sent by the protocol stack. - * - * \param ucFunctionCode The Modbus function code for which this handler should - * be registers. Valid function codes are in the range 1 to 127. - * \param pxHandler The function handler which should be called in case - * such a frame is received. If \c NULL a previously registered function handler - * for this function code is removed. - * - * \return eMBErrorCode::MB_ENOERR if the handler has been installed. If no - * more resources are available it returns eMBErrorCode::MB_ENORES. In this - * case the values in mbconfig.h should be adjusted. If the argument was not - * valid it returns eMBErrorCode::MB_EINVAL. - */ -eMBErrorCode eMBRegisterCB( UCHAR ucFunctionCode, - pxMBFunctionHandler pxHandler ); - -/* ----------------------- Callback -----------------------------------------*/ - -/*! \defgroup modbus_registers Modbus Registers - * \code #include "mb.h" \endcode - * The protocol stack does not internally allocate any memory for the - * registers. This makes the protocol stack very small and also usable on - * low end targets. In addition the values don't have to be in the memory - * and could for example be stored in a flash.<br> - * Whenever the protocol stack requires a value it calls one of the callback - * function with the register address and the number of registers to read - * as an argument. The application should then read the actual register values - * (for example the ADC voltage) and should store the result in the supplied - * buffer.<br> - * If the protocol stack wants to update a register value because a write - * register function was received a buffer with the new register values is - * passed to the callback function. The function should then use these values - * to update the application register values. - */ - -/*! \ingroup modbus_registers - * \brief Callback function used if the value of a <em>Input Register</em> - * is required by the protocol stack. The starting register address is given - * by \c usAddress and the last register is given by <tt>usAddress + - * usNRegs - 1</tt>. - * - * \param pucRegBuffer A buffer where the callback function should write - * the current value of the modbus registers to. - * \param usAddress The starting address of the register. Input registers - * are in the range 1 - 65535. - * \param usNRegs Number of registers the callback function must supply. - * - * \return The function must return one of the following error codes: - * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal - * Modbus response is sent. - * - eMBErrorCode::MB_ENOREG If the application can not supply values - * for registers within this range. In this case a - * <b>ILLEGAL DATA ADDRESS</b> exception frame is sent as a response. - * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is - * currently not available and the application dependent response - * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b> - * exception is sent as a response. - * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case - * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response. - */ -eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, - USHORT usNRegs ); - -/*! \ingroup modbus_registers - * \brief Callback function used if a <em>Holding Register</em> value is - * read or written by the protocol stack. The starting register address - * is given by \c usAddress and the last register is given by - * <tt>usAddress + usNRegs - 1</tt>. - * - * \param pucRegBuffer If the application registers values should be updated the - * buffer points to the new registers values. If the protocol stack needs - * to now the current values the callback function should write them into - * this buffer. - * \param usAddress The starting address of the register. - * \param usNRegs Number of registers to read or write. - * \param eMode If eMBRegisterMode::MB_REG_WRITE the application register - * values should be updated from the values in the buffer. For example - * this would be the case when the Modbus master has issued an - * <b>WRITE SINGLE REGISTER</b> command. - * If the value eMBRegisterMode::MB_REG_READ the application should copy - * the current values into the buffer \c pucRegBuffer. - * - * \return The function must return one of the following error codes: - * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal - * Modbus response is sent. - * - eMBErrorCode::MB_ENOREG If the application can not supply values - * for registers within this range. In this case a - * <b>ILLEGAL DATA ADDRESS</b> exception frame is sent as a response. - * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is - * currently not available and the application dependent response - * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b> - * exception is sent as a response. - * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case - * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response. - */ -eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, - USHORT usNRegs, eMBRegisterMode eMode ); - -/*! \ingroup modbus_registers - * \brief Callback function used if a <em>Coil Register</em> value is - * read or written by the protocol stack. If you are going to use - * this function you might use the functions xMBUtilSetBits( ) and - * xMBUtilGetBits( ) for working with bitfields. - * - * \param pucRegBuffer The bits are packed in bytes where the first coil - * starting at address \c usAddress is stored in the LSB of the - * first byte in the buffer <code>pucRegBuffer</code>. - * If the buffer should be written by the callback function unused - * coil values (I.e. if not a multiple of eight coils is used) should be set - * to zero. - * \param usAddress The first coil number. - * \param usNCoils Number of coil values requested. - * \param eMode If eMBRegisterMode::MB_REG_WRITE the application values should - * be updated from the values supplied in the buffer \c pucRegBuffer. - * If eMBRegisterMode::MB_REG_READ the application should store the current - * values in the buffer \c pucRegBuffer. - * - * \return The function must return one of the following error codes: - * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal - * Modbus response is sent. - * - eMBErrorCode::MB_ENOREG If the application does not map an coils - * within the requested address range. In this case a - * <b>ILLEGAL DATA ADDRESS</b> is sent as a response. - * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is - * currently not available and the application dependent response - * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b> - * exception is sent as a response. - * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case - * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response. - */ -eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, - USHORT usNCoils, eMBRegisterMode eMode ); - -/*! \ingroup modbus_registers - * \brief Callback function used if a <em>Input Discrete Register</em> value is - * read by the protocol stack. - * - * If you are going to use his function you might use the functions - * xMBUtilSetBits( ) and xMBUtilGetBits( ) for working with bitfields. - * - * \param pucRegBuffer The buffer should be updated with the current - * coil values. The first discrete input starting at \c usAddress must be - * stored at the LSB of the first byte in the buffer. If the requested number - * is not a multiple of eight the remaining bits should be set to zero. - * \param usAddress The starting address of the first discrete input. - * \param usNDiscrete Number of discrete input values. - * \return The function must return one of the following error codes: - * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal - * Modbus response is sent. - * - eMBErrorCode::MB_ENOREG If no such discrete inputs exists. - * In this case a <b>ILLEGAL DATA ADDRESS</b> exception frame is sent - * as a response. - * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is - * currently not available and the application dependent response - * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b> - * exception is sent as a response. - * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case - * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response. - */ -eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, - USHORT usNDiscrete ); - -#ifdef __cplusplus -PR_END_EXTERN_C -#endif -#endif
--- a/Modbus/mbconfig.h Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbconfig.h,v 1.14 2006/12/07 22:10:34 wolti Exp $ - */ - -#ifndef _MB_CONFIG_H -#define _MB_CONFIG_H - -#ifdef __cplusplus -PR_BEGIN_EXTERN_C -#endif -/* ----------------------- Defines ------------------------------------------*/ -/*! \defgroup modbus_cfg Modbus Configuration - * - * Most modules in the protocol stack are completly optional and can be - * excluded. This is specially important if target resources are very small - * and program memory space should be saved.<br> - * - * All of these settings are available in the file <code>mbconfig.h</code> - */ -/*! \addtogroup modbus_cfg - * @{ - */ -/*! \brief If Modbus ASCII support is enabled. */ -#define MB_ASCII_ENABLED ( 0 ) -/*! \brief If Modbus RTU support is enabled. */ -#define MB_RTU_ENABLED ( 1 ) -/*! \brief If Modbus TCP support is enabled. */ -#define MB_TCP_ENABLED ( 0 ) -/*! \brief The character timeout value for Modbus ASCII. - * - * The character timeout value is not fixed for Modbus ASCII and is therefore - * a configuration option. It should be set to the maximum expected delay - * time of the network. - */ -#define MB_ASCII_TIMEOUT_SEC ( 0 ) -/*! \brief Maximum number of Modbus functions codes the protocol stack - * should support. - * - * The maximum number of supported Modbus functions must be greater than - * the sum of all enabled functions in this file and custom function - * handlers. If set to small adding more functions will fail. - */ -#define MB_FUNC_HANDLERS_MAX ( 16 ) -/*! \brief Number of bytes which should be allocated for the <em>Report Slave ID - * </em>command. - * - * This number limits the maximum size of the additional segment in the - * report slave id function. See eMBSetSlaveID( ) for more information on - * how to set this value. It is only used if MB_FUNC_OTHER_REP_SLAVEID_ENABLED - * is set to <code>1</code>. - */ -#define MB_FUNC_OTHER_REP_SLAVEID_BUF ( 32 ) -/*! \brief If the <em>Report Slave ID</em> function should be enabled. */ -#define MB_FUNC_OTHER_REP_SLAVEID_ENABLED ( 1 ) -/*! \brief If the <em>Read Input Registers</em> function should be enabled. */ -#define MB_FUNC_READ_INPUT_ENABLED ( 1 ) -/*! \brief If the <em>Read Holding Registers</em> function should be enabled. */ -#define MB_FUNC_READ_HOLDING_ENABLED ( 1 ) -/*! \brief If the <em>Write Single Register</em> function should be enabled. */ -#define MB_FUNC_WRITE_HOLDING_ENABLED ( 1 ) -/*! \brief If the <em>Write Multiple registers</em> function should be enabled. */ -#define MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED ( 1 ) -/*! \brief If the <em>Read Coils</em> function should be enabled. */ -#define MB_FUNC_READ_COILS_ENABLED ( 1 ) -/*! \brief If the <em>Write Coils</em> function should be enabled. */ -#define MB_FUNC_WRITE_COIL_ENABLED ( 1 ) -/*! \brief If the <em>Write Multiple Coils</em> function should be enabled. */ -#define MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED ( 1 ) -/*! \brief If the <em>Read Discrete Inputs</em> function should be enabled. */ -#define MB_FUNC_READ_DISCRETE_INPUTS_ENABLED ( 1 ) -/*! \brief If the <em>Read/Write Multiple Registers</em> function should be enabled. */ -#define MB_FUNC_READWRITE_HOLDING_ENABLED ( 1 ) -/*! @} */ -#ifdef __cplusplus -PR_END_EXTERN_C -#endif -#endif
--- a/Modbus/mbcrc.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbcrc.c,v 1.7 2007/02/18 23:50:27 wolti Exp $ - */ - -/* ----------------------- Platform includes --------------------------------*/ -#include "port.h" - -static const UCHAR aucCRCHi[] = { - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40 -}; - -static const UCHAR aucCRCLo[] = { - 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, - 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, - 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, - 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, - 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, - 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, - 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, - 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, - 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, - 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, - 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, - 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, - 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, - 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, - 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, - 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, - 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, - 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, - 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, - 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, - 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, - 0x41, 0x81, 0x80, 0x40 -}; - -USHORT -usMBCRC16( UCHAR * pucFrame, USHORT usLen ) -{ - UCHAR ucCRCHi = 0xFF; - UCHAR ucCRCLo = 0xFF; - int iIndex; - - while( usLen-- ) - { - iIndex = ucCRCLo ^ *( pucFrame++ ); - ucCRCLo = ( UCHAR )( ucCRCHi ^ aucCRCHi[iIndex] ); - ucCRCHi = aucCRCLo[iIndex]; - } - return ( USHORT )( ucCRCHi << 8 | ucCRCLo ); -}
--- a/Modbus/mbcrc.h Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbcrc.h,v 1.5 2006/12/07 22:10:34 wolti Exp $ - */ - -#ifndef _MB_CRC_H -#define _MB_CRC_H - -USHORT usMBCRC16( UCHAR * pucFrame, USHORT usLen ); - -#endif
--- a/Modbus/mbframe.h Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbframe.h,v 1.9 2006/12/07 22:10:34 wolti Exp $ - */ - -#ifndef _MB_FRAME_H -#define _MB_FRAME_H - -#ifdef __cplusplus -PR_BEGIN_EXTERN_C -#endif - -/*! - * Constants which defines the format of a modbus frame. The example is - * shown for a Modbus RTU/ASCII frame. Note that the Modbus PDU is not - * dependent on the underlying transport. - * - * <code> - * <------------------------ MODBUS SERIAL LINE PDU (1) -------------------> - * <----------- MODBUS PDU (1') ----------------> - * +-----------+---------------+----------------------------+-------------+ - * | Address | Function Code | Data | CRC/LRC | - * +-----------+---------------+----------------------------+-------------+ - * | | | | - * (2) (3/2') (3') (4) - * - * (1) ... MB_SER_PDU_SIZE_MAX = 256 - * (2) ... MB_SER_PDU_ADDR_OFF = 0 - * (3) ... MB_SER_PDU_PDU_OFF = 1 - * (4) ... MB_SER_PDU_SIZE_CRC = 2 - * - * (1') ... MB_PDU_SIZE_MAX = 253 - * (2') ... MB_PDU_FUNC_OFF = 0 - * (3') ... MB_PDU_DATA_OFF = 1 - * </code> - */ - -/* ----------------------- Defines ------------------------------------------*/ -#define MB_PDU_SIZE_MAX 253 /*!< Maximum size of a PDU. */ -#define MB_PDU_SIZE_MIN 1 /*!< Function Code */ -#define MB_PDU_FUNC_OFF 0 /*!< Offset of function code in PDU. */ -#define MB_PDU_DATA_OFF 1 /*!< Offset for response data in PDU. */ - -/* ----------------------- Prototypes 0-------------------------------------*/ -typedef void ( *pvMBFrameStart ) ( void ); - -typedef void ( *pvMBFrameStop ) ( void ); - -typedef eMBErrorCode( *peMBFrameReceive ) ( UCHAR * pucRcvAddress, - UCHAR ** pucFrame, - USHORT * pusLength ); - -typedef eMBErrorCode( *peMBFrameSend ) ( UCHAR slaveAddress, - const UCHAR * pucFrame, - USHORT usLength ); - -typedef void( *pvMBFrameClose ) ( void ); - -#ifdef __cplusplus -PR_END_EXTERN_C -#endif -#endif
--- a/Modbus/mbfunc.h Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbfunc.h,v 1.12 2006/12/07 22:10:34 wolti Exp $ - */ - -#ifndef _MB_FUNC_H -#define _MB_FUNC_H - -#ifdef __cplusplus -PR_BEGIN_EXTERN_C -#endif -#if MB_FUNC_OTHER_REP_SLAVEID_BUF > 0 - eMBException eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen ); -#endif - -#if MB_FUNC_READ_INPUT_ENABLED > 0 -eMBException eMBFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen ); -#endif - -#if MB_FUNC_READ_HOLDING_ENABLED > 0 -eMBException eMBFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); -#endif - -#if MB_FUNC_WRITE_HOLDING_ENABLED > 0 -eMBException eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); -#endif - -#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0 -eMBException eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); -#endif - -#if MB_FUNC_READ_COILS_ENABLED > 0 -eMBException eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen ); -#endif - -#if MB_FUNC_WRITE_COIL_ENABLED > 0 -eMBException eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen ); -#endif - -#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0 -eMBException eMBFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen ); -#endif - -#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0 -eMBException eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen ); -#endif - -#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0 -eMBException eMBFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen ); -#endif - -#ifdef __cplusplus -PR_END_EXTERN_C -#endif -#endif
--- a/Modbus/mbfunccoils.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbfunccoils.c,v 1.8 2007/02/18 23:47:16 wolti Exp $ - */ - -/* ----------------------- System includes ----------------------------------*/ -#include "stdlib.h" -#include "string.h" - -/* ----------------------- Platform includes --------------------------------*/ -#include "port.h" - -/* ----------------------- Modbus includes ----------------------------------*/ -#include "mb.h" -#include "mbframe.h" -#include "mbproto.h" -#include "mbconfig.h" - -/* ----------------------- Defines ------------------------------------------*/ -#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF ) -#define MB_PDU_FUNC_READ_COILCNT_OFF ( MB_PDU_DATA_OFF + 2 ) -#define MB_PDU_FUNC_READ_SIZE ( 4 ) -#define MB_PDU_FUNC_READ_COILCNT_MAX ( 0x07D0 ) - -#define MB_PDU_FUNC_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF ) -#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 ) -#define MB_PDU_FUNC_WRITE_MUL_COILCNT_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_COILCNT_MAX ( 0x07B0 ) - -/* ----------------------- Static functions ---------------------------------*/ -eMBException prveMBError2Exception( eMBErrorCode eErrorCode ); - -/* ----------------------- Start implementation -----------------------------*/ - -#if MB_FUNC_READ_COILS_ENABLED > 0 - -eMBException -eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen ) -{ - USHORT usRegAddress; - USHORT usCoilCount; - UCHAR ucNBytes; - 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++; - - usCoilCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] << 8 ); - usCoilCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF + 1] ); - - /* Check if the number of registers to read is valid. If not - * return Modbus illegal data value exception. - */ - if( ( usCoilCount >= 1 ) && - ( usCoilCount < MB_PDU_FUNC_READ_COILCNT_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_COILS; - *usLen += 1; - - /* Test if the quantity of coils is a multiple of 8. If not last - * byte is only partially field with unused coils set to zero. */ - if( ( usCoilCount & 0x0007 ) != 0 ) - { - ucNBytes = ( UCHAR )( usCoilCount / 8 + 1 ); - } - else - { - ucNBytes = ( UCHAR )( usCoilCount / 8 ); - } - *pucFrameCur++ = ucNBytes; - *usLen += 1; - - eRegStatus = - eMBRegCoilsCB( pucFrameCur, usRegAddress, usCoilCount, - MB_REG_READ ); - - /* 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 += ucNBytes;; - } - } - else - { - eStatus = MB_EX_ILLEGAL_DATA_VALUE; - } - } - else - { - /* Can't be a valid read coil register request because the length - * is incorrect. */ - eStatus = MB_EX_ILLEGAL_DATA_VALUE; - } - return eStatus; -} - -#if MB_FUNC_WRITE_COIL_ENABLED > 0 -eMBException -eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen ) -{ - USHORT usRegAddress; - UCHAR ucBuf[2]; - - 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_ADDR_OFF] << 8 ); - usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] ); - usRegAddress++; - - if( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF + 1] == 0x00 ) && - ( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF ) || - ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0x00 ) ) ) - { - ucBuf[1] = 0; - if( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF ) - { - ucBuf[0] = 1; - } - else - { - ucBuf[0] = 0; - } - eRegStatus = - eMBRegCoilsCB( &ucBuf[0], usRegAddress, 1, MB_REG_WRITE ); - - /* 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 write coil register request because the length - * is incorrect. */ - eStatus = MB_EX_ILLEGAL_DATA_VALUE; - } - return eStatus; -} - -#endif - -#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0 -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; -} - -#endif - -#endif
--- a/Modbus/mbfuncdiag.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbfuncdiag.c,v 1.3 2006/12/07 22:10:34 wolti Exp $ - */
--- a/Modbus/mbfuncdisc.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ - /* - * FreeRTOS Modbus Libary: A Modbus serial implementation for FreeRTOS - * Copyright (C) 2006 Christian Walter <wolti@sil.at> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - - -/* ----------------------- System includes ----------------------------------*/ -#include "stdlib.h" -#include "string.h" - -/* ----------------------- Platform includes --------------------------------*/ -#include "port.h" - -/* ----------------------- Modbus includes ----------------------------------*/ -#include "mb.h" -#include "mbframe.h" -#include "mbproto.h" -#include "mbconfig.h" - -/* ----------------------- Defines ------------------------------------------*/ -#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF ) -#define MB_PDU_FUNC_READ_DISCCNT_OFF ( MB_PDU_DATA_OFF + 2 ) -#define MB_PDU_FUNC_READ_SIZE ( 4 ) -#define MB_PDU_FUNC_READ_DISCCNT_MAX ( 0x07D0 ) - -/* ----------------------- Static functions ---------------------------------*/ -eMBException prveMBError2Exception( eMBErrorCode eErrorCode ); - -/* ----------------------- Start implementation -----------------------------*/ - -#if MB_FUNC_READ_COILS_ENABLED > 0 - -eMBException -eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen ) -{ - USHORT usRegAddress; - USHORT usDiscreteCnt; - UCHAR ucNBytes; - 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++; - - usDiscreteCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF] << 8 ); - usDiscreteCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF + 1] ); - - /* Check if the number of registers to read is valid. If not - * return Modbus illegal data value exception. - */ - if( ( usDiscreteCnt >= 1 ) && - ( usDiscreteCnt < MB_PDU_FUNC_READ_DISCCNT_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_DISCRETE_INPUTS; - *usLen += 1; - - /* Test if the quantity of coils is a multiple of 8. If not last - * byte is only partially field with unused coils set to zero. */ - if( ( usDiscreteCnt & 0x0007 ) != 0 ) - { - ucNBytes = ( UCHAR ) ( usDiscreteCnt / 8 + 1 ); - } - else - { - ucNBytes = ( UCHAR ) ( usDiscreteCnt / 8 ); - } - *pucFrameCur++ = ucNBytes; - *usLen += 1; - - eRegStatus = - eMBRegDiscreteCB( pucFrameCur, usRegAddress, usDiscreteCnt ); - - /* 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 += ucNBytes;; - } - } - else - { - eStatus = MB_EX_ILLEGAL_DATA_VALUE; - } - } - else - { - /* Can't be a valid read coil register request because the length - * is incorrect. */ - eStatus = MB_EX_ILLEGAL_DATA_VALUE; - } - return eStatus; -} - -#endif
--- a/Modbus/mbfuncholding.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,308 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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.c,v 1.12 2007/02/18 23:48:22 wolti Exp $ - */ - -/* ----------------------- System includes ----------------------------------*/ -#include "stdlib.h" -#include "string.h" - -/* ----------------------- Platform includes --------------------------------*/ -#include "port.h" - -/* ----------------------- Modbus includes ----------------------------------*/ -#include "mb.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_FUNC_WRITE_HOLDING_ENABLED > 0 - -eMBException -eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen ) -{ - USHORT usRegAddress; - 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_ADDR_OFF] << 8 ); - usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] ); - usRegAddress++; - - /* Make callback to update the value. */ - eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF], - usRegAddress, 1, MB_REG_WRITE ); - - /* If an error occured convert it into a Modbus exception. */ - if( eRegStatus != MB_ENOERR ) - { - eStatus = prveMBError2Exception( eRegStatus ); - } - } - else - { - /* Can't be a valid request because the length is incorrect. */ - eStatus = MB_EX_ILLEGAL_DATA_VALUE; - } - return eStatus; -} -#endif - -#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0 -eMBException -eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen ) -{ - USHORT usRegAddress; - USHORT usRegCount; - UCHAR ucRegByteCount; - - eMBException eStatus = MB_EX_NONE; - eMBErrorCode eRegStatus; - - if( *usLen >= ( MB_PDU_FUNC_WRITE_MUL_SIZE_MIN + 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++; - - usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF] << 8 ); - usRegCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF + 1] ); - - ucRegByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF]; - - if( ( usRegCount >= 1 ) && - ( usRegCount <= MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX ) && - ( ucRegByteCount == ( UCHAR ) ( 2 * usRegCount ) ) ) - { - /* Make callback to update the register values. */ - eRegStatus = - eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF], - usRegAddress, usRegCount, 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 request because the length is incorrect. */ - eStatus = MB_EX_ILLEGAL_DATA_VALUE; - } - return eStatus; -} -#endif - -#if MB_FUNC_READ_HOLDING_ENABLED > 0 - -eMBException -eMBFuncReadHoldingRegister( 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 -eMBFuncReadWriteMultipleHoldingRegister( 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
--- a/Modbus/mbfuncinput.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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.c,v 1.10 2007/09/12 10:15:56 wolti Exp $ - */ - -/* ----------------------- System includes ----------------------------------*/ -#include "stdlib.h" -#include "string.h" - -/* ----------------------- Platform includes --------------------------------*/ -#include "port.h" - -/* ----------------------- Modbus includes ----------------------------------*/ -#include "mb.h" -#include "mbframe.h" -#include "mbproto.h" -#include "mbconfig.h" - -/* ----------------------- Defines ------------------------------------------*/ -#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF ) -#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_READ_RSP_BYTECNT_OFF ( MB_PDU_DATA_OFF ) - -/* ----------------------- Static functions ---------------------------------*/ -eMBException prveMBError2Exception( eMBErrorCode eErrorCode ); - -/* ----------------------- Start implementation -----------------------------*/ -#if MB_FUNC_READ_INPUT_ENABLED > 0 - -eMBException -eMBFuncReadInputRegister( 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_INPUT_REGISTER; - *usLen += 1; - - /* Second byte in the response contain the number of bytes. */ - *pucFrameCur++ = ( UCHAR )( usRegCount * 2 ); - *usLen += 1; - - eRegStatus = eMBRegInputCB( pucFrameCur, usRegAddress, usRegCount ); - - /* 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 read input register request because the length - * is incorrect. */ - eStatus = MB_EX_ILLEGAL_DATA_VALUE; - } - return eStatus; -} - -#endif
--- a/Modbus/mbfuncother.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbfuncother.c,v 1.8 2006/12/07 22:10:34 wolti Exp $ - */ - -/* ----------------------- System includes ----------------------------------*/ -#include "stdlib.h" -#include "string.h" - -/* ----------------------- Platform includes --------------------------------*/ -#include "port.h" - -/* ----------------------- Modbus includes ----------------------------------*/ -#include "mb.h" -#include "mbframe.h" -#include "mbproto.h" -#include "mbconfig.h" - -#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0 - -/* ----------------------- Static variables ---------------------------------*/ -static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF]; -static USHORT usMBSlaveIDLen; - -/* ----------------------- Start implementation -----------------------------*/ - -eMBErrorCode -eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning, - UCHAR const *pucAdditional, USHORT usAdditionalLen ) -{ - eMBErrorCode eStatus = MB_ENOERR; - - /* the first byte and second byte in the buffer is reserved for - * the parameter ucSlaveID and the running flag. The rest of - * the buffer is available for additional data. */ - if( usAdditionalLen + 2 < MB_FUNC_OTHER_REP_SLAVEID_BUF ) - { - usMBSlaveIDLen = 0; - ucMBSlaveID[usMBSlaveIDLen++] = ucSlaveID; - ucMBSlaveID[usMBSlaveIDLen++] = ( UCHAR )( xIsRunning ? 0xFF : 0x00 ); - if( usAdditionalLen > 0 ) - { - memcpy( &ucMBSlaveID[usMBSlaveIDLen], pucAdditional, - ( size_t )usAdditionalLen ); - usMBSlaveIDLen += usAdditionalLen; - } - } - else - { - eStatus = MB_ENORES; - } - return eStatus; -} - -eMBException -eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen ) -{ - memcpy( &pucFrame[MB_PDU_DATA_OFF], &ucMBSlaveID[0], ( size_t )usMBSlaveIDLen ); - *usLen = ( USHORT )( MB_PDU_DATA_OFF + usMBSlaveIDLen ); - return MB_EX_NONE; -} - -#endif
--- a/Modbus/mbport.h Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbport.h,v 1.17 2006/12/07 22:10:34 wolti Exp $ - */ - -#ifndef _MB_PORT_H -#define _MB_PORT_H - -#ifdef __cplusplus -PR_BEGIN_EXTERN_C -#endif - -/* ----------------------- Type definitions ---------------------------------*/ - -typedef enum -{ - EV_READY, /*!< Startup finished. */ - EV_FRAME_RECEIVED, /*!< Frame received. */ - EV_EXECUTE, /*!< Execute function. */ - EV_FRAME_SENT /*!< Frame sent. */ -} eMBEventType; - -/*! \ingroup modbus - * \brief Parity used for characters in serial mode. - * - * The parity which should be applied to the characters sent over the serial - * link. Please note that this values are actually passed to the porting - * layer and therefore not all parity modes might be available. - */ -typedef enum -{ - MB_PAR_NONE, /*!< No parity. */ - MB_PAR_ODD, /*!< Odd parity. */ - MB_PAR_EVEN /*!< Even parity. */ -} eMBParity; - -/* ----------------------- Supporting functions -----------------------------*/ -BOOL xMBPortEventInit( void ); - -BOOL xMBPortEventPost( eMBEventType eEvent ); - -BOOL xMBPortEventGet( /*@out@ */ eMBEventType * eEvent ); - -/* ----------------------- Serial port functions ----------------------------*/ - -BOOL xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate, - UCHAR ucDataBits, eMBParity eParity ); - -void vMBPortClose( void ); - -void xMBPortSerialClose( void ); - -void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ); - -INLINE BOOL xMBPortSerialGetByte( CHAR * pucByte ); - -INLINE BOOL xMBPortSerialPutByte( CHAR ucByte ); - -/* ----------------------- Timers functions ---------------------------------*/ -BOOL xMBPortTimersInit( USHORT usTimeOut50us ); - -void xMBPortTimersClose( void ); - -INLINE void vMBPortTimersEnable( void ); - -INLINE void vMBPortTimersDisable( void ); - -/* ----------------------- Callback for the protocol stack ------------------*/ - -/*! - * \brief Callback function for the porting layer when a new byte is - * available. - * - * Depending upon the mode this callback function is used by the RTU or - * ASCII transmission layers. In any case a call to xMBPortSerialGetByte() - * must immediately return a new character. - * - * \return <code>TRUE</code> if a event was posted to the queue because - * a new byte was received. The port implementation should wake up the - * tasks which are currently blocked on the eventqueue. - */ -extern BOOL( *pxMBFrameCBByteReceived ) ( void ); - -extern BOOL( *pxMBFrameCBTransmitterEmpty ) ( void ); - -extern BOOL( *pxMBPortCBTimerExpired ) ( void ); - -/* ----------------------- TCP port functions -------------------------------*/ -BOOL xMBTCPPortInit( USHORT usTCPPort ); - -void vMBTCPPortClose( void ); - -void vMBTCPPortDisable( void ); - -BOOL xMBTCPPortGetRequest( UCHAR **ppucMBTCPFrame, USHORT * usTCPLength ); - -BOOL xMBTCPPortSendResponse( const UCHAR *pucMBTCPFrame, USHORT usTCPLength ); - -#ifdef __cplusplus -PR_END_EXTERN_C -#endif -#endif
--- a/Modbus/mbproto.h Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbproto.h,v 1.14 2006/12/07 22:10:34 wolti Exp $ - */ - -#ifndef _MB_PROTO_H -#define _MB_PROTO_H - -#ifdef __cplusplus -PR_BEGIN_EXTERN_C -#endif -/* ----------------------- Defines ------------------------------------------*/ -#define MB_ADDRESS_BROADCAST ( 0 ) /*! Modbus broadcast address. */ -#define MB_ADDRESS_MIN ( 1 ) /*! Smallest possible slave address. */ -#define MB_ADDRESS_MAX ( 247 ) /*! Biggest possible slave address. */ -#define MB_FUNC_NONE ( 0 ) -#define MB_FUNC_READ_COILS ( 1 ) -#define MB_FUNC_READ_DISCRETE_INPUTS ( 2 ) -#define MB_FUNC_WRITE_SINGLE_COIL ( 5 ) -#define MB_FUNC_WRITE_MULTIPLE_COILS ( 15 ) -#define MB_FUNC_READ_HOLDING_REGISTER ( 3 ) -#define MB_FUNC_READ_INPUT_REGISTER ( 4 ) -#define MB_FUNC_WRITE_REGISTER ( 6 ) -#define MB_FUNC_WRITE_MULTIPLE_REGISTERS ( 16 ) -#define MB_FUNC_READWRITE_MULTIPLE_REGISTERS ( 23 ) -#define MB_FUNC_DIAG_READ_EXCEPTION ( 7 ) -#define MB_FUNC_DIAG_DIAGNOSTIC ( 8 ) -#define MB_FUNC_DIAG_GET_COM_EVENT_CNT ( 11 ) -#define MB_FUNC_DIAG_GET_COM_EVENT_LOG ( 12 ) -#define MB_FUNC_OTHER_REPORT_SLAVEID ( 17 ) -#define MB_FUNC_ERROR ( 128 ) -/* ----------------------- Type definitions ---------------------------------*/ - typedef enum -{ - MB_EX_NONE = 0x00, - MB_EX_ILLEGAL_FUNCTION = 0x01, - MB_EX_ILLEGAL_DATA_ADDRESS = 0x02, - MB_EX_ILLEGAL_DATA_VALUE = 0x03, - MB_EX_SLAVE_DEVICE_FAILURE = 0x04, - MB_EX_ACKNOWLEDGE = 0x05, - MB_EX_SLAVE_BUSY = 0x06, - MB_EX_MEMORY_PARITY_ERROR = 0x08, - MB_EX_GATEWAY_PATH_FAILED = 0x0A, - MB_EX_GATEWAY_TGT_FAILED = 0x0B -} eMBException; - -typedef eMBException( *pxMBFunctionHandler ) ( UCHAR * pucFrame, USHORT * pusLength ); - -typedef struct -{ - UCHAR ucFunctionCode; - pxMBFunctionHandler pxHandler; -} xMBFunctionHandler; - -#ifdef __cplusplus -PR_END_EXTERN_C -#endif -#endif
--- a/Modbus/mbrtu.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,361 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbrtu.c,v 1.18 2007/09/12 10:15:56 wolti Exp $ - */ - -/* ----------------------- System includes ----------------------------------*/ -#include "stdlib.h" -#include "string.h" - -/* ----------------------- Platform includes --------------------------------*/ -#include "port.h" - -/* ----------------------- Modbus includes ----------------------------------*/ -#include "mb.h" -#include "mbrtu.h" -#include "mbframe.h" - -#include "mbcrc.h" -#include "mbport.h" - -/* ----------------------- Defines ------------------------------------------*/ -#define MB_SER_PDU_SIZE_MIN 4 /*!< Minimum size of a Modbus RTU frame. */ -#define MB_SER_PDU_SIZE_MAX 256 /*!< Maximum size of a Modbus RTU frame. */ -#define MB_SER_PDU_SIZE_CRC 2 /*!< Size of CRC field in PDU. */ -#define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */ -#define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */ - -/* ----------------------- Type definitions ---------------------------------*/ -typedef enum -{ - STATE_RX_INIT, /*!< Receiver is in initial state. */ - STATE_RX_IDLE, /*!< Receiver is in idle state. */ - STATE_RX_RCV, /*!< Frame is beeing received. */ - STATE_RX_ERROR /*!< If the frame is invalid. */ -} eMBRcvState; - -typedef enum -{ - STATE_TX_IDLE, /*!< Transmitter is in idle state. */ - STATE_TX_XMIT /*!< Transmitter is in transfer state. */ -} eMBSndState; - -/* ----------------------- Static variables ---------------------------------*/ -static volatile eMBSndState eSndState; -static volatile eMBRcvState eRcvState; - -volatile UCHAR ucRTUBuf[MB_SER_PDU_SIZE_MAX]; - -static volatile UCHAR *pucSndBufferCur; -static volatile USHORT usSndBufferCount; - -static volatile USHORT usRcvBufferPos; - -/* ----------------------- Start implementation -----------------------------*/ -eMBErrorCode -eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ) -{ - eMBErrorCode eStatus = MB_ENOERR; - ULONG usTimerT35_50us; - - ( void )ucSlaveAddress; - ENTER_CRITICAL_SECTION( ); - - /* Modbus RTU uses 8 Databits. */ - if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE ) - { - eStatus = MB_EPORTERR; - } - else - { - /* If baudrate > 19200 then we should use the fixed timer values - * t35 = 1750us. Otherwise t35 must be 3.5 times the character time. - */ - if( ulBaudRate > 19200 ) - { - usTimerT35_50us = 35; /* 1800us. */ - } - else - { - /* The timer reload value for a character is given by: - * - * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 ) - * = 11 * Ticks_per_1s / Baudrate - * = 220000 / Baudrate - * The reload for t3.5 is 1.5 times this value and similary - * for t3.5. - */ - usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate ); - } - if( xMBPortTimersInit( ( USHORT ) usTimerT35_50us ) != TRUE ) - { - eStatus = MB_EPORTERR; - } - } - EXIT_CRITICAL_SECTION( ); - - return eStatus; -} - -void -eMBRTUStart( void ) -{ - ENTER_CRITICAL_SECTION( ); - /* Initially the receiver is in the state STATE_RX_INIT. we start - * the timer and if no character is received within t3.5 we change - * to STATE_RX_IDLE. This makes sure that we delay startup of the - * modbus protocol stack until the bus is free. - */ - eRcvState = STATE_RX_INIT; - vMBPortSerialEnable( TRUE, FALSE ); - vMBPortTimersEnable( ); - - EXIT_CRITICAL_SECTION( ); -} - -void -eMBRTUStop( void ) -{ - ENTER_CRITICAL_SECTION( ); - vMBPortSerialEnable( FALSE, FALSE ); - vMBPortTimersDisable( ); - EXIT_CRITICAL_SECTION( ); -} - -eMBErrorCode -eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength ) -{ - BOOL xFrameReceived = FALSE; - eMBErrorCode eStatus = MB_ENOERR; - - ENTER_CRITICAL_SECTION( ); - assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX ); - - /* Length and CRC check */ - if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN ) - && ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0 ) ) - { - /* Save the address field. All frames are passed to the upper layed - * and the decision if a frame is used is done there. - */ - *pucRcvAddress = ucRTUBuf[MB_SER_PDU_ADDR_OFF]; - - /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus - * size of address field and CRC checksum. - */ - *pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC ); - - /* Return the start of the Modbus PDU to the caller. */ - *pucFrame = ( UCHAR * ) & ucRTUBuf[MB_SER_PDU_PDU_OFF]; - xFrameReceived = TRUE; - - // Added by Cam - // Now that the poll routine knows about the received frame, - // clear the receive buffer position ready for the next frame received - //usRcvBufferPos = 0; - - } - else - { - eStatus = MB_EIO; - } - - EXIT_CRITICAL_SECTION( ); - return eStatus; -} - -eMBErrorCode -eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength ) -{ - eMBErrorCode eStatus = MB_ENOERR; - USHORT usCRC16; - - ENTER_CRITICAL_SECTION( ); - - /* Check if the receiver is still in idle state. If not we where to - * slow with processing the received frame and the master sent another - * frame on the network. We have to abort sending the frame. - */ - if( eRcvState == STATE_RX_IDLE ) - { - /* First byte before the Modbus-PDU is the slave address. */ - pucSndBufferCur = ( UCHAR * ) pucFrame - 1; - usSndBufferCount = 1; - - /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */ - pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress; - usSndBufferCount += usLength; - - /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */ - usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount ); - ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF ); - ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 ); - - /* Activate the transmitter. */ - eSndState = STATE_TX_XMIT; - vMBPortSerialEnable( FALSE, TRUE ); - } - else - { - eStatus = MB_EIO; - } - EXIT_CRITICAL_SECTION( ); - return eStatus; -} - -BOOL -xMBRTUReceiveFSM( void ) -{ - BOOL xTaskNeedSwitch = FALSE; - UCHAR ucByte; - - assert( eSndState == STATE_TX_IDLE ); - - /* Always read the character. */ - ( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte ); - - switch ( eRcvState ) - { - /* If we have received a character in the init state we have to - * wait until the frame is finished. - */ - case STATE_RX_INIT: - vMBPortTimersEnable( ); - break; - - /* In the error state we wait until all characters in the - * damaged frame are transmitted. - */ - case STATE_RX_ERROR: - vMBPortTimersEnable( ); - break; - - /* In the idle state we wait for a new character. If a character - * is received the t1.5 and t3.5 timers are started and the - * receiver is in the state STATE_RX_RECEIVCE. - */ - case STATE_RX_IDLE: - usRcvBufferPos = 0; //cam will comment this - ucRTUBuf[usRcvBufferPos++] = ucByte; - eRcvState = STATE_RX_RCV; - - /* Enable t3.5 timers. */ - vMBPortTimersEnable( ); - break; - - /* We are currently receiving a frame. Reset the timer after - * every character received. If more than the maximum possible - * number of bytes in a modbus frame is received the frame is - * ignored. - */ - case STATE_RX_RCV: - if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX ) - { - ucRTUBuf[usRcvBufferPos++] = ucByte; - } - else - { - eRcvState = STATE_RX_ERROR; - } - vMBPortTimersEnable( ); - break; - } - return xTaskNeedSwitch; -} - -BOOL -xMBRTUTransmitFSM( void ) -{ - BOOL xNeedPoll = FALSE; - - assert( eRcvState == STATE_RX_IDLE ); - - switch ( eSndState ) - { - /* We should not get a transmitter event if the transmitter is in - * idle state. */ - case STATE_TX_IDLE: - /* enable receiver/disable transmitter. */ - vMBPortSerialEnable( TRUE, FALSE ); - break; - - case STATE_TX_XMIT: - /* check if we are finished. */ - if( usSndBufferCount != 0 ) - { - xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur ); - pucSndBufferCur++; /* next byte in sendbuffer. */ - usSndBufferCount--; - } - else - { - xNeedPoll = xMBPortEventPost( EV_FRAME_SENT ); - /* Disable transmitter. This prevents another transmit buffer - * empty interrupt. */ - vMBPortSerialEnable( TRUE, FALSE ); - eSndState = STATE_TX_IDLE; - } - break; - } - - return xNeedPoll; -} - -BOOL -xMBRTUTimerT35Expired( void ) -{ - BOOL xNeedPoll = FALSE; - - switch ( eRcvState ) - { - /* Timer t35 expired. Startup phase is finished. */ - case STATE_RX_INIT: - xNeedPoll = xMBPortEventPost( EV_READY ); - break; - - /* A frame was received and t35 expired. Notify the listener that - * a new frame was received. */ - case STATE_RX_RCV: - xNeedPoll = xMBPortEventPost( EV_FRAME_RECEIVED ); - break; - - /* An error occured while receiving the frame. */ - case STATE_RX_ERROR: - break; - - /* Function called in an illegal state. */ - default: - assert( ( eRcvState == STATE_RX_INIT ) || - ( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) ); - } - - vMBPortTimersDisable( ); - eRcvState = STATE_RX_IDLE; - - return xNeedPoll; -}
--- a/Modbus/mbrtu.h Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbrtu.h,v 1.9 2006/12/07 22:10:34 wolti Exp $ - */ - -#ifndef _MB_RTU_H -#define _MB_RTU_H - -#ifdef __cplusplus -PR_BEGIN_EXTERN_C -#endif - eMBErrorCode eMBRTUInit( UCHAR slaveAddress, UCHAR ucPort, ULONG ulBaudRate, - eMBParity eParity ); -void eMBRTUStart( void ); -void eMBRTUStop( void ); -eMBErrorCode eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength ); -eMBErrorCode eMBRTUSend( UCHAR slaveAddress, const UCHAR * pucFrame, USHORT usLength ); -BOOL xMBRTUReceiveFSM( void ); -BOOL xMBRTUTransmitFSM( void ); -BOOL xMBRTUTimerT15Expired( void ); -BOOL xMBRTUTimerT35Expired( void ); - -#ifdef __cplusplus -PR_END_EXTERN_C -#endif -#endif
--- a/Modbus/mbutils.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbutils.c,v 1.6 2007/02/18 23:49:07 wolti Exp $ - */ - -/* ----------------------- System includes ----------------------------------*/ -#include "stdlib.h" -#include "string.h" - -/* ----------------------- Platform includes --------------------------------*/ -#include "port.h" - -/* ----------------------- Modbus includes ----------------------------------*/ -#include "mb.h" -#include "mbproto.h" - -/* ----------------------- Defines ------------------------------------------*/ -#define BITS_UCHAR 8U - -/* ----------------------- Start implementation -----------------------------*/ -void -xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits, - UCHAR ucValue ) -{ - USHORT usWordBuf; - USHORT usMask; - USHORT usByteOffset; - USHORT usNPreBits; - USHORT usValue = ucValue; - - assert( ucNBits <= 8 ); - assert( ( size_t )BITS_UCHAR == sizeof( UCHAR ) * 8 ); - - /* Calculate byte offset for first byte containing the bit values starting - * at usBitOffset. */ - usByteOffset = ( USHORT )( ( usBitOffset ) / BITS_UCHAR ); - - /* How many bits precede our bits to set. */ - usNPreBits = ( USHORT )( usBitOffset - usByteOffset * BITS_UCHAR ); - - /* Move bit field into position over bits to set */ - usValue <<= usNPreBits; - - /* Prepare a mask for setting the new bits. */ - usMask = ( USHORT )( ( 1 << ( USHORT ) ucNBits ) - 1 ); - usMask <<= usBitOffset - usByteOffset * BITS_UCHAR; - - /* copy bits into temporary storage. */ - usWordBuf = ucByteBuf[usByteOffset]; - usWordBuf |= ucByteBuf[usByteOffset + 1] << BITS_UCHAR; - - /* Zero out bit field bits and then or value bits into them. */ - usWordBuf = ( USHORT )( ( usWordBuf & ( ~usMask ) ) | usValue ); - - /* move bits back into storage */ - ucByteBuf[usByteOffset] = ( UCHAR )( usWordBuf & 0xFF ); - ucByteBuf[usByteOffset + 1] = ( UCHAR )( usWordBuf >> BITS_UCHAR ); -} - -UCHAR -xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits ) -{ - USHORT usWordBuf; - USHORT usMask; - USHORT usByteOffset; - USHORT usNPreBits; - - /* Calculate byte offset for first byte containing the bit values starting - * at usBitOffset. */ - usByteOffset = ( USHORT )( ( usBitOffset ) / BITS_UCHAR ); - - /* How many bits precede our bits to set. */ - usNPreBits = ( USHORT )( usBitOffset - usByteOffset * BITS_UCHAR ); - - /* Prepare a mask for setting the new bits. */ - usMask = ( USHORT )( ( 1 << ( USHORT ) ucNBits ) - 1 ); - - /* copy bits into temporary storage. */ - usWordBuf = ucByteBuf[usByteOffset]; - usWordBuf |= ucByteBuf[usByteOffset + 1] << BITS_UCHAR; - - /* throw away unneeded bits. */ - usWordBuf >>= usNPreBits; - - /* mask away bits above the requested bitfield. */ - usWordBuf &= usMask; - - return ( UCHAR ) usWordBuf; -} - -eMBException -prveMBError2Exception( eMBErrorCode eErrorCode ) -{ - eMBException eStatus; - - switch ( eErrorCode ) - { - case MB_ENOERR: - eStatus = MB_EX_NONE; - break; - - case MB_ENOREG: - eStatus = MB_EX_ILLEGAL_DATA_ADDRESS; - break; - - case MB_ETIMEDOUT: - eStatus = MB_EX_SLAVE_BUSY; - break; - - default: - eStatus = MB_EX_SLAVE_DEVICE_FAILURE; - break; - } - - return eStatus; -}
--- a/Modbus/mbutils.h Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. - * Copyright (c) 2006 Christian Walter <wolti@sil.at> - * 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: mbutils.h,v 1.5 2006/12/07 22:10:34 wolti Exp $ - */ - -#ifndef _MB_UTILS_H -#define _MB_UTILS_H - -#ifdef __cplusplus -PR_BEGIN_EXTERN_C -#endif -/*! \defgroup modbus_utils Utilities - * - * This module contains some utility functions which can be used by - * the application. It includes some special functions for working with - * bitfields backed by a character array buffer. - * - */ -/*! \addtogroup modbus_utils - * @{ - */ -/*! \brief Function to set bits in a byte buffer. - * - * This function allows the efficient use of an array to implement bitfields. - * The array used for storing the bits must always be a multiple of two - * bytes. Up to eight bits can be set or cleared in one operation. - * - * \param ucByteBuf A buffer where the bit values are stored. Must be a - * multiple of 2 bytes. No length checking is performed and if - * usBitOffset / 8 is greater than the size of the buffer memory contents - * is overwritten. - * \param usBitOffset The starting address of the bits to set. The first - * bit has the offset 0. - * \param ucNBits Number of bits to modify. The value must always be smaller - * than 8. - * \param ucValues Thew new values for the bits. The value for the first bit - * starting at <code>usBitOffset</code> is the LSB of the value - * <code>ucValues</code> - * - * \code - * ucBits[2] = {0, 0}; - * - * // Set bit 4 to 1 (read: set 1 bit starting at bit offset 4 to value 1) - * xMBUtilSetBits( ucBits, 4, 1, 1 ); - * - * // Set bit 7 to 1 and bit 8 to 0. - * xMBUtilSetBits( ucBits, 7, 2, 0x01 ); - * - * // Set bits 8 - 11 to 0x05 and bits 12 - 15 to 0x0A; - * xMBUtilSetBits( ucBits, 8, 8, 0x5A); - * \endcode - */ -void xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset, - UCHAR ucNBits, UCHAR ucValues ); - -/*! \brief Function to read bits in a byte buffer. - * - * This function is used to extract up bit values from an array. Up to eight - * bit values can be extracted in one step. - * - * \param ucByteBuf A buffer where the bit values are stored. - * \param usBitOffset The starting address of the bits to set. The first - * bit has the offset 0. - * \param ucNBits Number of bits to modify. The value must always be smaller - * than 8. - * - * \code - * UCHAR ucBits[2] = {0, 0}; - * UCHAR ucResult; - * - * // Extract the bits 3 - 10. - * ucResult = xMBUtilGetBits( ucBits, 3, 8 ); - * \endcode - */ -UCHAR xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset, - UCHAR ucNBits ); - -/*! @} */ - -#ifdef __cplusplus -PR_END_EXTERN_C -#endif -#endif
--- a/Modbus/port.h Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * FreeModbus Libary: BARE Port - * Copyright (C) 2006 Christian Walter <wolti@sil.at> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * File: $Id: port.h,v 1.1 2006/08/22 21:35:13 wolti Exp $ - */ - -#ifndef _PORT_H -#define _PORT_H - -#include <assert.h> -#include <inttypes.h> -#include "mbed.h" //stanley -#define INLINE //inline -#define PR_BEGIN_EXTERN_C //extern "C" { -#define PR_END_EXTERN_C //} - -#define ENTER_CRITICAL_SECTION( ) __disable_irq() //stanley -#define EXIT_CRITICAL_SECTION( ) __enable_irq() //stanley - -typedef uint8_t BOOL; - -typedef unsigned char UCHAR; -typedef char CHAR; - -typedef uint16_t USHORT; -typedef int16_t SHORT; - -typedef uint32_t ULONG; -typedef int32_t LONG; - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/port/port.h Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,54 @@ +/* + * FreeModbus Libary: BARE Port + * Copyright (C) 2006 Christian Walter <wolti@sil.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * File: $Id: port.h,v 1.1 2006/08/22 21:35:13 wolti Exp $ + */ + +#ifndef _PORT_H +#define _PORT_H + +#include <assert.h> +#include <inttypes.h> +#include "mbed.h" //stanley +#define INLINE //inline +#define PR_BEGIN_EXTERN_C //extern "C" { +#define PR_END_EXTERN_C //} + +#define ENTER_CRITICAL_SECTION( ) __disable_irq() //stanley +#define EXIT_CRITICAL_SECTION( ) __enable_irq() //stanley + +typedef uint8_t BOOL; + +typedef unsigned char UCHAR; +typedef char CHAR; + +typedef uint16_t USHORT; +typedef int16_t SHORT; + +typedef uint32_t ULONG; +typedef int32_t LONG; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/port/portevent.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,58 @@ +/* + * FreeModbus Libary: BARE Port + * Copyright (C) 2006 Christian Walter <wolti@sil.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * File: $Id: portevent.c,v 1.1 2006/08/22 21:35:13 wolti Exp $ + */ + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbport.h" + +/* ----------------------- Variables ----------------------------------------*/ +static eMBEventType eQueuedEvent; +static BOOL xEventInQueue; + +/* ----------------------- Start implementation -----------------------------*/ +BOOL +xMBPortEventInit( void ) +{ + xEventInQueue = FALSE; + return TRUE; +} + +BOOL +xMBPortEventPost( eMBEventType eEvent ) +{ + xEventInQueue = TRUE; + eQueuedEvent = eEvent; + return TRUE; +} + +BOOL +xMBPortEventGet( eMBEventType * eEvent ) +{ + BOOL xEventHappened = FALSE; + + if( xEventInQueue ) + { + *eEvent = eQueuedEvent; + xEventInQueue = FALSE; + xEventHappened = TRUE; + } + return xEventHappened; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/port/portserial.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,140 @@ +/* + * FreeModbus Libary: BARE Port + * Copyright (C) 2006 Christian Walter <wolti@sil.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * File: $Id: portserial.c,v 1.1 2006/08/22 21:35:13 wolti Exp $ + */ + +/* ----------------------- System includes ----------------------------------*/ +#include "mbed.h" // Cam + +/* ----------------------- Platform includes --------------------------------*/ +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbport.h" + + +/* ----------------------- static functions ---------------------------------*/ +static void prvvUARTTxReadyISR( void ); +static void prvvUARTRxISR( void ); + + +/* ----------------------- System Variables ---------------------------------*/ +Serial ser3(PB_10, PC_5); //serial3 +extern Serial pc; +static uint8_t grx_buf=0; + +/* ----------------------- Start implementation -----------------------------*/ +void +vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ) +{ + /* If xRXEnable enable serial receive interrupts. If xTxENable enable + * transmitter empty interrupts. + */ + + + //stanley + ENTER_CRITICAL_SECTION( ); + + + ser3.attach(NULL); //close all + + if(xRxEnable) + ser3.attach(&prvvUARTRxISR,Serial::RxIrq); + + if(xTxEnable) + { + ser3.attach(&prvvUARTTxReadyISR,Serial::TxIrq); + while(!ser3.writeable()); + prvvUARTTxReadyISR(); + } + EXIT_CRITICAL_SECTION( ); + + //if(xTxEnable) + //¤£¥Î¦b³oÃä³]©wser3.write(tx_buf,TX_BUFF_LENGTH,serialTxCBEvent,SERIAL_EVENT_TX_COMPLETE); + + //else + //{ + // ser3.attach(NULL,Serial::RxIrq); //stanley the test result find that this may disable RxIrq and TxIrq so have to enable TxIrq + // ser3.attach(&prvvUARTTxReadyISR,Serial::TxIrq); + //} +} + +BOOL +xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity ) +{ + + ser3.baud(ulBaudRate); //stanley + + + return TRUE; +} + +BOOL +xMBPortSerialPutByte( CHAR ucByte ) +{ + /* Put a byte in the UARTs transmit buffer. This function is called + * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been + * called. */ + + //stanley + ser3.putc( ucByte); + + return TRUE; +} + +BOOL +xMBPortSerialGetByte( CHAR * pucByte ) +{ + /* Return the byte in the UARTs receive buffer. This function is called + * by the protocol stack after pxMBFrameCBByteReceived( ) has been called. + */ + + *pucByte = grx_buf;//stanley + + + + return TRUE; +} + +/* Create an interrupt handler for the transmit buffer empty interrupt + * (or an equivalent) for your target processor. This function should then + * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that + * a new character can be sent. The protocol stack will then call + * xMBPortSerialPutByte( ) to send the character. + */ +static void prvvUARTTxReadyISR( void ) +{ + pxMBFrameCBTransmitterEmpty(); +} + +/* Create an interrupt handler for the receive interrupt for your target + * processor. This function should then call pxMBFrameCBByteReceived( ). The + * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the + * character. + */ +static void prvvUARTRxISR( void ) +{ + if(ser3.readable()) //stanlely RX ISR must contain getc + grx_buf=ser3.getc(); + + pxMBFrameCBByteReceived(); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/port/porttimer.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,79 @@ +/* + * FreeModbus Libary: BARE Port + * Copyright (C) 2006 Christian Walter <wolti@sil.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * File: $Id: porttimer.c,v 1.1 2006/08/22 21:35:13 wolti Exp $ + */ + +/* ----------------------- System includes ----------------------------------*/ +#include "mbed.h" // Cam + +/* ----------------------- Platform includes --------------------------------*/ +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbport.h" +extern DigitalOut testD8; //stanley +/* ----------------------- static functions ---------------------------------*/ +static void prvvTIMERExpiredISR( void ); + +/* ----------------------- System Variables ---------------------------------*/ +Timeout toMBUS; // Cam - mbed timeout +static ULONG usInterval; // Cam - timeout interval in microseconds + +/* ----------------------- Start implementation -----------------------------*/ +BOOL +xMBPortTimersInit( USHORT usTim1Timerout50us ) +{ + usInterval = 50 * usTim1Timerout50us; + return TRUE; +} + + +/*inline*/ void +vMBPortTimersEnable( ) +{ + /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */ + + // Cam - firstly detach from any existing timeout + toMBUS.detach(); + // Cam - now attach the timeout to the prvvTIMERExpiredISR routine + toMBUS.attach_us(&prvvTIMERExpiredISR, usInterval); +} + +/*inline*/ void +vMBPortTimersDisable( ) +{ + /* Disable any pending timers. */ + + // Cam - disable further interrupts by detaching + toMBUS.detach(); +} + +/* Create an ISR which is called whenever the timer has expired. This function + * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that + * the timer has expired. + */ +static void prvvTIMERExpiredISR( void ) +{ + + (void)pxMBPortCBTimerExpired( ); + // Cam - disable further interrupts by detaching + toMBUS.detach(); +} +
--- a/Modbus/portevent.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * FreeModbus Libary: BARE Port - * Copyright (C) 2006 Christian Walter <wolti@sil.at> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * File: $Id: portevent.c,v 1.1 2006/08/22 21:35:13 wolti Exp $ - */ - -/* ----------------------- Modbus includes ----------------------------------*/ -#include "mb.h" -#include "mbport.h" - -/* ----------------------- Variables ----------------------------------------*/ -static eMBEventType eQueuedEvent; -static BOOL xEventInQueue; - -/* ----------------------- Start implementation -----------------------------*/ -BOOL -xMBPortEventInit( void ) -{ - xEventInQueue = FALSE; - return TRUE; -} - -BOOL -xMBPortEventPost( eMBEventType eEvent ) -{ - xEventInQueue = TRUE; - eQueuedEvent = eEvent; - return TRUE; -} - -BOOL -xMBPortEventGet( eMBEventType * eEvent ) -{ - BOOL xEventHappened = FALSE; - - if( xEventInQueue ) - { - *eEvent = eQueuedEvent; - xEventInQueue = FALSE; - xEventHappened = TRUE; - } - return xEventHappened; -}
--- a/Modbus/portserial.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* - * FreeModbus Libary: BARE Port - * Copyright (C) 2006 Christian Walter <wolti@sil.at> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * File: $Id: portserial.c,v 1.1 2006/08/22 21:35:13 wolti Exp $ - */ - -/* ----------------------- System includes ----------------------------------*/ -#include "mbed.h" // Cam - -/* ----------------------- Platform includes --------------------------------*/ -#include "port.h" - -/* ----------------------- Modbus includes ----------------------------------*/ -#include "mb.h" -#include "mbport.h" - - -/* ----------------------- static functions ---------------------------------*/ -static void prvvUARTTxReadyISR( void ); -static void prvvUARTRxISR( void ); - - -/* ----------------------- System Variables ---------------------------------*/ -Serial ser3(PB_10, PC_5); //serial3 -extern Serial pc; -static uint8_t grx_buf=0; - -/* ----------------------- Start implementation -----------------------------*/ -void -vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ) -{ - /* If xRXEnable enable serial receive interrupts. If xTxENable enable - * transmitter empty interrupts. - */ - - - //stanley - ENTER_CRITICAL_SECTION( ); - - - ser3.attach(NULL); //close all - - if(xRxEnable) - ser3.attach(&prvvUARTRxISR,Serial::RxIrq); - - if(xTxEnable) - { - ser3.attach(&prvvUARTTxReadyISR,Serial::TxIrq); - while(!ser3.writeable()); - prvvUARTTxReadyISR(); - } - EXIT_CRITICAL_SECTION( ); - - //if(xTxEnable) - //¤£¥Î¦b³oÃä³]©wser3.write(tx_buf,TX_BUFF_LENGTH,serialTxCBEvent,SERIAL_EVENT_TX_COMPLETE); - - //else - //{ - // ser3.attach(NULL,Serial::RxIrq); //stanley the test result find that this may disable RxIrq and TxIrq so have to enable TxIrq - // ser3.attach(&prvvUARTTxReadyISR,Serial::TxIrq); - //} -} - -BOOL -xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity ) -{ - - ser3.baud(ulBaudRate); //stanley - - - return TRUE; -} - -BOOL -xMBPortSerialPutByte( CHAR ucByte ) -{ - /* Put a byte in the UARTs transmit buffer. This function is called - * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been - * called. */ - - //stanley - ser3.putc( ucByte); - - return TRUE; -} - -BOOL -xMBPortSerialGetByte( CHAR * pucByte ) -{ - /* Return the byte in the UARTs receive buffer. This function is called - * by the protocol stack after pxMBFrameCBByteReceived( ) has been called. - */ - - *pucByte = grx_buf;//stanley - - - - return TRUE; -} - -/* Create an interrupt handler for the transmit buffer empty interrupt - * (or an equivalent) for your target processor. This function should then - * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that - * a new character can be sent. The protocol stack will then call - * xMBPortSerialPutByte( ) to send the character. - */ -static void prvvUARTTxReadyISR( void ) -{ - pxMBFrameCBTransmitterEmpty(); -} - -/* Create an interrupt handler for the receive interrupt for your target - * processor. This function should then call pxMBFrameCBByteReceived( ). The - * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the - * character. - */ -static void prvvUARTRxISR( void ) -{ - if(ser3.readable()) //stanlely RX ISR must contain getc - grx_buf=ser3.getc(); - - pxMBFrameCBByteReceived(); -} - -
--- a/Modbus/porttimer.cpp Thu Mar 30 23:20:29 2017 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * FreeModbus Libary: BARE Port - * Copyright (C) 2006 Christian Walter <wolti@sil.at> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * File: $Id: porttimer.c,v 1.1 2006/08/22 21:35:13 wolti Exp $ - */ - -/* ----------------------- System includes ----------------------------------*/ -#include "mbed.h" // Cam - -/* ----------------------- Platform includes --------------------------------*/ -#include "port.h" - -/* ----------------------- Modbus includes ----------------------------------*/ -#include "mb.h" -#include "mbport.h" -extern DigitalOut testD8; //stanley -/* ----------------------- static functions ---------------------------------*/ -static void prvvTIMERExpiredISR( void ); - -/* ----------------------- System Variables ---------------------------------*/ -Timeout toMBUS; // Cam - mbed timeout -static ULONG usInterval; // Cam - timeout interval in microseconds - -/* ----------------------- Start implementation -----------------------------*/ -BOOL -xMBPortTimersInit( USHORT usTim1Timerout50us ) -{ - usInterval = 50 * usTim1Timerout50us; - return TRUE; -} - - -/*inline*/ void -vMBPortTimersEnable( ) -{ - /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */ - - // Cam - firstly detach from any existing timeout - toMBUS.detach(); - // Cam - now attach the timeout to the prvvTIMERExpiredISR routine - toMBUS.attach_us(&prvvTIMERExpiredISR, usInterval); -} - -/*inline*/ void -vMBPortTimersDisable( ) -{ - /* Disable any pending timers. */ - - // Cam - disable further interrupts by detaching - toMBUS.detach(); -} - -/* Create an ISR which is called whenever the timer has expired. This function - * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that - * the timer has expired. - */ -static void prvvTIMERExpiredISR( void ) -{ - - (void)pxMBPortCBTimerExpired( ); - // Cam - disable further interrupts by detaching - toMBUS.detach(); -} -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/rtu/mbcrc.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,98 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbcrc.c,v 1.7 2007/02/18 23:50:27 wolti Exp $ + */ + +/* ----------------------- Platform includes --------------------------------*/ +#include "port.h" + +static const UCHAR aucCRCHi[] = { + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40 +}; + +static const UCHAR aucCRCLo[] = { + 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, + 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, + 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, + 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, + 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, + 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, + 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, + 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, + 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, + 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, + 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, + 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, + 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, + 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, + 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, + 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, + 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, + 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, + 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, + 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, + 0x41, 0x81, 0x80, 0x40 +}; + +USHORT +usMBCRC16( UCHAR * pucFrame, USHORT usLen ) +{ + UCHAR ucCRCHi = 0xFF; + UCHAR ucCRCLo = 0xFF; + int iIndex; + + while( usLen-- ) + { + iIndex = ucCRCLo ^ *( pucFrame++ ); + ucCRCLo = ( UCHAR )( ucCRCHi ^ aucCRCHi[iIndex] ); + ucCRCHi = aucCRCLo[iIndex]; + } + return ( USHORT )( ucCRCHi << 8 | ucCRCLo ); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/rtu/mbcrc.h Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,36 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbcrc.h,v 1.5 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_CRC_H +#define _MB_CRC_H + +USHORT usMBCRC16( UCHAR * pucFrame, USHORT usLen ); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/rtu/mbrtu.cpp Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,361 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbrtu.c,v 1.18 2007/09/12 10:15:56 wolti Exp $ + */ + +/* ----------------------- System includes ----------------------------------*/ +#include "stdlib.h" +#include "string.h" + +/* ----------------------- Platform includes --------------------------------*/ +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbrtu.h" +#include "mbframe.h" + +#include "mbcrc.h" +#include "mbport.h" + +/* ----------------------- Defines ------------------------------------------*/ +#define MB_SER_PDU_SIZE_MIN 4 /*!< Minimum size of a Modbus RTU frame. */ +#define MB_SER_PDU_SIZE_MAX 256 /*!< Maximum size of a Modbus RTU frame. */ +#define MB_SER_PDU_SIZE_CRC 2 /*!< Size of CRC field in PDU. */ +#define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */ +#define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */ + +/* ----------------------- Type definitions ---------------------------------*/ +typedef enum +{ + STATE_RX_INIT, /*!< Receiver is in initial state. */ + STATE_RX_IDLE, /*!< Receiver is in idle state. */ + STATE_RX_RCV, /*!< Frame is beeing received. */ + STATE_RX_ERROR /*!< If the frame is invalid. */ +} eMBRcvState; + +typedef enum +{ + STATE_TX_IDLE, /*!< Transmitter is in idle state. */ + STATE_TX_XMIT /*!< Transmitter is in transfer state. */ +} eMBSndState; + +/* ----------------------- Static variables ---------------------------------*/ +static volatile eMBSndState eSndState; +static volatile eMBRcvState eRcvState; + +volatile UCHAR ucRTUBuf[MB_SER_PDU_SIZE_MAX]; + +static volatile UCHAR *pucSndBufferCur; +static volatile USHORT usSndBufferCount; + +static volatile USHORT usRcvBufferPos; + +/* ----------------------- Start implementation -----------------------------*/ +eMBErrorCode +eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ) +{ + eMBErrorCode eStatus = MB_ENOERR; + ULONG usTimerT35_50us; + + ( void )ucSlaveAddress; + ENTER_CRITICAL_SECTION( ); + + /* Modbus RTU uses 8 Databits. */ + if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE ) + { + eStatus = MB_EPORTERR; + } + else + { + /* If baudrate > 19200 then we should use the fixed timer values + * t35 = 1750us. Otherwise t35 must be 3.5 times the character time. + */ + if( ulBaudRate > 19200 ) + { + usTimerT35_50us = 35; /* 1800us. */ + } + else + { + /* The timer reload value for a character is given by: + * + * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 ) + * = 11 * Ticks_per_1s / Baudrate + * = 220000 / Baudrate + * The reload for t3.5 is 1.5 times this value and similary + * for t3.5. + */ + usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate ); + } + if( xMBPortTimersInit( ( USHORT ) usTimerT35_50us ) != TRUE ) + { + eStatus = MB_EPORTERR; + } + } + EXIT_CRITICAL_SECTION( ); + + return eStatus; +} + +void +eMBRTUStart( void ) +{ + ENTER_CRITICAL_SECTION( ); + /* Initially the receiver is in the state STATE_RX_INIT. we start + * the timer and if no character is received within t3.5 we change + * to STATE_RX_IDLE. This makes sure that we delay startup of the + * modbus protocol stack until the bus is free. + */ + eRcvState = STATE_RX_INIT; + vMBPortSerialEnable( TRUE, FALSE ); + vMBPortTimersEnable( ); + + EXIT_CRITICAL_SECTION( ); +} + +void +eMBRTUStop( void ) +{ + ENTER_CRITICAL_SECTION( ); + vMBPortSerialEnable( FALSE, FALSE ); + vMBPortTimersDisable( ); + EXIT_CRITICAL_SECTION( ); +} + +eMBErrorCode +eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength ) +{ + BOOL xFrameReceived = FALSE; + eMBErrorCode eStatus = MB_ENOERR; + + ENTER_CRITICAL_SECTION( ); + assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX ); + + /* Length and CRC check */ + if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN ) + && ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0 ) ) + { + /* Save the address field. All frames are passed to the upper layed + * and the decision if a frame is used is done there. + */ + *pucRcvAddress = ucRTUBuf[MB_SER_PDU_ADDR_OFF]; + + /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus + * size of address field and CRC checksum. + */ + *pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC ); + + /* Return the start of the Modbus PDU to the caller. */ + *pucFrame = ( UCHAR * ) & ucRTUBuf[MB_SER_PDU_PDU_OFF]; + xFrameReceived = TRUE; + + // Added by Cam + // Now that the poll routine knows about the received frame, + // clear the receive buffer position ready for the next frame received + //usRcvBufferPos = 0; + + } + else + { + eStatus = MB_EIO; + } + + EXIT_CRITICAL_SECTION( ); + return eStatus; +} + +eMBErrorCode +eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength ) +{ + eMBErrorCode eStatus = MB_ENOERR; + USHORT usCRC16; + + ENTER_CRITICAL_SECTION( ); + + /* Check if the receiver is still in idle state. If not we where to + * slow with processing the received frame and the master sent another + * frame on the network. We have to abort sending the frame. + */ + if( eRcvState == STATE_RX_IDLE ) + { + /* First byte before the Modbus-PDU is the slave address. */ + pucSndBufferCur = ( UCHAR * ) pucFrame - 1; + usSndBufferCount = 1; + + /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */ + pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress; + usSndBufferCount += usLength; + + /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */ + usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount ); + ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF ); + ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 ); + + /* Activate the transmitter. */ + eSndState = STATE_TX_XMIT; + vMBPortSerialEnable( FALSE, TRUE ); + } + else + { + eStatus = MB_EIO; + } + EXIT_CRITICAL_SECTION( ); + return eStatus; +} + +BOOL +xMBRTUReceiveFSM( void ) +{ + BOOL xTaskNeedSwitch = FALSE; + UCHAR ucByte; + + assert( eSndState == STATE_TX_IDLE ); + + /* Always read the character. */ + ( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte ); + + switch ( eRcvState ) + { + /* If we have received a character in the init state we have to + * wait until the frame is finished. + */ + case STATE_RX_INIT: + vMBPortTimersEnable( ); + break; + + /* In the error state we wait until all characters in the + * damaged frame are transmitted. + */ + case STATE_RX_ERROR: + vMBPortTimersEnable( ); + break; + + /* In the idle state we wait for a new character. If a character + * is received the t1.5 and t3.5 timers are started and the + * receiver is in the state STATE_RX_RECEIVCE. + */ + case STATE_RX_IDLE: + usRcvBufferPos = 0; //cam will comment this + ucRTUBuf[usRcvBufferPos++] = ucByte; + eRcvState = STATE_RX_RCV; + + /* Enable t3.5 timers. */ + vMBPortTimersEnable( ); + break; + + /* We are currently receiving a frame. Reset the timer after + * every character received. If more than the maximum possible + * number of bytes in a modbus frame is received the frame is + * ignored. + */ + case STATE_RX_RCV: + if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX ) + { + ucRTUBuf[usRcvBufferPos++] = ucByte; + } + else + { + eRcvState = STATE_RX_ERROR; + } + vMBPortTimersEnable( ); + break; + } + return xTaskNeedSwitch; +} + +BOOL +xMBRTUTransmitFSM( void ) +{ + BOOL xNeedPoll = FALSE; + + assert( eRcvState == STATE_RX_IDLE ); + + switch ( eSndState ) + { + /* We should not get a transmitter event if the transmitter is in + * idle state. */ + case STATE_TX_IDLE: + /* enable receiver/disable transmitter. */ + vMBPortSerialEnable( TRUE, FALSE ); + break; + + case STATE_TX_XMIT: + /* check if we are finished. */ + if( usSndBufferCount != 0 ) + { + xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur ); + pucSndBufferCur++; /* next byte in sendbuffer. */ + usSndBufferCount--; + } + else + { + xNeedPoll = xMBPortEventPost( EV_FRAME_SENT ); + /* Disable transmitter. This prevents another transmit buffer + * empty interrupt. */ + vMBPortSerialEnable( TRUE, FALSE ); + eSndState = STATE_TX_IDLE; + } + break; + } + + return xNeedPoll; +} + +BOOL +xMBRTUTimerT35Expired( void ) +{ + BOOL xNeedPoll = FALSE; + + switch ( eRcvState ) + { + /* Timer t35 expired. Startup phase is finished. */ + case STATE_RX_INIT: + xNeedPoll = xMBPortEventPost( EV_READY ); + break; + + /* A frame was received and t35 expired. Notify the listener that + * a new frame was received. */ + case STATE_RX_RCV: + xNeedPoll = xMBPortEventPost( EV_FRAME_RECEIVED ); + break; + + /* An error occured while receiving the frame. */ + case STATE_RX_ERROR: + break; + + /* Function called in an illegal state. */ + default: + assert( ( eRcvState == STATE_RX_INIT ) || + ( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) ); + } + + vMBPortTimersDisable( ); + eRcvState = STATE_RX_IDLE; + + return xNeedPoll; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus/rtu/mbrtu.h Fri Mar 31 01:35:28 2017 +0000 @@ -0,0 +1,51 @@ +/* + * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. + * Copyright (c) 2006 Christian Walter <wolti@sil.at> + * 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: mbrtu.h,v 1.9 2006/12/07 22:10:34 wolti Exp $ + */ + +#ifndef _MB_RTU_H +#define _MB_RTU_H + +#ifdef __cplusplus +PR_BEGIN_EXTERN_C +#endif + eMBErrorCode eMBRTUInit( UCHAR slaveAddress, UCHAR ucPort, ULONG ulBaudRate, + eMBParity eParity ); +void eMBRTUStart( void ); +void eMBRTUStop( void ); +eMBErrorCode eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength ); +eMBErrorCode eMBRTUSend( UCHAR slaveAddress, const UCHAR * pucFrame, USHORT usLength ); +BOOL xMBRTUReceiveFSM( void ); +BOOL xMBRTUTransmitFSM( void ); +BOOL xMBRTUTimerT15Expired( void ); +BOOL xMBRTUTimerT35Expired( void ); + +#ifdef __cplusplus +PR_END_EXTERN_C +#endif +#endif
--- a/mbed.bld Thu Mar 30 23:20:29 2017 +0800 +++ b/mbed.bld Fri Mar 31 01:35:28 2017 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/e1686b8d5b90 \ No newline at end of file +https://mbed.org/users/mbed_official/code/mbed/builds/093f2bd7b9eb \ No newline at end of file