Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 Sun Jul 17 2022 02:04:12 by
1.7.2