Modbus RTU/ASCII/TCP with lwip TCP working partial, but with errors (retransmitions)
Dependencies: EthernetNetIf mbed
mbtcp.cpp
00001 /* 00002 * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. 00003 * Copyright (c) 2006 Christian Walter <wolti@sil.at> 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 3. The name of the author may not be used to endorse or promote products 00015 * derived from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00019 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00020 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 * 00028 * File: $Id: mbtcp.c,v 1.3 2006/12/07 22:10:34 wolti Exp $ 00029 */ 00030 00031 /* ----------------------- System includes ----------------------------------*/ 00032 #include "stdlib.h" 00033 #include "string.h" 00034 00035 /* ----------------------- Platform includes --------------------------------*/ 00036 #include "port.h" 00037 00038 /* ----------------------- Modbus includes ----------------------------------*/ 00039 #include "mb.h" 00040 #include "mbconfig.h" 00041 #include "mbtcp.h" 00042 #include "mbframe.h" 00043 #include "mbport.h" 00044 00045 #if MB_TCP_ENABLED > 0 00046 00047 /* ----------------------- Defines ------------------------------------------*/ 00048 00049 /* ----------------------- MBAP Header --------------------------------------*/ 00050 /* 00051 * 00052 * <------------------------ MODBUS TCP/IP ADU(1) -------------------------> 00053 * <----------- MODBUS PDU (1') ----------------> 00054 * +-----------+---------------+------------------------------------------+ 00055 * | TID | PID | Length | UID |Code | Data | 00056 * +-----------+---------------+------------------------------------------+ 00057 * | | | | | 00058 * (2) (3) (4) (5) (6) 00059 * 00060 * (2) ... MB_TCP_TID = 0 (Transaction Identifier - 2 Byte) 00061 * (3) ... MB_TCP_PID = 2 (Protocol Identifier - 2 Byte) 00062 * (4) ... MB_TCP_LEN = 4 (Number of bytes - 2 Byte) 00063 * (5) ... MB_TCP_UID = 6 (Unit Identifier - 1 Byte) 00064 * (6) ... MB_TCP_FUNC = 7 (Modbus Function Code) 00065 * 00066 * (1) ... Modbus TCP/IP Application Data Unit 00067 * (1') ... Modbus Protocol Data Unit 00068 */ 00069 00070 #define MB_TCP_TID 0 00071 #define MB_TCP_PID 2 00072 #define MB_TCP_LEN 4 00073 #define MB_TCP_UID 6 00074 #define MB_TCP_FUNC 7 00075 00076 #define MB_TCP_PROTOCOL_ID 0 /* 0 = Modbus Protocol */ 00077 00078 00079 /* ----------------------- Start implementation -----------------------------*/ 00080 eMBErrorCode 00081 eMBTCPDoInit( USHORT ucTCPPort ) 00082 { 00083 eMBErrorCode eStatus = MB_ENOERR ; 00084 00085 if( xMBTCPPortInit( ucTCPPort ) == FALSE ) 00086 { 00087 eStatus = MB_EPORTERR ; 00088 } 00089 return eStatus; 00090 } 00091 00092 void 00093 eMBTCPStart( void ) 00094 { 00095 } 00096 00097 void 00098 eMBTCPStop( void ) 00099 { 00100 /* Make sure that no more clients are connected. */ 00101 vMBTCPPortDisable( ); 00102 } 00103 00104 eMBErrorCode 00105 eMBTCPReceive( UCHAR * pucRcvAddress, UCHAR ** ppucFrame, USHORT * pusLength ) 00106 { 00107 eMBErrorCode eStatus = MB_EIO ; 00108 UCHAR *pucMBTCPFrame; 00109 USHORT usLength; 00110 USHORT usPID; 00111 00112 if( xMBTCPPortGetRequest( &pucMBTCPFrame, &usLength ) != FALSE ) 00113 { 00114 usPID = pucMBTCPFrame[MB_TCP_PID] << 8U; 00115 usPID |= pucMBTCPFrame[MB_TCP_PID + 1]; 00116 00117 if( usPID == MB_TCP_PROTOCOL_ID ) 00118 { 00119 *ppucFrame = &pucMBTCPFrame[MB_TCP_FUNC]; 00120 *pusLength = usLength - MB_TCP_FUNC; 00121 eStatus = MB_ENOERR ; 00122 00123 /* Modbus TCP does not use any addresses. Fake the source address such 00124 * that the processing part deals with this frame. 00125 */ 00126 *pucRcvAddress = MB_TCP_PSEUDO_ADDRESS; 00127 } 00128 } 00129 else 00130 { 00131 eStatus = MB_EIO ; 00132 } 00133 return eStatus; 00134 } 00135 00136 eMBErrorCode 00137 eMBTCPSend( UCHAR _unused, const UCHAR * pucFrame, USHORT usLength ) 00138 { 00139 eMBErrorCode eStatus = MB_ENOERR ; 00140 UCHAR *pucMBTCPFrame = ( UCHAR * ) pucFrame - MB_TCP_FUNC; 00141 USHORT usTCPLength = usLength + MB_TCP_FUNC; 00142 00143 /* The MBAP header is already initialized because the caller calls this 00144 * function with the buffer returned by the previous call. Therefore we 00145 * only have to update the length in the header. Note that the length 00146 * header includes the size of the Modbus PDU and the UID Byte. Therefore 00147 * the length is usLength plus one. 00148 */ 00149 pucMBTCPFrame[MB_TCP_LEN] = ( usLength + 1 ) >> 8U; 00150 pucMBTCPFrame[MB_TCP_LEN + 1] = ( usLength + 1 ) & 0xFF; 00151 if( xMBTCPPortSendResponse( pucMBTCPFrame, usTCPLength ) == FALSE ) 00152 { 00153 eStatus = MB_EIO ; 00154 } 00155 return eStatus; 00156 } 00157 00158 #endif
Generated on Tue Jul 12 2022 21:29:48 by 1.7.2