提交 39465797 编写于 作者: B Bernard Xiong

Merge pull request #194 from grissiom/eol-issue

freemodbus: fix eol
Copyright (c) 2006 Christian Walter <wolti@sil.at> Copyright (c) 2006 Christian Walter <wolti@sil.at>
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
are met: are met:
1. Redistributions of source code must retain the above copyright 1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products 3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission. derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/* /*
* FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
* Copyright (c) 2006 Christian Walter <wolti@sil.at> * Copyright (c) 2006 Christian Walter <wolti@sil.at>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* File: $Id: mbascii.h,v 1.8 2006/12/07 22:10:34 wolti Exp $ * File: $Id: mbascii.h,v 1.8 2006/12/07 22:10:34 wolti Exp $
*/ */
#ifndef _MB_ASCII_H #ifndef _MB_ASCII_H
#define _MB_ASCII_H #define _MB_ASCII_H
#ifdef __cplusplus #ifdef __cplusplus
PR_BEGIN_EXTERN_C PR_BEGIN_EXTERN_C
#endif #endif
#if MB_SLAVE_ASCII_ENABLED > 0 #if MB_SLAVE_ASCII_ENABLED > 0
eMBErrorCode eMBASCIIInit( UCHAR slaveAddress, UCHAR ucPort, eMBErrorCode eMBASCIIInit( UCHAR slaveAddress, UCHAR ucPort,
ULONG ulBaudRate, eMBParity eParity ); ULONG ulBaudRate, eMBParity eParity );
void eMBASCIIStart( void ); void eMBASCIIStart( void );
void eMBASCIIStop( void ); void eMBASCIIStop( void );
eMBErrorCode eMBASCIIReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, eMBErrorCode eMBASCIIReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame,
USHORT * pusLength ); USHORT * pusLength );
eMBErrorCode eMBASCIISend( UCHAR slaveAddress, const UCHAR * pucFrame, eMBErrorCode eMBASCIISend( UCHAR slaveAddress, const UCHAR * pucFrame,
USHORT usLength ); USHORT usLength );
BOOL xMBASCIIReceiveFSM( void ); BOOL xMBASCIIReceiveFSM( void );
BOOL xMBASCIITransmitFSM( void ); BOOL xMBASCIITransmitFSM( void );
BOOL xMBASCIITimerT1SExpired( void ); BOOL xMBASCIITimerT1SExpired( void );
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
PR_END_EXTERN_C PR_END_EXTERN_C
#endif #endif
#endif #endif
/* /*
* FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
* Copyright (c) 2006 Christian Walter <wolti@sil.at> * Copyright (c) 2006 Christian Walter <wolti@sil.at>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* File: $Id: mbfunccoils.c,v 1.8 2007/02/18 23:47:16 wolti Exp $ * File: $Id: mbfunccoils.c,v 1.8 2007/02/18 23:47:16 wolti Exp $
*/ */
/* ----------------------- System includes ----------------------------------*/ /* ----------------------- System includes ----------------------------------*/
#include "stdlib.h" #include "stdlib.h"
#include "string.h" #include "string.h"
/* ----------------------- Platform includes --------------------------------*/ /* ----------------------- Platform includes --------------------------------*/
#include "port.h" #include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/ /* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h" #include "mb.h"
#include "mbframe.h" #include "mbframe.h"
#include "mbproto.h" #include "mbproto.h"
#include "mbconfig.h" #include "mbconfig.h"
/* ----------------------- Defines ------------------------------------------*/ /* ----------------------- Defines ------------------------------------------*/
#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF ) #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_COILCNT_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_READ_SIZE ( 4 ) #define MB_PDU_FUNC_READ_SIZE ( 4 )
#define MB_PDU_FUNC_READ_COILCNT_MAX ( 0x07D0 ) #define MB_PDU_FUNC_READ_COILCNT_MAX ( 0x07D0 )
#define MB_PDU_FUNC_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF ) #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_VALUE_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_WRITE_SIZE ( 4 ) #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_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_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_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_VALUES_OFF ( MB_PDU_DATA_OFF + 5 )
#define MB_PDU_FUNC_WRITE_MUL_SIZE_MIN ( 5 ) #define MB_PDU_FUNC_WRITE_MUL_SIZE_MIN ( 5 )
#define MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX ( 0x07B0 ) #define MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX ( 0x07B0 )
/* ----------------------- Static functions ---------------------------------*/ /* ----------------------- Static functions ---------------------------------*/
eMBException prveMBError2Exception( eMBErrorCode eErrorCode ); eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
#if MB_FUNC_READ_COILS_ENABLED > 0 #if MB_FUNC_READ_COILS_ENABLED > 0
eMBException eMBException
eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen ) eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
{ {
USHORT usRegAddress; USHORT usRegAddress;
USHORT usCoilCount; USHORT usCoilCount;
UCHAR ucNBytes; UCHAR ucNBytes;
UCHAR *pucFrameCur; UCHAR *pucFrameCur;
eMBException eStatus = MB_EX_NONE; eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus; eMBErrorCode eRegStatus;
if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) ) 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] << 8 );
usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] ); usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
usRegAddress++; usRegAddress++;
usCoilCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] << 8 ); usCoilCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] << 8 );
usCoilCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF + 1] ); usCoilCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF + 1] );
/* Check if the number of registers to read is valid. If not /* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception. * return Modbus illegal data value exception.
*/ */
if( ( usCoilCount >= 1 ) && if( ( usCoilCount >= 1 ) &&
( usCoilCount < MB_PDU_FUNC_READ_COILCNT_MAX ) ) ( usCoilCount < MB_PDU_FUNC_READ_COILCNT_MAX ) )
{ {
/* Set the current PDU data pointer to the beginning. */ /* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF]; pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF; *usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */ /* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READ_COILS; *pucFrameCur++ = MB_FUNC_READ_COILS;
*usLen += 1; *usLen += 1;
/* Test if the quantity of coils is a multiple of 8. If not last /* 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. */ * byte is only partially field with unused coils set to zero. */
if( ( usCoilCount & 0x0007 ) != 0 ) if( ( usCoilCount & 0x0007 ) != 0 )
{ {
ucNBytes = ( UCHAR )( usCoilCount / 8 + 1 ); ucNBytes = ( UCHAR )( usCoilCount / 8 + 1 );
} }
else else
{ {
ucNBytes = ( UCHAR )( usCoilCount / 8 ); ucNBytes = ( UCHAR )( usCoilCount / 8 );
} }
*pucFrameCur++ = ucNBytes; *pucFrameCur++ = ucNBytes;
*usLen += 1; *usLen += 1;
eRegStatus = eRegStatus =
eMBRegCoilsCB( pucFrameCur, usRegAddress, usCoilCount, eMBRegCoilsCB( pucFrameCur, usRegAddress, usCoilCount,
MB_REG_READ ); MB_REG_READ );
/* If an error occured convert it into a Modbus exception. */ /* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR ) if( eRegStatus != MB_ENOERR )
{ {
eStatus = prveMBError2Exception( eRegStatus ); eStatus = prveMBError2Exception( eRegStatus );
} }
else else
{ {
/* The response contains the function code, the starting address /* The response contains the function code, the starting address
* and the quantity of registers. We reuse the old values in the * and the quantity of registers. We reuse the old values in the
* buffer because they are still valid. */ * buffer because they are still valid. */
*usLen += ucNBytes;; *usLen += ucNBytes;;
} }
} }
else else
{ {
eStatus = MB_EX_ILLEGAL_DATA_VALUE; eStatus = MB_EX_ILLEGAL_DATA_VALUE;
} }
} }
else else
{ {
/* Can't be a valid read coil register request because the length /* Can't be a valid read coil register request because the length
* is incorrect. */ * is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE; eStatus = MB_EX_ILLEGAL_DATA_VALUE;
} }
return eStatus; return eStatus;
} }
#endif #endif
#if MB_FUNC_WRITE_COIL_ENABLED > 0 #if MB_FUNC_WRITE_COIL_ENABLED > 0
eMBException eMBException
eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen ) eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
{ {
USHORT usRegAddress; USHORT usRegAddress;
UCHAR ucBuf[2]; UCHAR ucBuf[2];
eMBException eStatus = MB_EX_NONE; eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus; eMBErrorCode eRegStatus;
if( *usLen == ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) ) 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] << 8 );
usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] ); usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] );
usRegAddress++; usRegAddress++;
if( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF + 1] == 0x00 ) && 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] == 0xFF ) ||
( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0x00 ) ) ) ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0x00 ) ) )
{ {
ucBuf[1] = 0; ucBuf[1] = 0;
if( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF ) if( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF )
{ {
ucBuf[0] = 1; ucBuf[0] = 1;
} }
else else
{ {
ucBuf[0] = 0; ucBuf[0] = 0;
} }
eRegStatus = eRegStatus =
eMBRegCoilsCB( &ucBuf[0], usRegAddress, 1, MB_REG_WRITE ); eMBRegCoilsCB( &ucBuf[0], usRegAddress, 1, MB_REG_WRITE );
/* If an error occured convert it into a Modbus exception. */ /* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR ) if( eRegStatus != MB_ENOERR )
{ {
eStatus = prveMBError2Exception( eRegStatus ); eStatus = prveMBError2Exception( eRegStatus );
} }
} }
else else
{ {
eStatus = MB_EX_ILLEGAL_DATA_VALUE; eStatus = MB_EX_ILLEGAL_DATA_VALUE;
} }
} }
else else
{ {
/* Can't be a valid write coil register request because the length /* Can't be a valid write coil register request because the length
* is incorrect. */ * is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE; eStatus = MB_EX_ILLEGAL_DATA_VALUE;
} }
return eStatus; return eStatus;
} }
#endif #endif
#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0 #if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
eMBException eMBException
eMBFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen ) eMBFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen )
{ {
USHORT usRegAddress; USHORT usRegAddress;
USHORT usCoilCnt; USHORT usCoilCnt;
UCHAR ucByteCount; UCHAR ucByteCount;
UCHAR ucByteCountVerify; UCHAR ucByteCountVerify;
eMBException eStatus = MB_EX_NONE; eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus; eMBErrorCode eRegStatus;
if( *usLen > ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) ) 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] << 8 );
usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] ); usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] );
usRegAddress++; usRegAddress++;
usCoilCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF] << 8 ); usCoilCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF] << 8 );
usCoilCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF + 1] ); usCoilCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF + 1] );
ucByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF]; ucByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];
/* Compute the number of expected bytes in the request. */ /* Compute the number of expected bytes in the request. */
if( ( usCoilCnt & 0x0007 ) != 0 ) if( ( usCoilCnt & 0x0007 ) != 0 )
{ {
ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 + 1 ); ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 + 1 );
} }
else else
{ {
ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 ); ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 );
} }
if( ( usCoilCnt >= 1 ) && if( ( usCoilCnt >= 1 ) &&
( usCoilCnt <= MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX ) && ( usCoilCnt <= MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX ) &&
( ucByteCountVerify == ucByteCount ) ) ( ucByteCountVerify == ucByteCount ) )
{ {
eRegStatus = eRegStatus =
eMBRegCoilsCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF], eMBRegCoilsCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF],
usRegAddress, usCoilCnt, MB_REG_WRITE ); usRegAddress, usCoilCnt, MB_REG_WRITE );
/* If an error occured convert it into a Modbus exception. */ /* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR ) if( eRegStatus != MB_ENOERR )
{ {
eStatus = prveMBError2Exception( eRegStatus ); eStatus = prveMBError2Exception( eRegStatus );
} }
else else
{ {
/* The response contains the function code, the starting address /* The response contains the function code, the starting address
* and the quantity of registers. We reuse the old values in the * and the quantity of registers. We reuse the old values in the
* buffer because they are still valid. */ * buffer because they are still valid. */
*usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF; *usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;
} }
} }
else else
{ {
eStatus = MB_EX_ILLEGAL_DATA_VALUE; eStatus = MB_EX_ILLEGAL_DATA_VALUE;
} }
} }
else else
{ {
/* Can't be a valid write coil register request because the length /* Can't be a valid write coil register request because the length
* is incorrect. */ * is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE; eStatus = MB_EX_ILLEGAL_DATA_VALUE;
} }
return eStatus; return eStatus;
} }
#endif #endif
/* /*
* FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
* Copyright (c) 2006 Christian Walter <wolti@sil.at> * Copyright (c) 2006 Christian Walter <wolti@sil.at>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* File: $Id: mbfuncdiag.c,v 1.3 2006/12/07 22:10:34 wolti Exp $ * File: $Id: mbfuncdiag.c,v 1.3 2006/12/07 22:10:34 wolti Exp $
*/ */
/* /*
* FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
* Copyright (c) 2006 Christian Walter <wolti@sil.at> * Copyright (c) 2006 Christian Walter <wolti@sil.at>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* File: $Id: mbfuncother.c,v 1.8 2006/12/07 22:10:34 wolti Exp $ * File: $Id: mbfuncother.c,v 1.8 2006/12/07 22:10:34 wolti Exp $
*/ */
/* ----------------------- System includes ----------------------------------*/ /* ----------------------- System includes ----------------------------------*/
#include "stdlib.h" #include "stdlib.h"
#include "string.h" #include "string.h"
/* ----------------------- Platform includes --------------------------------*/ /* ----------------------- Platform includes --------------------------------*/
#include "port.h" #include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/ /* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h" #include "mb.h"
#include "mbframe.h" #include "mbframe.h"
#include "mbproto.h" #include "mbproto.h"
#include "mbconfig.h" #include "mbconfig.h"
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0 #if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0
/* ----------------------- Static variables ---------------------------------*/ /* ----------------------- Static variables ---------------------------------*/
static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF]; static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF];
static USHORT usMBSlaveIDLen; static USHORT usMBSlaveIDLen;
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
eMBErrorCode eMBErrorCode
eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning, eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning,
UCHAR const *pucAdditional, USHORT usAdditionalLen ) UCHAR const *pucAdditional, USHORT usAdditionalLen )
{ {
eMBErrorCode eStatus = MB_ENOERR; eMBErrorCode eStatus = MB_ENOERR;
/* the first byte and second byte in the buffer is reserved for /* the first byte and second byte in the buffer is reserved for
* the parameter ucSlaveID and the running flag. The rest of * the parameter ucSlaveID and the running flag. The rest of
* the buffer is available for additional data. */ * the buffer is available for additional data. */
if( usAdditionalLen + 2 < MB_FUNC_OTHER_REP_SLAVEID_BUF ) if( usAdditionalLen + 2 < MB_FUNC_OTHER_REP_SLAVEID_BUF )
{ {
usMBSlaveIDLen = 0; usMBSlaveIDLen = 0;
ucMBSlaveID[usMBSlaveIDLen++] = ucSlaveID; ucMBSlaveID[usMBSlaveIDLen++] = ucSlaveID;
ucMBSlaveID[usMBSlaveIDLen++] = ( UCHAR )( xIsRunning ? 0xFF : 0x00 ); ucMBSlaveID[usMBSlaveIDLen++] = ( UCHAR )( xIsRunning ? 0xFF : 0x00 );
if( usAdditionalLen > 0 ) if( usAdditionalLen > 0 )
{ {
memcpy( &ucMBSlaveID[usMBSlaveIDLen], pucAdditional, memcpy( &ucMBSlaveID[usMBSlaveIDLen], pucAdditional,
( size_t )usAdditionalLen ); ( size_t )usAdditionalLen );
usMBSlaveIDLen += usAdditionalLen; usMBSlaveIDLen += usAdditionalLen;
} }
} }
else else
{ {
eStatus = MB_ENORES; eStatus = MB_ENORES;
} }
return eStatus; return eStatus;
} }
eMBException eMBException
eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen ) eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen )
{ {
memcpy( &pucFrame[MB_PDU_DATA_OFF], &ucMBSlaveID[0], ( size_t )usMBSlaveIDLen ); memcpy( &pucFrame[MB_PDU_DATA_OFF], &ucMBSlaveID[0], ( size_t )usMBSlaveIDLen );
*usLen = ( USHORT )( MB_PDU_DATA_OFF + usMBSlaveIDLen ); *usLen = ( USHORT )( MB_PDU_DATA_OFF + usMBSlaveIDLen );
return MB_EX_NONE; return MB_EX_NONE;
} }
#endif #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册