From 7e1fa80cc548e975b8b76460de068ab26c069152 Mon Sep 17 00:00:00 2001 From: Alexei Date: Mon, 6 Feb 2023 00:22:53 +0700 Subject: [PATCH] Added FreeRTOS_debug_printf --- DemoTasks/SimpleTCPEchoServer.c | 5 +- FreeRTOS/source/FreeRTOS_DHCP.c | 8 +- FreeRTOS/source/FreeRTOS_DNS.c | 6 +- FreeRTOS/source/FreeRTOS_IP_Utils.c | 14 +- FreeRTOS/source/FreeRTOS_TCP_IP.c | 23 +- FreeRTOS/source/include/FreeRTOSIPConfig.h | 17 +- .../include/FreeRTOS_TCP_State_Handling.h | 3 +- .../NetworkInterface/Common/phyHandling.c | 14 +- .../board_family/NetworkInterface.c | 1421 +++++++++-------- RTE/RTOS/FreeRTOSConfig.h | 12 +- Test_project_for_GD32107C-EVAL.uvoptx | 54 +- Test_project_for_GD32107C-EVAL.uvprojx | 12 +- main.c | 56 +- 13 files changed, 826 insertions(+), 819 deletions(-) diff --git a/DemoTasks/SimpleTCPEchoServer.c b/DemoTasks/SimpleTCPEchoServer.c index 5d8d2c3..314cd1f 100644 --- a/DemoTasks/SimpleTCPEchoServer.c +++ b/DemoTasks/SimpleTCPEchoServer.c @@ -189,6 +189,9 @@ const BaseType_t xBacklog = 20; listen for incoming connections. */ xBindAddress.sin_port = tcpechoPORT_NUMBER; xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); +#if (ipconfigUSE_DHCP == 0) + xBindAddress.sin_addr = FreeRTOS_htonl(xNetworkAddressing.ulDefaultIPAddress); +#endif FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); FreeRTOS_listen( xListeningSocket, xBacklog ); @@ -196,7 +199,7 @@ const BaseType_t xBacklog = 20; { /* Wait for a client to connect. */ xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize ); - configASSERT( xConnectedSocket != FREERTOS_INVALID_SOCKET ); + //configASSERT( xConnectedSocket != FREERTOS_INVALID_SOCKET ); /* Spawn a task to handle the connection. */ xTaskCreate( prvServerConnectionInstance, "EchoServer", usUsedStackSize, ( void * ) xConnectedSocket, tskIDLE_PRIORITY, NULL ); diff --git a/FreeRTOS/source/FreeRTOS_DHCP.c b/FreeRTOS/source/FreeRTOS_DHCP.c index 098e01c..fa3e045 100644 --- a/FreeRTOS/source/FreeRTOS_DHCP.c +++ b/FreeRTOS/source/FreeRTOS_DHCP.c @@ -198,7 +198,7 @@ { EP_DHCPData.eDHCPState = eInitialWait; } - + if( ( EP_DHCPData.eDHCPState != eExpectedState ) && ( xReset == pdFALSE ) ) { /* When the DHCP event was generated, the DHCP client was @@ -352,7 +352,7 @@ if( prvSendDHCPDiscover() == pdPASS ) { - FreeRTOS_debug_printf( ( "vDHCPProcess: timeout %lu ticks\n", EP_DHCPData.xDHCPTxPeriod ) ); + FreeRTOS_debug_printf( ( "vDHCPProcess: timeout %lu ticks\n", (UBaseType_t)EP_DHCPData.xDHCPTxPeriod ) ); } else { @@ -369,7 +369,7 @@ } else { - FreeRTOS_debug_printf( ( "vDHCPProcess: giving up %lu > %lu ticks\n", EP_DHCPData.xDHCPTxPeriod, ipconfigMAXIMUM_DISCOVER_TX_PERIOD ) ); + FreeRTOS_debug_printf( ( "vDHCPProcess: giving up %lu > %lu ticks\n", (UBaseType_t)EP_DHCPData.xDHCPTxPeriod, (UBaseType_t)ipconfigMAXIMUM_DISCOVER_TX_PERIOD ) ); #if ( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 ) { @@ -665,7 +665,7 @@ /* Create the DHCP socket if it has not already been created. */ prvCreateDHCPSocket(); - FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) ); + FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", (UBaseType_t)dhcpINITIAL_TIMER_PERIOD ) ); vDHCPTimerReload( dhcpINITIAL_TIMER_PERIOD ); } else diff --git a/FreeRTOS/source/FreeRTOS_DNS.c b/FreeRTOS/source/FreeRTOS_DNS.c index 87ca5c9..226d2a7 100644 --- a/FreeRTOS/source/FreeRTOS_DNS.c +++ b/FreeRTOS/source/FreeRTOS_DNS.c @@ -233,8 +233,8 @@ else { FreeRTOS_printf( ( "prvPrepareLookup: name is too long ( %lu > %lu )\n", - ( uint32_t ) xLength, - ( uint32_t ) ipconfigDNS_CACHE_NAME_LENGTH ) ); + (UBaseType_t) xLength, + (UBaseType_t) ipconfigDNS_CACHE_NAME_LENGTH ) ); } } @@ -256,7 +256,7 @@ if( ulIPAddress != 0U ) { - FreeRTOS_debug_printf( ( "FreeRTOS_gethostbyname: found '%s' in cache: %lxip\n", pcHostName, ulIPAddress ) ); + FreeRTOS_debug_printf( ( "FreeRTOS_gethostbyname: found '%s' in cache: %lxip\n", pcHostName, (UBaseType_t)ulIPAddress ) ); } else { diff --git a/FreeRTOS/source/FreeRTOS_IP_Utils.c b/FreeRTOS/source/FreeRTOS_IP_Utils.c index 002d8b0..3947f3e 100644 --- a/FreeRTOS/source/FreeRTOS_IP_Utils.c +++ b/FreeRTOS/source/FreeRTOS_IP_Utils.c @@ -53,6 +53,7 @@ #include "NetworkInterface.h" #include "NetworkBufferManagement.h" #include "FreeRTOS_DNS.h" +#include "portable.h" /* Used to ensure the structure packing is having the desired effect. The * 'volatile' is used to prevent compiler warnings about comparing a constant with @@ -670,7 +671,7 @@ uint16_t usGenerateProtocolChecksum( uint8_t * pucEthernetBuffer, { #if ( ipconfigHAS_DEBUG_PRINTF != 0 ) { - FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: len invalid: %lu\n", pcType, ulLength ) ); + FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: len invalid: %lu\n", pcType, (UBaseType_t)ulLength ) ); } #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */ @@ -758,8 +759,8 @@ uint16_t usGenerateProtocolChecksum( uint8_t * pucEthernetBuffer, FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: ID %04X: from %lxip to %lxip bad crc: %04X\n", pcType, FreeRTOS_ntohs( pxIPPacket->xIPHeader.usIdentification ), - FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulSourceIPAddress ), - FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulDestinationIPAddress ), + (UBaseType_t)FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulSourceIPAddress ), + (UBaseType_t)FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulDestinationIPAddress ), FreeRTOS_ntohs( usChecksumFound ) ) ); } else @@ -1016,7 +1017,7 @@ uint16_t usGenerateChecksum( uint16_t usSum, void vPrintResourceStats( void ) { UBaseType_t uxCurrentBufferCount; - size_t uxMinSize; + size_t uxMinSize = 0; /* When setting up and testing a project with FreeRTOS+TCP, it is * can be helpful to monitor a few resources: the number of network @@ -1034,8 +1035,9 @@ uint16_t usGenerateChecksum( uint16_t usSum, uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) ); } - +#ifndef DEBUG uxMinSize = xPortGetMinimumEverFreeHeapSize(); +#endif if( uxMinLastSize == 0U ) { @@ -1050,7 +1052,7 @@ uint16_t usGenerateChecksum( uint16_t usSum, else if( ( uxMinLastSize * ipMONITOR_PERCENTAGE_90 ) > ( uxMinSize * ipMONITOR_PERCENTAGE_100 ) ) { uxMinLastSize = uxMinSize; - FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", xPortGetFreeHeapSize(), uxMinSize ) ); + FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", (UBaseType_t)xPortGetFreeHeapSize(), (UBaseType_t)uxMinSize ) ); } else { diff --git a/FreeRTOS/source/FreeRTOS_TCP_IP.c b/FreeRTOS/source/FreeRTOS_TCP_IP.c index 1b9451d..8e5b976 100644 --- a/FreeRTOS/source/FreeRTOS_TCP_IP.c +++ b/FreeRTOS/source/FreeRTOS_TCP_IP.c @@ -60,7 +60,6 @@ #include "FreeRTOS_TCP_State_Handling.h" #include "FreeRTOS_TCP_Utils.h" - /* Just make sure the contents doesn't get compiled if TCP is not enabled. */ #if ipconfigUSE_TCP == 1 @@ -191,7 +190,7 @@ { if( ( xTCPWindowLoggingLevel > 1 ) && ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) ) { - FreeRTOS_debug_printf( ( "Send[%u->%u] del ACK %u SEQ %u (len %u)\n", + FreeRTOS_debug_printf( ("Send[%u->%u] del ACK %u SEQ %u (len %u)\n", pxSocket->usLocalPort, pxSocket->u.xTCP.usRemotePort, ( unsigned ) ( pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber ), @@ -316,7 +315,7 @@ { /* A socket was in the connecting phase but something * went wrong and it should be closed. */ - FreeRTOS_debug_printf( ( "Move from %s to %s\n", + FreeRTOS_debug_printf( ("Move from %s to %s\n", FreeRTOS_GetTCPStateName( xPreviousState ), FreeRTOS_GetTCPStateName( eTCPState ) ) ); @@ -454,7 +453,7 @@ ( pxSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) ) { FreeRTOS_debug_printf( ( "vTCPStateChange: Closing socket\n" ) ); - + if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED ) { configASSERT( xIsCallingFromIPTask() != pdFALSE ); @@ -472,7 +471,7 @@ { case eSYN_FIRST: /* 3 (server) Just created, must ACK the SYN request */ case eSYN_RECEIVED: /* 4 (server) waiting for a confirming connection request */ - FreeRTOS_debug_printf( ( "Restoring a reuse socket port %u\n", pxSocket->usLocalPort ) ); + FreeRTOS_debug_printf( ("Restoring a reuse socket port %u\n", pxSocket->usLocalPort ) ); /* Go back into listening mode. Set the TCP status to 'eCLOSED', * otherwise FreeRTOS_listen() will refuse the action. */ @@ -557,10 +556,10 @@ ulDelayMs = 500U; } - FreeRTOS_debug_printf( ( "Connect[%xip:%u]: next timeout %u: %u ms\n", + FreeRTOS_debug_printf( ("Connect[%xip:%u]: next timeout %u: %u ms\n", ( unsigned ) pxSocket->u.xTCP.ulRemoteIP, pxSocket->u.xTCP.usRemotePort, - pxSocket->u.xTCP.ucRepCount, ( unsigned ) ulDelayMs ) ); - pxSocket->u.xTCP.usTimeout = ( uint16_t ) ipMS_TO_MIN_TICKS( ulDelayMs ); + pxSocket->u.xTCP.ucRepCount, ( unsigned ) ulDelayMs ); + pxSocket->u.xTCP.usTimeout = ( uint16_t ) ipMS_TO_MIN_TICKS( ulDelayMs ) ); } else if( pxSocket->u.xTCP.usTimeout == 0U ) { @@ -668,7 +667,7 @@ * non-active states: eCLOSED, eCLOSE_WAIT, eFIN_WAIT_2, eCLOSING, or * eTIME_WAIT. */ - FreeRTOS_debug_printf( ( "TCP: No active socket on port %d (%xip:%d)\n", usLocalPort, ( unsigned ) ulRemoteIP, usRemotePort ) ); + FreeRTOS_debug_printf( ("TCP: No active socket on port %d (%xip:%d)\n", usLocalPort, ( unsigned ) ulRemoteIP, usRemotePort ) ); /* Send a RST to all packets that can not be handled. As a result * the other party will get a ECONN error. There are two exceptions: @@ -731,7 +730,7 @@ * flag. */ if( ( ucTCPFlags & tcpTCP_FLAG_RST ) != 0U ) { - FreeRTOS_debug_printf( ( "TCP: RST received from %xip:%u for %u\n", ( unsigned ) ulRemoteIP, usRemotePort, usLocalPort ) ); + FreeRTOS_debug_printf( ("TCP: RST received from %xip:%u for %u\n", ( unsigned ) ulRemoteIP, usRemotePort, usLocalPort ) ); /* Implement https://tools.ietf.org/html/rfc5961#section-3.2. */ if( pxSocket->u.xTCP.eTCPState == eCONNECT_SYN ) @@ -771,7 +770,7 @@ else if( ( ( ucTCPFlags & tcpTCP_FLAG_CTRL ) == tcpTCP_FLAG_SYN ) && ( pxSocket->u.xTCP.eTCPState >= eESTABLISHED ) ) { /* SYN flag while this socket is already connected. */ - FreeRTOS_debug_printf( ( "TCP: SYN unexpected from %xip:%u\n", ( unsigned ) ulRemoteIP, usRemotePort ) ); + FreeRTOS_debug_printf( ("TCP: SYN unexpected from %xip:%u\n", ( unsigned ) ulRemoteIP, usRemotePort ) ); /* The packet cannot be handled. */ xResult = pdFAIL; @@ -900,7 +899,7 @@ if( ( pxFound->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP ) && ( pxFound->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) ) { pxSocket->u.xTCP.pxPeerSocket = pxFound; - FreeRTOS_debug_printf( ( "xTCPCheckNewClient[0]: client on port %u\n", pxSocket->usLocalPort ) ); + FreeRTOS_debug_printf( ("xTCPCheckNewClient[0]: client on port %u\n", pxSocket->usLocalPort ) ); xResult = pdTRUE; break; } diff --git a/FreeRTOS/source/include/FreeRTOSIPConfig.h b/FreeRTOS/source/include/FreeRTOSIPConfig.h index ec3eeaa..663eb60 100644 --- a/FreeRTOS/source/include/FreeRTOSIPConfig.h +++ b/FreeRTOS/source/include/FreeRTOSIPConfig.h @@ -33,14 +33,21 @@ #ifndef FREERTOS_IP_CONFIG_H #define FREERTOS_IP_CONFIG_H - +#include /* Empty configuration file to check the build with default configuration. */ /* It is not sensible for this macro to have a default value as it is hardware * dependent. */ #define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN -#define ipconfigUSE_NETWORK_EVENT_HOOK 1 -#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 4 - - +#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 4 +#define ipconfigUSE_NETWORK_EVENT_HOOK 1 +#define ipconfigUSE_DHCP 1 +#define ipconfigUSE_DHCP_HOOK 1 +#define ipconfigUSE_DNS_CACHE 1 +#ifdef DEBUG + #define ipconfigHAS_DEBUG_PRINTF 1 + #define ipconfigHAS_PRINTF 1 + #define FreeRTOS_debug_printf( X ) printf X//, ##__VA_ARGS__ + #define FreeRTOS_printf( X ) printf X +#endif #endif diff --git a/FreeRTOS/source/include/FreeRTOS_TCP_State_Handling.h b/FreeRTOS/source/include/FreeRTOS_TCP_State_Handling.h index ca567eb..9b74a35 100644 --- a/FreeRTOS/source/include/FreeRTOS_TCP_State_Handling.h +++ b/FreeRTOS/source/include/FreeRTOS_TCP_State_Handling.h @@ -64,7 +64,8 @@ BaseType_t prvTCPHandleState( FreeRTOS_Socket_t * pxSocket, */ FreeRTOS_Socket_t * prvHandleListen( FreeRTOS_Socket_t * pxSocket, NetworkBufferDescriptor_t * pxNetworkBuffer ); - + +const char * FreeRTOS_GetTCPStateName( UBaseType_t ulState ); /* *INDENT-OFF* */ #ifdef __cplusplus } /* extern "C" */ diff --git a/FreeRTOS/source/portable/NetworkInterface/Common/phyHandling.c b/FreeRTOS/source/portable/NetworkInterface/Common/phyHandling.c index ec6ca34..44687e0 100644 --- a/FreeRTOS/source/portable/NetworkInterface/Common/phyHandling.c +++ b/FreeRTOS/source/portable/NetworkInterface/Common/phyHandling.c @@ -253,7 +253,7 @@ BaseType_t xPhyDiscover( EthernetPhy_t * pxPhyObject ) if( pxPhyObject->xPortCount > 0 ) { - FreeRTOS_printf( ( "PHY ID %lX\n", pxPhyObject->ulPhyIDs[ 0 ] ) ); + FreeRTOS_printf( ( "PHY ID %lX\n", (UBaseType_t)pxPhyObject->ulPhyIDs[ 0 ] ) ); } return pxPhyObject->xPortCount; @@ -308,7 +308,7 @@ static uint32_t xPhyReset( EthernetPhy_t * pxPhyObject, if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE ) { - FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) ); + FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", (UBaseType_t)ulDoneMask ) ); break; } @@ -487,7 +487,7 @@ BaseType_t xPhyConfigure( EthernetPhy_t * pxPhyObject, pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_19_PHYCR, ulPhyControl ); } - FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) ); + FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", (UBaseType_t)ulAdvertise, (UBaseType_t)ulConfig ) ); } /* Keep these values for later use. */ @@ -597,7 +597,7 @@ BaseType_t xPhyStartAutoNegotiation( EthernetPhy_t * pxPhyObject, if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE ) { - FreeRTOS_printf( ( "xPhyStartAutoNegotiation: phyBMSR_AN_COMPLETE timed out ( done 0x%02lX )\n", ulDoneMask ) ); + FreeRTOS_printf( ( "xPhyStartAutoNegotiation: phyBMSR_AN_COMPLETE timed out ( done 0x%02lX )\n", (UBaseType_t)ulDoneMask ) ); break; } @@ -727,7 +727,7 @@ BaseType_t xPhyStartAutoNegotiation( EthernetPhy_t * pxPhyObject, } FreeRTOS_printf( ( "Autonego ready: %08lx: %s duplex %u mbit %s status\n", - ulRegValue, + (UBaseType_t)ulRegValue, ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half", ( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100, ( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0 ) ? "high" : "low" ) ); @@ -775,7 +775,7 @@ BaseType_t xPhyCheckLinkStatus( EthernetPhy_t * pxPhyObject, if( ( pxPhyObject->ulLinkStatusMask & ulBitMask ) == 0UL ) { pxPhyObject->ulLinkStatusMask |= ulBitMask; - FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) ); + FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", (UBaseType_t)pxPhyObject->ulLinkStatusMask ) ); xNeedCheck = pdTRUE; } } @@ -802,7 +802,7 @@ BaseType_t xPhyCheckLinkStatus( EthernetPhy_t * pxPhyObject, pxPhyObject->ulLinkStatusMask &= ~( ulBitMask ); } - FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) ); + FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", (UBaseType_t)pxPhyObject->ulLinkStatusMask ) ); xNeedCheck = pdTRUE; } } diff --git a/FreeRTOS/source/portable/NetworkInterface/board_family/NetworkInterface.c b/FreeRTOS/source/portable/NetworkInterface/board_family/NetworkInterface.c index faa73fb..61c9eef 100644 --- a/FreeRTOS/source/portable/NetworkInterface/board_family/NetworkInterface.c +++ b/FreeRTOS/source/portable/NetworkInterface/board_family/NetworkInterface.c @@ -1,3 +1,714 @@ +/* + * FreeRTOS+TCP Labs Build 160919 (C) 2016 Real Time Engineers ltd. + * Authors include Hein Tibosch and Richard Barry + * + ******************************************************************************* + ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE *** + *** *** + *** *** + *** FREERTOS+TCP IS STILL IN THE LAB (mainly because the FTP and HTTP *** + *** demos have a dependency on FreeRTOS+FAT, which is only in the Labs *** + *** download): *** + *** *** + *** FreeRTOS+TCP is functional and has been used in commercial products *** + *** for some time. Be aware however that we are still refining its *** + *** design, the source code does not yet quite conform to the strict *** + *** coding and style standards mandated by Real Time Engineers ltd., and *** + *** the documentation and testing is not necessarily complete. *** + *** *** + *** PLEASE REPORT EXPERIENCES USING THE SUPPORT RESOURCES FOUND ON THE *** + *** URL: http://www.FreeRTOS.org/contact Active early adopters may, at *** + *** the sole discretion of Real Time Engineers Ltd., be offered versions *** + *** under a license other than that described below. *** + *** *** + *** *** + ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE *** + ******************************************************************************* + * + * FreeRTOS+TCP can be used under two different free open source licenses. The + * license that applies is dependent on the processor on which FreeRTOS+TCP is + * executed, as follows: + * + * If FreeRTOS+TCP is executed on one of the processors listed under the Special + * License Arrangements heading of the FreeRTOS+TCP license information web + * page, then it can be used under the terms of the FreeRTOS Open Source + * License. If FreeRTOS+TCP is used on any other processor, then it can be used + * under the terms of the GNU General Public License V2. Links to the relevant + * licenses follow: + * + * The FreeRTOS+TCP License Information Page: http://www.FreeRTOS.org/tcp_license + * The FreeRTOS Open Source License: http://www.FreeRTOS.org/license + * The GNU General Public License Version 2: http://www.FreeRTOS.org/gpl-2.0.txt + * + * FreeRTOS+TCP is distributed in the hope that it will be useful. You cannot + * use FreeRTOS+TCP unless you agree that you use the software 'as is'. + * FreeRTOS+TCP is provided WITHOUT ANY WARRANTY; without even the implied + * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they + * implied, expressed, or statutory. + * + * 1 tab == 4 spaces! + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/plus + * http://www.FreeRTOS.org/labs + * + */ + +/* Standard includes. */ +#include +#include +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" +#include "FreeRTOS_IP_Private.h" +#include "NetworkBufferManagement.h" +#include "NetworkInterface.h" + +#include "Driver_ETH.h" +#include "Driver_ETH_MAC.h" +#include "Driver_ETH_PHY.h" +#include "gd32f10x_enet.h" +//#include "RTE_Components.h" +//#ifdef RTE_Drivers_PHY_DP83848C /* Driver PHY DP83848C */ + +//#endif + +static void receiveHandlerTask( void *pvParameters ); +static TaskHandle_t receiveHandler = NULL; + +static ARM_ETH_MAC_ADDR own_mac_address ;//device mac adress stores here. MSB first +static ARM_DRIVER_ETH_MAC *mac; +static ARM_ETH_MAC_CAPABILITIES capabilities; +//#define Driver_ETH_MAC0 ARM_Driver_ETH_MAC_(0) +//extern ARM_DRIVER_ETH_MAC Driver_ETH_MAC0; + +extern ARM_DRIVER_ETH_PHY ARM_Driver_ETH_PHY_(0); +#define Driver_ETH_PHY0 ARM_Driver_ETH_PHY_(0) + +/** + \fn ARM_DRIVER_VERSION ARM_ETH_MAC_GetVersion (void) + \brief Get driver version. + \return \ref ARM_DRIVER_VERSION +*/ +ARM_DRIVER_VERSION ARM_ETH_MAC_GetVersion (void) +{ + ARM_DRIVER_VERSION eth_mac_driver_version = {1,1}; + return eth_mac_driver_version; +} + +/** + \fn ARM_ETH_MAC_CAPABILITIES ARM_ETH_MAC_GetCapabilities (void) + \brief Get driver capabilities. + \return \ref ARM_ETH_MAC_CAPABILITIES +*/ +ARM_ETH_MAC_CAPABILITIES ARM_ETH_MAC_GetCapabilities (void) +{ + ARM_ETH_MAC_CAPABILITIES eth_mac_capabilities = { + 1, ///< 1 = IPv4 header checksum verified on receive + 1, ///< 1 = IPv6 checksum verification supported on receive + 1, ///< 1 = UDP payload checksum verified on receive + 1, ///< 1 = TCP payload checksum verified on receive + 1, ///< 1 = ICMP payload checksum verified on receive + 1, ///< 1 = IPv4 header checksum generated on transmit + 1, ///< 1 = IPv6 checksum generation supported on transmit + 1, ///< 1 = UDP payload checksum generated on transmit + 1, ///< 1 = TCP payload checksum generated on transmit + 1, ///< 1 = ICMP payload checksum generated on transmit + ARM_ETH_INTERFACE_RMII, ///< 0, 1, 2, 3, Ethernet Media Interface type + 1, ///< 1 = driver provides initial valid MAC address + 1, ///< 1 = callback event \ref ARM_ETH_MAC_EVENT_RX_FRAME generated + 1, ///< 1 = callback event \ref ARM_ETH_MAC_EVENT_TX_FRAME generated + 1, ///< 1 = wakeup event \ref ARM_ETH_MAC_EVENT_WAKEUP generated + 1, ///< 1 = Precision Timer supported + 0 ///< Reserved (must be zero) + }; + return eth_mac_capabilities; +} + +/** + \fn int32_t ARM_ETH_MAC_Initialize (ARM_ETH_MAC_SignalEvent_t cb_event) + \brief Initialize Ethernet MAC Device. + \param[in] cb_event Pointer to \ref ARM_ETH_MAC_SignalEvent + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_Initialize (ARM_ETH_MAC_SignalEvent_t cb_event) +{ + + ErrStatus xResult = ARM_DRIVER_ERROR; + if (SUCCESS == enet_init(ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_RECEIVEALL)) + xResult = ARM_DRIVER_OK; + //enet_ptp_start(int32_t updatemethod, uint32_t init_sec, uint32_t init_subsec, uint32_t carry_cfg, uint32_t accuracy_cfg) + return xResult; + + //enet_init(ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_RECEIVEALL); + //enet_ptp_start(int32_t updatemethod, uint32_t init_sec, uint32_t init_subsec, uint32_t carry_cfg, uint32_t accuracy_cfg) + //return pdTRUE; + +} + +/** + \fn int32_t ARM_ETH_MAC_Uninitialize (void) + \brief De-initialize Ethernet MAC Device. + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_Uninitialize (void) +{ + enet_deinit(); + return ARM_DRIVER_OK; +} + +/** + \fn int32_t ARM_ETH_MAC_PowerControl (ARM_POWER_STATE state) + \brief Control Ethernet MAC Device Power. + \param[in] state Power state + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_PowerControl (ARM_POWER_STATE state) +{ + + return ARM_DRIVER_OK; +} +/** + \fn int32_t ARM_ETH_MAC_GetMacAddress (ARM_ETH_MAC_ADDR *ptr_addr) + \brief Get Ethernet MAC Address. + \param[in] ptr_addr Pointer to address + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_GetMacAddress (ARM_ETH_MAC_ADDR *ptr_addr) +{ + if (ptr_addr != NULL) + { + enet_mac_address_get(ENET_MAC_ADDRESS0, (uint8_t*)ptr_addr->b); + return ARM_DRIVER_OK; + } + else return ARM_DRIVER_ERROR_PARAMETER; +} + +/** + \fn int32_t ARM_ETH_MAC_SetMacAddress (const ARM_ETH_MAC_ADDR *ptr_addr) + \brief Set Ethernet MAC Address. + \param[in] ptr_addr Pointer to address + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_SetMacAddress (const ARM_ETH_MAC_ADDR *ptr_addr) +{ + if (ptr_addr != NULL) + { + enet_mac_address_set(ENET_MAC_ADDRESS0, (uint8_t*)ptr_addr->b); + return ARM_DRIVER_OK; + } + else return ARM_DRIVER_ERROR_PARAMETER; +} + +/** + \fn int32_t ARM_ETH_MAC_SetAddressFilter (const ARM_ETH_MAC_ADDR *ptr_addr, + uint32_t num_addr) + \brief Configure Address Filter. + \param[in] ptr_addr Pointer to addresses + \param[in] num_addr Number of addresses to configure + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_SetAddressFilter (const ARM_ETH_MAC_ADDR *ptr_addr, uint32_t num_addr) +{ +#ifdef DEBUG + printf("ARM_ETH_MAC_SetAddressFilter\n"); + __asm volatile("BKPT #0\n") ; +#endif + enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE0, ENET_ADDRESS_FILTER_SA); + enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE1, ENET_ADDRESS_FILTER_SA); + enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE2, ENET_ADDRESS_FILTER_SA); + enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE3, ENET_ADDRESS_FILTER_SA); + enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE4, ENET_ADDRESS_FILTER_SA); + enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE5, ENET_ADDRESS_FILTER_SA); + return ARM_DRIVER_OK; +} + +/** + \fn int32_t ARM_ETH_MAC_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags) + \brief Send Ethernet frame. + \param[in] frame Pointer to frame buffer with data to send + \param[in] len Frame buffer length in bytes + \param[in] flags Frame transmit flags (see ARM_ETH_MAC_TX_FRAME_...) + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags) +{ +#ifdef DEBUG + printf("ARM_ETH_MAC_SendFrame\n"); +// __asm volatile("BKPT #0\n") ; +#endif + if (frame != NULL & len > 0) + { + if (SUCCESS == enet_frame_transmit((uint8_t*)frame, len)) + return ARM_DRIVER_OK; + else + return ARM_DRIVER_ERROR; + }else + return ARM_DRIVER_ERROR_PARAMETER; +} + +/** + \fn int32_t ARM_ETH_MAC_ReadFrame (uint8_t *frame, uint32_t len) + \brief Read data of received Ethernet frame. + \param[in] frame Pointer to frame buffer for data to read into + \param[in] len Frame buffer length in bytes + \return number of data bytes read or execution status + - value >= 0: number of data bytes read + - value < 0: error occurred, value is execution status as defined with \ref execution_status +*/ +int32_t ARM_ETH_MAC_ReadFrame (uint8_t *frame, uint32_t len) +{ +#ifdef DEBUG + printf("ARM_ETH_MAC_ReadFrame\n"); +// __asm volatile("BKPT #0\n") ; +#endif + if (frame != NULL & len > 0) + { + if (SUCCESS == enet_frame_receive(frame, len)) + return ARM_DRIVER_OK; + else + return ARM_DRIVER_ERROR; + }else + return ARM_DRIVER_ERROR_PARAMETER; +} + +/** + \fn uint32_t ARM_ETH_MAC_GetRxFrameSize (void) + \brief Get size of received Ethernet frame. + \return number of bytes in received frame +*/ +uint32_t ARM_ETH_MAC_GetRxFrameSize (void) +{ + return enet_rxframe_size_get(); +} + +/** + \fn int32_t ARM_ETH_MAC_GetRxFrameTime (ARM_ETH_MAC_TIME *time) + \brief Get time of received Ethernet frame. + \param[in] time Pointer to time structure for data to read into + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_GetRxFrameTime (ARM_ETH_MAC_TIME *time) +{ +#ifdef DEBUG + printf("ARM_ETH_MAC_GetRxFrameTime\n"); +// __asm volatile("BKPT #0\n") ; +#endif + //if ENET_RXTX_TIMESTAMP bit set in ENET_PTP_TSCTL register (enet_ptp_start(int32_t updatemethod, uint32_t init_sec, uint32_t init_subsec, uint32_t carry_cfg, uint32_t accuracy_cfg);) + enet_ptp_systime_struct systime_struct; + enet_ptp_system_time_get(&systime_struct); + time->sec = systime_struct.second; + time->ns = systime_struct.nanosecond; + return ARM_DRIVER_OK; +} + +/** + \fn int32_t ARM_ETH_MAC_GetTxFrameTime (ARM_ETH_MAC_TIME *time) + \brief Get time of transmitted Ethernet frame. + \param[in] time Pointer to time structure for data to read into + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_GetTxFrameTime (ARM_ETH_MAC_TIME *time) +{ +#ifdef DEBUG + printf("ARM_ETH_MAC_GetTxFrameTime\n"); +// __asm volatile("BKPT #0\n") ; +#endif + //if ENET_RXTX_TIMESTAMP bit set in ENET_PTP_TSCTL register (enet_ptp_timestamp_function_config(ENET_PTP_SYSTIME_INIT);) + enet_ptp_systime_struct systime_struct; + enet_ptp_system_time_get(&systime_struct); + time->sec = systime_struct.second; + time->ns = systime_struct.nanosecond; + return ARM_DRIVER_OK; +} + +/** + \fn int32_t ARM_ETH_MAC_Control (uint32_t control, uint32_t arg) + \brief Control Ethernet Interface. + \param[in] control Operation + \param[in] arg Argument of operation (optional) + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_Control (uint32_t control, uint32_t arg) +{ +#ifdef DEBUG + printf("ARM_ETH_MAC_Control\n"); +// __asm volatile("BKPT #0\n") ; +#endif + if((control >= 0) & (arg >= 0)) + { + if(SUCCESS == enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, control, (uint16_t*)&arg)) + return ARM_DRIVER_OK; + else + return ARM_DRIVER_ERROR; + }else + return ARM_DRIVER_ERROR_PARAMETER; +} + +/** + \fn int32_t ARM_ETH_MAC_ControlTimer (uint32_t control, ARM_ETH_MAC_TIME *time) + \brief Control Precision Timer. + \param[in] control Operation + \param[in] time Pointer to time structure + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_ControlTimer (uint32_t control, ARM_ETH_MAC_TIME *time) +{ +#ifdef DEBUG + printf("ARM_ETH_MAC_ControlTimer\n"); +// __asm volatile("BKPT #0\n") ; +#endif + if((control >= 0) & (time != NULL)) + { + if(SUCCESS == enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, control, (uint16_t*)time)) + return ARM_DRIVER_OK; + else + return ARM_DRIVER_ERROR; + }else + return ARM_DRIVER_ERROR_PARAMETER; +} + +/** + \fn int32_t ARM_ETH_MAC_PHY_Read (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data) + \brief Read Ethernet PHY Register through Management Interface. + \param[in] phy_addr 5-bit device address + \param[in] reg_addr 5-bit register address + \param[out] data Pointer where the result is written to + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_PHY_Read (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data) +{ + if((phy_addr >= 0) & (reg_addr >= 0x00) & data >= 0x0000) + { + if(SUCCESS == enet_phy_write_read(ENET_PHY_READ, phy_addr, reg_addr, data)) + return ARM_DRIVER_OK; + else + { +#ifdef DEBUG + printf("ARM_ETH_MAC_PHY_Read_ERROR\n"); +#endif + return ARM_DRIVER_ERROR; + } + }else +#ifdef DEBUG + printf("ARM_ETH_MAC_PHY_Read_ERROR_PARAMETER\n"); +#endif + return ARM_DRIVER_ERROR_PARAMETER; +} + +/** + \fn int32_t ARM_ETH_MAC_PHY_Write (uint8_t phy_addr, uint8_t reg_addr, uint16_t data) + \brief Write Ethernet PHY Register through Management Interface. + \param[in] phy_addr 5-bit device address + \param[in] reg_addr 5-bit register address + \param[in] data 16-bit data to write + \return \ref execution_status +*/ +int32_t ARM_ETH_MAC_PHY_Write (uint8_t phy_addr, uint8_t reg_addr, uint16_t data) +{ + if((phy_addr >= 0) & (reg_addr >= 0x00) & data >= 0x0000) + { + if(SUCCESS == enet_phy_write_read(ENET_PHY_WRITE, phy_addr, reg_addr, &data)) + return ARM_DRIVER_OK; + else + { +#ifdef DEBUG + printf("ARM_ETH_MAC_PHY_Write_ERROR\n"); +#endif + return ARM_DRIVER_ERROR; + } + }else +#ifdef DEBUG + printf("ARM_ETH_MAC_PHY_Write_ERROR_PARAMETER\n"); +#endif + return ARM_DRIVER_ERROR_PARAMETER; +} + +/** + \fn void ARM_ETH_MAC_SignalEvent (uint32_t event) + \brief Callback function that signals a Ethernet Event. + \param[in] event event notification mask + \return none +*/ + + +ARM_DRIVER_ETH_MAC Driver_ETH_MAC0 = {ARM_ETH_MAC_GetVersion, + ARM_ETH_MAC_GetCapabilities, + ARM_ETH_MAC_Initialize, + ARM_ETH_MAC_Uninitialize, + ARM_ETH_MAC_PowerControl, + ARM_ETH_MAC_GetMacAddress, + ARM_ETH_MAC_SetMacAddress, + ARM_ETH_MAC_SetAddressFilter, + ARM_ETH_MAC_SendFrame, + ARM_ETH_MAC_ReadFrame, + ARM_ETH_MAC_GetRxFrameSize, + ARM_ETH_MAC_GetRxFrameTime, + ARM_ETH_MAC_GetTxFrameTime, + ARM_ETH_MAC_ControlTimer, + ARM_ETH_MAC_Control, + ARM_ETH_MAC_PHY_Read, + ARM_ETH_MAC_PHY_Write}; + + + + + +/*callback function for ARM_ETH_MAC_SignalEvent_t*/ +void ethernet_mac_notify (uint32_t event) { + switch (event) { + case ARM_ETH_MAC_EVENT_RX_FRAME: + /*received frame,call receive fuction*/ + //led1_toggle(); + xTaskNotifyGive( receiveHandler ); + break; + + case ARM_ETH_MAC_EVENT_TX_FRAME: + /* deliver finished */ + break; + + case ARM_ETH_MAC_EVENT_WAKEUP: + break; + + case ARM_ETH_MAC_EVENT_TIMER_ALARM: + /* do nothing */ + break; + } +} + +/* init the mac */ +int32_t macIntialise(void) +{ + own_mac_address.b[0] = configMAC_ADDR0; + own_mac_address.b[1] = configMAC_ADDR1; + own_mac_address.b[2] = configMAC_ADDR2; + own_mac_address.b[3] = configMAC_ADDR3; + own_mac_address.b[4] = configMAC_ADDR4; + own_mac_address.b[5] = configMAC_ADDR5; + + + + mac = &Driver_ETH_MAC0; + capabilities = mac->GetCapabilities (); + + + + if(mac->Initialize (ethernet_mac_notify) == ARM_DRIVER_OK && mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK){ + + if (capabilities.mac_address == 0) { + // populate own_mac_address with the address to use.-----the fact situation + mac->SetMacAddress(&own_mac_address); + } + else { + mac->GetMacAddress(&own_mac_address); + } + + return ARM_DRIVER_OK; + } + else{ + return ARM_DRIVER_ERROR; + } +} + +/* init the phy */ + int32_t phyIntialise(void){ + int32_t state = ARM_DRIVER_OK; + + /* link the mac and phy through MAC0.PHY_Read() and MAC0.PHY_write */ + if(Driver_ETH_PHY0.Initialize(Driver_ETH_MAC0.PHY_Read,Driver_ETH_MAC0.PHY_Write)!= ARM_DRIVER_OK){ + state = ARM_DRIVER_ERROR; + return state; + } + + /* power on */ + if(Driver_ETH_PHY0.PowerControl(ARM_POWER_FULL)!=ARM_DRIVER_OK){ + state = ARM_DRIVER_ERROR; + return state; + } + + /* set RMII interface */ + if(Driver_ETH_PHY0.SetInterface (capabilities.media_interface)!=ARM_DRIVER_OK){ + state = ARM_DRIVER_ERROR; + return state; + } + + /* set mode */ + if(Driver_ETH_PHY0.SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE)!=ARM_DRIVER_OK){ + state = ARM_DRIVER_ERROR; + return state; + } + + return state; +} + +/*init the mac and phy*/ +BaseType_t xNetworkInterfaceInitialise( void ) +{ + static ARM_ETH_LINK_INFO info; + BaseType_t state = pdFALSE; + if(state == pdFALSE){ + state = xTaskCreate( receiveHandlerTask, "receiveHandlerTask", 1000, NULL, 1, &receiveHandler ); + } + + if(macIntialise() == ARM_DRIVER_OK && phyIntialise() ==ARM_DRIVER_OK){ + ARM_ETH_LINK_STATE link = Driver_ETH_PHY0.GetLinkState (); + + while(link != ARM_ETH_LINK_UP){ + link = Driver_ETH_PHY0.GetLinkState (); + } + + info = Driver_ETH_PHY0.GetLinkInfo (); + mac->Control(ARM_ETH_MAC_CONFIGURE, + info.speed << ARM_ETH_MAC_SPEED_Pos | + info.duplex << ARM_ETH_MAC_DUPLEX_Pos | + ARM_ETH_MAC_ADDRESS_BROADCAST); + mac->Control(ARM_ETH_MAC_CONTROL_TX, 1); + mac->Control(ARM_ETH_MAC_CONTROL_RX, 1); + return pdPASS; + } + else{ + //error + return pdFALSE; + } +} +/*-----------------------------------------------------------*/ + + +/* send tcp/ip buffer to mac buffer */ +static void sendData(uint8_t *pucEthernetBuffer,size_t xDataLength){ + if(mac->SendFrame(pucEthernetBuffer,xDataLength,ARM_ETH_MAC_TX_FRAME_EVENT|ARM_ETH_MAC_TX_FRAME_TIMESTAMP) == ARM_DRIVER_OK){ + //success + } + else{ + //error + } +} + + +/* send frame */ +#if ( ipconfigZERO_COPY_TX_DRIVER == 0) +/*the Simple network interfaces ,just use Ethernet peripheral driver library functions to copy +data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer.*/ +BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,BaseType_t xReleaseAfterSend ){ + /* Simple network interfaces (as opposed to more efficient zero copy network + interfaces) just use Ethernet peripheral driver library functions to copy + data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer. + This example assumes SendData() is a peripheral driver library function that + takes a pointer to the start of the data to be sent and the length of the + data to be sent as two separate parameters. The start of the data is located + by pxDescriptor->pucEthernetBuffer. The length of the data is located + by pxDescriptor->xDataLength. */ + sendData( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength ); + + /* Call the standard trace macro to log the send event. */ + iptraceNETWORK_INTERFACE_TRANSMIT(); + + if( xReleaseAfterSend != pdFALSE ) + { + /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet + buffer. The Ethernet buffer is therefore no longer needed, and must be + freed for re-use. */ + vReleaseNetworkBufferAndDescriptor( pxDescriptor ); + } + + return pdTRUE; +} +#else +/*zero copy method here*/ + +#endif +/*-----------------------------------------------------------*/ + +/*receive data func , will be notify after ARM_ETH_MAC_EVENT_RX_FRAME event*/ +#if (ipconfigZERO_COPY_RX_DRIVER==0) +static void receiveHandlerTask( void *pvParameters ){ + NetworkBufferDescriptor_t *receiveBufferDescriptor; + size_t xBytesReceived; + /* Used to indicate that xSendEventStructToIPTask() is being called becauseof an Ethernet receive event. */ + IPStackEvent_t xRxEvent; + + while(1){ + /* Wait for the Ethernet MAC interrupt to indicate that another packet + has been received. The task notification is used in a similar way to a + counting semaphore to count Rx events, but is a lot more efficient than + a semaphore. */ + ulTaskNotifyTake( pdFALSE, portMAX_DELAY ); + + /* See how much data was received. Here it is assumed ReceiveSize() is + a peripheral driver function that returns the number of bytes in the + received Ethernet frame. */ + xBytesReceived = mac->GetRxFrameSize(); + + if( xBytesReceived > 0 ){ + /* Allocate a network buffer descriptor that points to a buffer + large enough to hold the received frame. As this is the simple + rather than efficient example the received data will just be copied + into this buffer. */ + receiveBufferDescriptor = pxGetNetworkBufferWithDescriptor( xBytesReceived, 0 ); + if( receiveBufferDescriptor != NULL ){ + /* pxBufferDescriptor->pucEthernetBuffer now points to an Ethernet + buffer large enough to hold the received data. Copy the + received data into pcNetworkBuffer->pucEthernetBuffer. Here it + is assumed ReceiveData() is a peripheral driver function that + copies the received data into a buffer passed in as the function's + parameter. Remember! While is is a simple robust technique - + it is not efficient. An example that uses a zero copy technique + is provided further down this page. */ + mac->ReadFrame(receiveBufferDescriptor->pucEthernetBuffer,xBytesReceived); + receiveBufferDescriptor->xDataLength = xBytesReceived; + + /* See if the data contained in the received Ethernet frame needs + to be processed. NOTE! It is preferable to do this in + the interrupt service routine itself, which would remove the need + to unblock this task for packets that don't need processing. */ + if( eConsiderFrameForProcessing( receiveBufferDescriptor->pucEthernetBuffer )== eProcessBuffer ){ + /* The event about to be sent to the TCP/IP is an Rx event. */ + xRxEvent.eEventType = eNetworkRxEvent; + + /* pvData is used to point to the network buffer descriptor that + now references the received data. */ + xRxEvent.pvData = ( void * ) receiveBufferDescriptor; + + /* Send the data to the TCP/IP stack. */ + if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE ){ + /* The buffer could not be sent to the IP task so the buffer must be released. */ + vReleaseNetworkBufferAndDescriptor( receiveBufferDescriptor ); + + /* Make a call to the standard trace macro to log the occurrence. */ + iptraceETHERNET_RX_EVENT_LOST(); + }else{ + /* The message was successfully sent to the TCP/IP stack. + Call the standard trace macro to log the occurrence. */ + iptraceNETWORK_INTERFACE_RECEIVE(); + } + }else{ + /* The Ethernet frame can be dropped, but the Ethernet buffer + must be released. */ + vReleaseNetworkBufferAndDescriptor( receiveBufferDescriptor ); + } + + }else{ + /* The event was lost because a network buffer was not available. + Call the standard trace macro to log the occurrence. */ + iptraceETHERNET_RX_EVENT_LOST(); + } + } + } +} +#else +/*zero copy method here*/ + +#endif ///* // * FreeRTOS+TCP V3.1.0 // * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -1363,716 +2074,6 @@ * library, COPYRIGHT(c) 2015 STMicroelectronics. */ -/* - * FreeRTOS+TCP Labs Build 160919 (C) 2016 Real Time Engineers ltd. - * Authors include Hein Tibosch and Richard Barry - * - ******************************************************************************* - ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE *** - *** *** - *** *** - *** FREERTOS+TCP IS STILL IN THE LAB (mainly because the FTP and HTTP *** - *** demos have a dependency on FreeRTOS+FAT, which is only in the Labs *** - *** download): *** - *** *** - *** FreeRTOS+TCP is functional and has been used in commercial products *** - *** for some time. Be aware however that we are still refining its *** - *** design, the source code does not yet quite conform to the strict *** - *** coding and style standards mandated by Real Time Engineers ltd., and *** - *** the documentation and testing is not necessarily complete. *** - *** *** - *** PLEASE REPORT EXPERIENCES USING THE SUPPORT RESOURCES FOUND ON THE *** - *** URL: http://www.FreeRTOS.org/contact Active early adopters may, at *** - *** the sole discretion of Real Time Engineers Ltd., be offered versions *** - *** under a license other than that described below. *** - *** *** - *** *** - ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE *** - ******************************************************************************* - * - * FreeRTOS+TCP can be used under two different free open source licenses. The - * license that applies is dependent on the processor on which FreeRTOS+TCP is - * executed, as follows: - * - * If FreeRTOS+TCP is executed on one of the processors listed under the Special - * License Arrangements heading of the FreeRTOS+TCP license information web - * page, then it can be used under the terms of the FreeRTOS Open Source - * License. If FreeRTOS+TCP is used on any other processor, then it can be used - * under the terms of the GNU General Public License V2. Links to the relevant - * licenses follow: - * - * The FreeRTOS+TCP License Information Page: http://www.FreeRTOS.org/tcp_license - * The FreeRTOS Open Source License: http://www.FreeRTOS.org/license - * The GNU General Public License Version 2: http://www.FreeRTOS.org/gpl-2.0.txt - * - * FreeRTOS+TCP is distributed in the hope that it will be useful. You cannot - * use FreeRTOS+TCP unless you agree that you use the software 'as is'. - * FreeRTOS+TCP is provided WITHOUT ANY WARRANTY; without even the implied - * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they - * implied, expressed, or statutory. - * - * 1 tab == 4 spaces! - * - * http://www.FreeRTOS.org - * http://www.FreeRTOS.org/plus - * http://www.FreeRTOS.org/labs - * - */ -/* Standard includes. */ -#include -#include -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "semphr.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" -#include "FreeRTOS_IP_Private.h" -#include "NetworkBufferManagement.h" -#include "NetworkInterface.h" - -#include "Driver_ETH.h" -#include "Driver_ETH_MAC.h" -#include "Driver_ETH_PHY.h" -#include "gd32f10x_enet.h" -//#include "RTE_Components.h" -//#ifdef RTE_Drivers_PHY_DP83848C /* Driver PHY DP83848C */ - -//#endif - -static void receiveHandlerTask( void *pvParameters ); -static TaskHandle_t receiveHandler = NULL; - -static ARM_ETH_MAC_ADDR own_mac_address ;//device mac adress stores here. MSB first -static ARM_DRIVER_ETH_MAC *mac; -static ARM_ETH_MAC_CAPABILITIES capabilities; -//#define Driver_ETH_MAC0 ARM_Driver_ETH_MAC_(0) -//extern ARM_DRIVER_ETH_MAC Driver_ETH_MAC0; - -extern ARM_DRIVER_ETH_PHY ARM_Driver_ETH_PHY_(0); -#define Driver_ETH_PHY0 ARM_Driver_ETH_PHY_(0) - -/** - \fn ARM_DRIVER_VERSION ARM_ETH_MAC_GetVersion (void) - \brief Get driver version. - \return \ref ARM_DRIVER_VERSION -*/ -ARM_DRIVER_VERSION ARM_ETH_MAC_GetVersion (void) -{ - ARM_DRIVER_VERSION eth_mac_driver_version = {1,1}; - return eth_mac_driver_version; -} - -/** - \fn ARM_ETH_MAC_CAPABILITIES ARM_ETH_MAC_GetCapabilities (void) - \brief Get driver capabilities. - \return \ref ARM_ETH_MAC_CAPABILITIES -*/ -ARM_ETH_MAC_CAPABILITIES ARM_ETH_MAC_GetCapabilities (void) -{ - ARM_ETH_MAC_CAPABILITIES eth_mac_capabilities = { - 1, ///< 1 = IPv4 header checksum verified on receive - 1, ///< 1 = IPv6 checksum verification supported on receive - 1, ///< 1 = UDP payload checksum verified on receive - 1, ///< 1 = TCP payload checksum verified on receive - 1, ///< 1 = ICMP payload checksum verified on receive - 1, ///< 1 = IPv4 header checksum generated on transmit - 1, ///< 1 = IPv6 checksum generation supported on transmit - 1, ///< 1 = UDP payload checksum generated on transmit - 1, ///< 1 = TCP payload checksum generated on transmit - 1, ///< 1 = ICMP payload checksum generated on transmit - ARM_ETH_INTERFACE_RMII, ///< 0, 1, 2, 3, Ethernet Media Interface type - 1, ///< 1 = driver provides initial valid MAC address - 1, ///< 1 = callback event \ref ARM_ETH_MAC_EVENT_RX_FRAME generated - 1, ///< 1 = callback event \ref ARM_ETH_MAC_EVENT_TX_FRAME generated - 1, ///< 1 = wakeup event \ref ARM_ETH_MAC_EVENT_WAKEUP generated - 1, ///< 1 = Precision Timer supported - 0 ///< Reserved (must be zero) - }; - return eth_mac_capabilities; -} - -/** - \fn int32_t ARM_ETH_MAC_Initialize (ARM_ETH_MAC_SignalEvent_t cb_event) - \brief Initialize Ethernet MAC Device. - \param[in] cb_event Pointer to \ref ARM_ETH_MAC_SignalEvent - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_Initialize (ARM_ETH_MAC_SignalEvent_t cb_event) -{ - - ErrStatus xResult = ARM_DRIVER_ERROR; - if (SUCCESS == enet_init(ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_RECEIVEALL)) - xResult = ARM_DRIVER_OK; - //enet_ptp_start(int32_t updatemethod, uint32_t init_sec, uint32_t init_subsec, uint32_t carry_cfg, uint32_t accuracy_cfg) - return xResult; - - //enet_init(ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_RECEIVEALL); - //enet_ptp_start(int32_t updatemethod, uint32_t init_sec, uint32_t init_subsec, uint32_t carry_cfg, uint32_t accuracy_cfg) - //return pdTRUE; - -} - -/** - \fn int32_t ARM_ETH_MAC_Uninitialize (void) - \brief De-initialize Ethernet MAC Device. - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_Uninitialize (void) -{ - enet_deinit(); - return ARM_DRIVER_OK; -} - -/** - \fn int32_t ARM_ETH_MAC_PowerControl (ARM_POWER_STATE state) - \brief Control Ethernet MAC Device Power. - \param[in] state Power state - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_PowerControl (ARM_POWER_STATE state) -{ - - return ARM_DRIVER_OK; -} -/** - \fn int32_t ARM_ETH_MAC_GetMacAddress (ARM_ETH_MAC_ADDR *ptr_addr) - \brief Get Ethernet MAC Address. - \param[in] ptr_addr Pointer to address - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_GetMacAddress (ARM_ETH_MAC_ADDR *ptr_addr) -{ - if (ptr_addr != NULL) - { - enet_mac_address_get(ENET_MAC_ADDRESS0, (uint8_t*)ptr_addr->b); - return ARM_DRIVER_OK; - } - else return ARM_DRIVER_ERROR_PARAMETER; -} - -/** - \fn int32_t ARM_ETH_MAC_SetMacAddress (const ARM_ETH_MAC_ADDR *ptr_addr) - \brief Set Ethernet MAC Address. - \param[in] ptr_addr Pointer to address - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_SetMacAddress (const ARM_ETH_MAC_ADDR *ptr_addr) -{ - if (ptr_addr != NULL) - { - enet_mac_address_set(ENET_MAC_ADDRESS0, (uint8_t*)ptr_addr->b); - return ARM_DRIVER_OK; - } - else return ARM_DRIVER_ERROR_PARAMETER; -} - -/** - \fn int32_t ARM_ETH_MAC_SetAddressFilter (const ARM_ETH_MAC_ADDR *ptr_addr, - uint32_t num_addr) - \brief Configure Address Filter. - \param[in] ptr_addr Pointer to addresses - \param[in] num_addr Number of addresses to configure - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_SetAddressFilter (const ARM_ETH_MAC_ADDR *ptr_addr, uint32_t num_addr) -{ -#ifdef DEBUG - printf("ARM_ETH_MAC_SetAddressFilter\n"); - __asm volatile("BKPT #0\n") ; -#endif - enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE0, ENET_ADDRESS_FILTER_SA); - enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE1, ENET_ADDRESS_FILTER_SA); - enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE2, ENET_ADDRESS_FILTER_SA); - enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE3, ENET_ADDRESS_FILTER_SA); - enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE4, ENET_ADDRESS_FILTER_SA); - enet_address_filter_config(ENET_MAC_ADDRESS0, ENET_ADDRESS_MASK_BYTE5, ENET_ADDRESS_FILTER_SA); - return ARM_DRIVER_OK; -} - -/** - \fn int32_t ARM_ETH_MAC_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags) - \brief Send Ethernet frame. - \param[in] frame Pointer to frame buffer with data to send - \param[in] len Frame buffer length in bytes - \param[in] flags Frame transmit flags (see ARM_ETH_MAC_TX_FRAME_...) - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags) -{ -#ifdef DEBUG - printf("ARM_ETH_MAC_SendFrame\n"); -// __asm volatile("BKPT #0\n") ; -#endif - if (frame != NULL & len > 0) - { - if (SUCCESS == enet_frame_transmit((uint8_t*)frame, len)) - return ARM_DRIVER_OK; - else - return ARM_DRIVER_ERROR; - }else - return ARM_DRIVER_ERROR_PARAMETER; -} - -/** - \fn int32_t ARM_ETH_MAC_ReadFrame (uint8_t *frame, uint32_t len) - \brief Read data of received Ethernet frame. - \param[in] frame Pointer to frame buffer for data to read into - \param[in] len Frame buffer length in bytes - \return number of data bytes read or execution status - - value >= 0: number of data bytes read - - value < 0: error occurred, value is execution status as defined with \ref execution_status -*/ -int32_t ARM_ETH_MAC_ReadFrame (uint8_t *frame, uint32_t len) -{ -#ifdef DEBUG - printf("ARM_ETH_MAC_ReadFrame\n"); -// __asm volatile("BKPT #0\n") ; -#endif - if (frame != NULL & len > 0) - { - if (SUCCESS == enet_frame_receive(frame, len)) - return ARM_DRIVER_OK; - else - return ARM_DRIVER_ERROR; - }else - return ARM_DRIVER_ERROR_PARAMETER; -} - -/** - \fn uint32_t ARM_ETH_MAC_GetRxFrameSize (void) - \brief Get size of received Ethernet frame. - \return number of bytes in received frame -*/ -uint32_t ARM_ETH_MAC_GetRxFrameSize (void) -{ - return enet_rxframe_size_get(); -} - -/** - \fn int32_t ARM_ETH_MAC_GetRxFrameTime (ARM_ETH_MAC_TIME *time) - \brief Get time of received Ethernet frame. - \param[in] time Pointer to time structure for data to read into - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_GetRxFrameTime (ARM_ETH_MAC_TIME *time) -{ -#ifdef DEBUG - printf("ARM_ETH_MAC_GetRxFrameTime\n"); -// __asm volatile("BKPT #0\n") ; -#endif - //if ENET_RXTX_TIMESTAMP bit set in ENET_PTP_TSCTL register (enet_ptp_start(int32_t updatemethod, uint32_t init_sec, uint32_t init_subsec, uint32_t carry_cfg, uint32_t accuracy_cfg);) - enet_ptp_systime_struct systime_struct; - enet_ptp_system_time_get(&systime_struct); - time->sec = systime_struct.second; - time->ns = systime_struct.nanosecond; - return ARM_DRIVER_OK; -} - -/** - \fn int32_t ARM_ETH_MAC_GetTxFrameTime (ARM_ETH_MAC_TIME *time) - \brief Get time of transmitted Ethernet frame. - \param[in] time Pointer to time structure for data to read into - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_GetTxFrameTime (ARM_ETH_MAC_TIME *time) -{ -#ifdef DEBUG - printf("ARM_ETH_MAC_GetTxFrameTime\n"); -// __asm volatile("BKPT #0\n") ; -#endif - //if ENET_RXTX_TIMESTAMP bit set in ENET_PTP_TSCTL register (enet_ptp_timestamp_function_config(ENET_PTP_SYSTIME_INIT);) - enet_ptp_systime_struct systime_struct; - enet_ptp_system_time_get(&systime_struct); - time->sec = systime_struct.second; - time->ns = systime_struct.nanosecond; - return ARM_DRIVER_OK; -} - -/** - \fn int32_t ARM_ETH_MAC_Control (uint32_t control, uint32_t arg) - \brief Control Ethernet Interface. - \param[in] control Operation - \param[in] arg Argument of operation (optional) - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_Control (uint32_t control, uint32_t arg) -{ -#ifdef DEBUG - printf("ARM_ETH_MAC_Control\n"); -// __asm volatile("BKPT #0\n") ; -#endif - if((control >= 0) & (arg >= 0)) - { - if(SUCCESS == enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, control, (uint16_t*)&arg)) - return ARM_DRIVER_OK; - else - return ARM_DRIVER_ERROR; - }else - return ARM_DRIVER_ERROR_PARAMETER; -} - -/** - \fn int32_t ARM_ETH_MAC_ControlTimer (uint32_t control, ARM_ETH_MAC_TIME *time) - \brief Control Precision Timer. - \param[in] control Operation - \param[in] time Pointer to time structure - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_ControlTimer (uint32_t control, ARM_ETH_MAC_TIME *time) -{ -#ifdef DEBUG - printf("ARM_ETH_MAC_ControlTimer\n"); -// __asm volatile("BKPT #0\n") ; -#endif - if((control >= 0) & (time != NULL)) - { - if(SUCCESS == enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, control, (uint16_t*)time)) - return ARM_DRIVER_OK; - else - return ARM_DRIVER_ERROR; - }else - return ARM_DRIVER_ERROR_PARAMETER; -} - -/** - \fn int32_t ARM_ETH_MAC_PHY_Read (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data) - \brief Read Ethernet PHY Register through Management Interface. - \param[in] phy_addr 5-bit device address - \param[in] reg_addr 5-bit register address - \param[out] data Pointer where the result is written to - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_PHY_Read (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data) -{ - if((phy_addr >= 0) & (reg_addr >= 0x00) & data >= 0x0000) - { - if(SUCCESS == enet_phy_write_read(ENET_PHY_READ, phy_addr, reg_addr, data)) - return ARM_DRIVER_OK; - else - { -#ifdef DEBUG - printf("ARM_ETH_MAC_PHY_Read_ERROR\n"); -#endif - return ARM_DRIVER_ERROR; - } - }else -#ifdef DEBUG - printf("ARM_ETH_MAC_PHY_Read_ERROR_PARAMETER\n"); -#endif - return ARM_DRIVER_ERROR_PARAMETER; -} - -/** - \fn int32_t ARM_ETH_MAC_PHY_Write (uint8_t phy_addr, uint8_t reg_addr, uint16_t data) - \brief Write Ethernet PHY Register through Management Interface. - \param[in] phy_addr 5-bit device address - \param[in] reg_addr 5-bit register address - \param[in] data 16-bit data to write - \return \ref execution_status -*/ -int32_t ARM_ETH_MAC_PHY_Write (uint8_t phy_addr, uint8_t reg_addr, uint16_t data) -{ - if((phy_addr >= 0) & (reg_addr >= 0x00) & data >= 0x0000) - { - if(SUCCESS == enet_phy_write_read(ENET_PHY_WRITE, phy_addr, reg_addr, &data)) - return ARM_DRIVER_OK; - else - { -#ifdef DEBUG - printf("ARM_ETH_MAC_PHY_Write_ERROR\n"); -#endif - return ARM_DRIVER_ERROR; - } - }else -#ifdef DEBUG - printf("ARM_ETH_MAC_PHY_Write_ERROR_PARAMETER\n"); -#endif - return ARM_DRIVER_ERROR_PARAMETER; -} - -/** - \fn void ARM_ETH_MAC_SignalEvent (uint32_t event) - \brief Callback function that signals a Ethernet Event. - \param[in] event event notification mask - \return none -*/ - - -ARM_DRIVER_ETH_MAC Driver_ETH_MAC0 = {ARM_ETH_MAC_GetVersion, - ARM_ETH_MAC_GetCapabilities, - ARM_ETH_MAC_Initialize, - ARM_ETH_MAC_Uninitialize, - ARM_ETH_MAC_PowerControl, - ARM_ETH_MAC_GetMacAddress, - ARM_ETH_MAC_SetMacAddress, - ARM_ETH_MAC_SetAddressFilter, - ARM_ETH_MAC_SendFrame, - ARM_ETH_MAC_ReadFrame, - ARM_ETH_MAC_GetRxFrameSize, - ARM_ETH_MAC_GetRxFrameTime, - ARM_ETH_MAC_GetTxFrameTime, - ARM_ETH_MAC_ControlTimer, - ARM_ETH_MAC_Control, - ARM_ETH_MAC_PHY_Read, - ARM_ETH_MAC_PHY_Write}; - - - - - -/*callback function for ARM_ETH_MAC_SignalEvent_t*/ -void ethernet_mac_notify (uint32_t event) { - switch (event) { - case ARM_ETH_MAC_EVENT_RX_FRAME: - /*received frame,call receive fuction*/ - //led1_toggle(); - xTaskNotifyGive( receiveHandler ); - break; - - case ARM_ETH_MAC_EVENT_TX_FRAME: - /* deliver finished */ - break; - - case ARM_ETH_MAC_EVENT_WAKEUP: - break; - - case ARM_ETH_MAC_EVENT_TIMER_ALARM: - /* do nothing */ - break; - } -} - -/* init the mac */ -int32_t macIntialise(void) -{ - own_mac_address.b[0] = configMAC_ADDR0; - own_mac_address.b[1] = configMAC_ADDR1; - own_mac_address.b[2] = configMAC_ADDR2; - own_mac_address.b[3] = configMAC_ADDR3; - own_mac_address.b[4] = configMAC_ADDR4; - own_mac_address.b[5] = configMAC_ADDR5; - - - - mac = &Driver_ETH_MAC0; - capabilities = mac->GetCapabilities (); - - - - if(mac->Initialize (ethernet_mac_notify) == ARM_DRIVER_OK && mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK){ - - if (capabilities.mac_address == 0) { - // populate own_mac_address with the address to use.-----the fact situation - mac->SetMacAddress(&own_mac_address); - } - else { - mac->GetMacAddress(&own_mac_address); - } - - return ARM_DRIVER_OK; - } - else{ - return ARM_DRIVER_ERROR; - } -} - -/* init the phy */ - int32_t phyIntialise(void){ - int32_t state = ARM_DRIVER_OK; - - /* link the mac and phy through MAC0.PHY_Read() and MAC0.PHY_write */ - if(Driver_ETH_PHY0.Initialize(Driver_ETH_MAC0.PHY_Read,Driver_ETH_MAC0.PHY_Write)!= ARM_DRIVER_OK){ - state = ARM_DRIVER_ERROR; - return state; - } - - /* power on */ - if(Driver_ETH_PHY0.PowerControl(ARM_POWER_FULL)!=ARM_DRIVER_OK){ - state = ARM_DRIVER_ERROR; - return state; - } - - /* set RMII interface */ - if(Driver_ETH_PHY0.SetInterface (capabilities.media_interface)!=ARM_DRIVER_OK){ - state = ARM_DRIVER_ERROR; - return state; - } - - /* set mode */ - if(Driver_ETH_PHY0.SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE)!=ARM_DRIVER_OK){ - state = ARM_DRIVER_ERROR; - return state; - } - - return state; -} - -/*init the mac and phy*/ -BaseType_t xNetworkInterfaceInitialise( void ) -{ - static ARM_ETH_LINK_INFO info; - BaseType_t state = pdFALSE; - if(state == pdFALSE){ - state = xTaskCreate( receiveHandlerTask, "receiveHandlerTask", 1000, NULL, 1, &receiveHandler ); - } - - if(macIntialise() == ARM_DRIVER_OK && phyIntialise() ==ARM_DRIVER_OK){ - ARM_ETH_LINK_STATE link = Driver_ETH_PHY0.GetLinkState (); - - while(link != ARM_ETH_LINK_UP){ - link = Driver_ETH_PHY0.GetLinkState (); - } - - info = Driver_ETH_PHY0.GetLinkInfo (); - mac->Control(ARM_ETH_MAC_CONFIGURE, - info.speed << ARM_ETH_MAC_SPEED_Pos | - info.duplex << ARM_ETH_MAC_DUPLEX_Pos | - ARM_ETH_MAC_ADDRESS_BROADCAST); - mac->Control(ARM_ETH_MAC_CONTROL_TX, 1); - mac->Control(ARM_ETH_MAC_CONTROL_RX, 1); - return pdPASS; - } - else{ - //error - return pdFALSE; - } -} -/*-----------------------------------------------------------*/ - - -/* send tcp/ip buffer to mac buffer */ -static void sendData(uint8_t *pucEthernetBuffer,size_t xDataLength){ - if(mac->SendFrame(pucEthernetBuffer,xDataLength,ARM_ETH_MAC_TX_FRAME_EVENT|ARM_ETH_MAC_TX_FRAME_TIMESTAMP) == ARM_DRIVER_OK){ - //success - } - else{ - //error - } -} - - -/* send frame */ -#if ( ipconfigZERO_COPY_TX_DRIVER == 0) -/*the Simple network interfaces ,just use Ethernet peripheral driver library functions to copy -data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer.*/ -BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,BaseType_t xReleaseAfterSend ){ - /* Simple network interfaces (as opposed to more efficient zero copy network - interfaces) just use Ethernet peripheral driver library functions to copy - data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer. - This example assumes SendData() is a peripheral driver library function that - takes a pointer to the start of the data to be sent and the length of the - data to be sent as two separate parameters. The start of the data is located - by pxDescriptor->pucEthernetBuffer. The length of the data is located - by pxDescriptor->xDataLength. */ - sendData( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength ); - - /* Call the standard trace macro to log the send event. */ - iptraceNETWORK_INTERFACE_TRANSMIT(); - - if( xReleaseAfterSend != pdFALSE ) - { - /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet - buffer. The Ethernet buffer is therefore no longer needed, and must be - freed for re-use. */ - vReleaseNetworkBufferAndDescriptor( pxDescriptor ); - } - - return pdTRUE; -} -#else -/*zero copy method here*/ - -#endif -/*-----------------------------------------------------------*/ - -/*receive data func , will be notify after ARM_ETH_MAC_EVENT_RX_FRAME event*/ -#if (ipconfigZERO_COPY_RX_DRIVER==0) -static void receiveHandlerTask( void *pvParameters ){ - NetworkBufferDescriptor_t *receiveBufferDescriptor; - size_t xBytesReceived; - /* Used to indicate that xSendEventStructToIPTask() is being called becauseof an Ethernet receive event. */ - IPStackEvent_t xRxEvent; - - while(1){ - /* Wait for the Ethernet MAC interrupt to indicate that another packet - has been received. The task notification is used in a similar way to a - counting semaphore to count Rx events, but is a lot more efficient than - a semaphore. */ - ulTaskNotifyTake( pdFALSE, portMAX_DELAY ); - - /* See how much data was received. Here it is assumed ReceiveSize() is - a peripheral driver function that returns the number of bytes in the - received Ethernet frame. */ - xBytesReceived = mac->GetRxFrameSize(); - - if( xBytesReceived > 0 ){ - /* Allocate a network buffer descriptor that points to a buffer - large enough to hold the received frame. As this is the simple - rather than efficient example the received data will just be copied - into this buffer. */ - receiveBufferDescriptor = pxGetNetworkBufferWithDescriptor( xBytesReceived, 0 ); - if( receiveBufferDescriptor != NULL ){ - /* pxBufferDescriptor->pucEthernetBuffer now points to an Ethernet - buffer large enough to hold the received data. Copy the - received data into pcNetworkBuffer->pucEthernetBuffer. Here it - is assumed ReceiveData() is a peripheral driver function that - copies the received data into a buffer passed in as the function's - parameter. Remember! While is is a simple robust technique - - it is not efficient. An example that uses a zero copy technique - is provided further down this page. */ - mac->ReadFrame(receiveBufferDescriptor->pucEthernetBuffer,xBytesReceived); - receiveBufferDescriptor->xDataLength = xBytesReceived; - - /* See if the data contained in the received Ethernet frame needs - to be processed. NOTE! It is preferable to do this in - the interrupt service routine itself, which would remove the need - to unblock this task for packets that don't need processing. */ - if( eConsiderFrameForProcessing( receiveBufferDescriptor->pucEthernetBuffer )== eProcessBuffer ){ - /* The event about to be sent to the TCP/IP is an Rx event. */ - xRxEvent.eEventType = eNetworkRxEvent; - - /* pvData is used to point to the network buffer descriptor that - now references the received data. */ - xRxEvent.pvData = ( void * ) receiveBufferDescriptor; - - /* Send the data to the TCP/IP stack. */ - if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE ){ - /* The buffer could not be sent to the IP task so the buffer must be released. */ - vReleaseNetworkBufferAndDescriptor( receiveBufferDescriptor ); - - /* Make a call to the standard trace macro to log the occurrence. */ - iptraceETHERNET_RX_EVENT_LOST(); - }else{ - /* The message was successfully sent to the TCP/IP stack. - Call the standard trace macro to log the occurrence. */ - iptraceNETWORK_INTERFACE_RECEIVE(); - } - }else{ - /* The Ethernet frame can be dropped, but the Ethernet buffer - must be released. */ - vReleaseNetworkBufferAndDescriptor( receiveBufferDescriptor ); - } - - }else{ - /* The event was lost because a network buffer was not available. - Call the standard trace macro to log the occurrence. */ - iptraceETHERNET_RX_EVENT_LOST(); - } - } - } -} -#else -/*zero copy method here*/ - -#endif diff --git a/RTE/RTOS/FreeRTOSConfig.h b/RTE/RTOS/FreeRTOSConfig.h index 1b5ea41..3138fda 100644 --- a/RTE/RTOS/FreeRTOSConfig.h +++ b/RTE/RTOS/FreeRTOSConfig.h @@ -208,7 +208,7 @@ void vAssertCalled(const char* pcFile, * results in the wired network being used, while setting * configNETWORK_INTERFACE_TO_USE to 2 results in the wireless network being * used. */ -#define configNETWORK_INTERFACE_TO_USE ( 0L ) +#define configNETWORK_INTERFACE_TO_USE ( 2L ) /* The address of an echo server that will be used by the two demo echo client * tasks: @@ -216,7 +216,7 @@ void vAssertCalled(const char* pcFile, * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html. */ #define configECHO_SERVER_ADDR0 192 #define configECHO_SERVER_ADDR1 168 -#define configECHO_SERVER_ADDR2 0 +#define configECHO_SERVER_ADDR2 1 #define configECHO_SERVER_ADDR3 2 #define configTCP_ECHO_CLIENT_PORT 7 @@ -236,15 +236,15 @@ void vAssertCalled(const char* pcFile, * ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */ #define configIP_ADDR0 192 #define configIP_ADDR1 168 -#define configIP_ADDR2 0 -#define configIP_ADDR3 1 +#define configIP_ADDR2 1 +#define configIP_ADDR3 2 /* Default gateway IP address configuration. Used in ipconfigUSE_DHCP is set to * 0, or ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */ #define configGATEWAY_ADDR0 192 #define configGATEWAY_ADDR1 168 -#define configGATEWAY_ADDR2 0 -#define configGATEWAY_ADDR3 1 +#define configGATEWAY_ADDR2 1 +#define configGATEWAY_ADDR3 2 /* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and * 208.67.220.220. Used in ipconfigUSE_DHCP is set to 0, or ipconfigUSE_DHCP is diff --git a/Test_project_for_GD32107C-EVAL.uvoptx b/Test_project_for_GD32107C-EVAL.uvoptx index d9e743a..adf7678 100644 --- a/Test_project_for_GD32107C-EVAL.uvoptx +++ b/Test_project_for_GD32107C-EVAL.uvoptx @@ -153,40 +153,7 @@ UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F10x_CL -FS08000000 -FL040000 -FP0($$Device:GD32F107VC$Flash\GD32F10x_CL.FLM)) - - - 0 - 0 - 391 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - .\FreeRTOS\source\FreeRTOS_IP.c - - -
- - 1 - 0 - 406 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - .\FreeRTOS\source\FreeRTOS_IP.c - - -
-
+ 0 @@ -208,12 +175,17 @@ 1 PHY + + 4 + 1 + frame + 1 0 - 0x40028014 + pxNetworkBuffer 0 @@ -234,7 +206,7 @@ - C:\Users\User\AppData\Local\Arm\Packs\ARM\CMSIS-FreeRTOS\10.5.1\CMSIS\RTOS2\FreeRTOS\FreeRTOS.scvd + E:\Arm\Packs\ARM\CMSIS-FreeRTOS\10.5.1\CMSIS\RTOS2\FreeRTOS\FreeRTOS.scvd ARM.CMSIS-FreeRTOS.10.5.1 1 @@ -285,7 +257,7 @@ Source Group 1 - 1 + 0 0 0 0 @@ -353,7 +325,7 @@ FreeRTOS - 0 + 1 0 0 0 @@ -373,7 +345,7 @@ 2 7 1 - 0 + 1 0 0 .\FreeRTOS\source\FreeRTOS_IP.c @@ -665,7 +637,7 @@ ::Compiler - 0 + 1 0 0 1 @@ -681,7 +653,7 @@ ::RTOS - 0 + 1 0 0 1 diff --git a/Test_project_for_GD32107C-EVAL.uvprojx b/Test_project_for_GD32107C-EVAL.uvprojx index a88460f..6c04685 100644 --- a/Test_project_for_GD32107C-EVAL.uvprojx +++ b/Test_project_for_GD32107C-EVAL.uvprojx @@ -317,23 +317,23 @@ 1 1 0 - 1 - 1 + 0 + 0 0 0 0 0 0 - 3 + 4 0 0 1 1 0 5 - 5 - 1 - 1 + 6 + 0 + 0 0 0 0 diff --git a/main.c b/main.c index e530990..cb8dedb 100644 --- a/main.c +++ b/main.c @@ -3,6 +3,8 @@ #include "gd32f107c_eval.h" #include "gd32f10x_gpio.h" #include "stdio.h" + + /* System application includes. */ #include "FreeRTOSIPConfig.h" @@ -200,13 +202,7 @@ static void vInitMCU(void) gpio_bit_set(LED5_TICK_PORT, LED5_TICK); /*Enable PLL2 to generate 50MHz clocks */ - if (ERROR == xInitPLL2()) - { -#ifdef DEBUG - printf("PLL2 initialization failed\n"); - __ASM("BKPT #0\n"); -#endif - } + if (ERROR == xInitPLL2()) FreeRTOS_debug_printf(("PLL2 initialization failed\n")); /* Put PLL2 clocks into CKOUT0(PA1) as ref clock for ethernet phy */ rcu_ckout0_config(RCU_CKOUT0SRC_CKPLL2); @@ -242,7 +238,7 @@ void vTaskHelloWorld( void *pvParameters) ButtonState = !gpio_input_bit_get(GPIOB, BUTTON_USER); if (ButtonState) { - printf("Hello world\n"); + FreeRTOS_debug_printf(("Key pressed\n")); fflush( stdout ); vTaskDelay(TASK_HELLO_WORLD_DELAY); } @@ -270,21 +266,23 @@ void vTaskToggleLed( void *pvParameters) } } + static void prvMiscInitialisation( void ) { -// time_t xTimeNow; + unsigned long xTimeNow; uint32_t ulRandomNumbers[ 4 ]; /* Seed the random number generator. */ // time( &xTimeNow ); - FreeRTOS_debug_printf( ( "Seed for randomiser: %lu\r\n", xTimeNow ) ); + FreeRTOS_debug_printf( ("Seed for randomiser: %lu\r\n", xTimeNow ) ); + FreeRTOS_debug_printf( ("Seed for randomiser\n") ); // prvSRand( ( uint32_t ) xTimeNow ); ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 0 ] ); ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 1 ] ); ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 2 ] ); ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 3 ] ); - FreeRTOS_debug_printf( ( "Random numbers: %08X %08X %08X %08X\r\n", + FreeRTOS_debug_printf( ("Random numbers: %08X %08X %08X %08X\r\n", ulRandomNumbers[ 0 ], ulRandomNumbers[ 1 ], ulRandomNumbers[ 2 ], @@ -300,11 +298,35 @@ int main(void) xTaskCreate( vTaskToggleLed, "ToggleLed", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL); xTaskCreate( vTaskHelloWorld, "HelloWorld", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL); FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); -// vStartSimpleTCPServerTasks( configMINIMAL_STACK_SIZE*2, tskIDLE_PRIORITY+1 ); + enet_enable(); vTaskStartScheduler(); while(1); } +/** + * @brief xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase, uint32_t ulIPAddress ) + */ +eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase, uint32_t ulIPAddress ) +{ + eDHCPCallbackAnswer_t xResult = eDHCPUseDefaults; + switch (eDHCPPhase) + { + case eDHCPPhasePreDiscover: + FreeRTOS_debug_printf((" Driver is about to send a DHCP discovery.\n")); + xResult = eDHCPContinue; + break; + case eDHCPPhasePreRequest: + FreeRTOS_debug_printf((" Driver is about to request DHCP an IP address.\n")); + xResult = eDHCPContinue; + break; + default: + FreeRTOS_debug_printf((" Stop DHCP requests.\n")); + xResult = eDHCPStopNoChanges; + break; + }; + return xResult; +}; + /** * @brief vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) */ @@ -563,8 +585,8 @@ extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress, */ void vApplicationMallocFailedHook( void ) { -#if defined (DEBUG) - printf("Malloc Failed Hook\n"); + FreeRTOS_debug_printf(("Malloc Failed Hook\n")); +#if defined (DEBUG) __ASM("BKPT #0\n"); #endif NVIC_SystemReset(); @@ -602,7 +624,7 @@ void vApplicationIdleHook( void ) uint32_t currentTick = xTaskGetTickCount(); if(currentTick > idleHookCounter + delta) { - printf("Idle Hook %d\n", idleHookCounter);//__ASM("BKPT #0\n"); + FreeRTOS_debug_printf(("Idle Hook %d\n", idleHookCounter));//__ASM("BKPT #0\n"); } idleHookCounter = currentTick; #endif @@ -613,8 +635,8 @@ void vApplicationIdleHook( void ) */ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) { -#if defined (DEBUG) - printf("Stack Overflow Hook\n"); + FreeRTOS_debug_printf(("Stack Overflow Hook\n")); +#if defined (DEBUG) __ASM("BKPT #0\n"); #endif NVIC_SystemReset();