sw k
/
Modbus
a
Fork of Modbus by
Embed:
(wiki syntax)
Show/hide line numbers
mbfuncdisc.cpp
00001 /* 00002 * FreeRTOS Modbus Libary: A Modbus serial implementation for FreeRTOS 00003 * Copyright (C) 2006 Christian Walter <wolti@sil.at> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 00020 00021 00022 /* ----------------------- System includes ----------------------------------*/ 00023 #include "stdlib.h" 00024 #include "string.h" 00025 00026 /* ----------------------- Platform includes --------------------------------*/ 00027 #include "port.h" 00028 00029 /* ----------------------- Modbus includes ----------------------------------*/ 00030 #include "mb.h" 00031 #include "mbframe.h" 00032 #include "mbproto.h" 00033 #include "mbconfig.h" 00034 00035 /* ----------------------- Defines ------------------------------------------*/ 00036 #define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF ) 00037 #define MB_PDU_FUNC_READ_DISCCNT_OFF ( MB_PDU_DATA_OFF + 2 ) 00038 #define MB_PDU_FUNC_READ_SIZE ( 4 ) 00039 #define MB_PDU_FUNC_READ_DISCCNT_MAX ( 0x07D0 ) 00040 00041 /* ----------------------- Static functions ---------------------------------*/ 00042 eMBException prveMBError2Exception( eMBErrorCode eErrorCode ); 00043 00044 /* ----------------------- Start implementation -----------------------------*/ 00045 00046 #if MB_FUNC_READ_COILS_ENABLED > 0 00047 00048 eMBException 00049 eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen ) 00050 { 00051 USHORT usRegAddress; 00052 USHORT usDiscreteCnt; 00053 UCHAR ucNBytes; 00054 UCHAR *pucFrameCur; 00055 00056 eMBException eStatus = MB_EX_NONE; 00057 eMBErrorCode eRegStatus; 00058 00059 if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) ) 00060 { 00061 usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 ); 00062 usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] ); 00063 usRegAddress++; 00064 00065 usDiscreteCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF] << 8 ); 00066 usDiscreteCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF + 1] ); 00067 00068 /* Check if the number of registers to read is valid. If not 00069 * return Modbus illegal data value exception. 00070 */ 00071 if( ( usDiscreteCnt >= 1 ) && 00072 ( usDiscreteCnt < MB_PDU_FUNC_READ_DISCCNT_MAX ) ) 00073 { 00074 /* Set the current PDU data pointer to the beginning. */ 00075 pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF]; 00076 *usLen = MB_PDU_FUNC_OFF; 00077 00078 /* First byte contains the function code. */ 00079 *pucFrameCur++ = MB_FUNC_READ_DISCRETE_INPUTS; 00080 *usLen += 1; 00081 00082 /* Test if the quantity of coils is a multiple of 8. If not last 00083 * byte is only partially field with unused coils set to zero. */ 00084 if( ( usDiscreteCnt & 0x0007 ) != 0 ) 00085 { 00086 ucNBytes = ( UCHAR ) ( usDiscreteCnt / 8 + 1 ); 00087 } 00088 else 00089 { 00090 ucNBytes = ( UCHAR ) ( usDiscreteCnt / 8 ); 00091 } 00092 *pucFrameCur++ = ucNBytes; 00093 *usLen += 1; 00094 00095 eRegStatus = 00096 eMBRegDiscreteCB( pucFrameCur, usRegAddress, usDiscreteCnt ); 00097 00098 /* If an error occured convert it into a Modbus exception. */ 00099 if( eRegStatus != MB_ENOERR ) 00100 { 00101 eStatus = prveMBError2Exception( eRegStatus ); 00102 } 00103 else 00104 { 00105 /* The response contains the function code, the starting address 00106 * and the quantity of registers. We reuse the old values in the 00107 * buffer because they are still valid. */ 00108 *usLen += ucNBytes;; 00109 } 00110 } 00111 else 00112 { 00113 eStatus = MB_EX_ILLEGAL_DATA_VALUE; 00114 } 00115 } 00116 else 00117 { 00118 /* Can't be a valid read coil register request because the length 00119 * is incorrect. */ 00120 eStatus = MB_EX_ILLEGAL_DATA_VALUE; 00121 } 00122 return eStatus; 00123 } 00124 00125 #endif
Generated on Tue Jul 12 2022 23:11:12 by 1.7.2