Sync FreeRTOS-Labs -CLI -TCP -Trace with the version in FreeRTOS-Plus.

Projects under FreeRTOS-Labs directory are in beta, developers updating projects please make sure you are using the correct version of -CLI -TCP -Trace. If you must edit -CLI -TCP and -Trace, please ensure the copies are synced.
This commit is contained in:
Yuhui.Zheng
2020-01-31 19:21:15 +00:00
parent ec6f3d77c3
commit 9fdfbf33e9
58 changed files with 4129 additions and 4415 deletions
@@ -1,43 +1,28 @@
/*
* FreeRTOS+CLI V1.0.3 (C) 2014 Real Time Engineers ltd. All rights reserved.
* FreeRTOS+CLI V1.0.4
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* This file is part of the FreeRTOS+CLI distribution. The FreeRTOS+CLI license
* terms are different to the FreeRTOS license terms.
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* FreeRTOS+CLI uses a dual license model that allows the software to be used
* under a standard GPL open source license, or a commercial license. The
* standard GPL license (unlike the modified GPL license under which FreeRTOS
* itself is distributed) requires that all software statically linked with
* FreeRTOS+CLI is also distributed under the same GPL V2 license terms.
* Details of both license options follow:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* - Open source licensing -
* FreeRTOS+CLI is a free download and may be used, modified, evaluated and
* distributed without charge provided the user adheres to version two of the
* GNU General Public License (GPL) and does not remove the copyright notice or
* this text. The GPL V2 text is available on the gnu.org web site, and on the
* following URL: http://www.FreeRTOS.org/gpl-2.0.txt.
*
* - Commercial licensing -
* Businesses and individuals that for commercial or other reasons cannot comply
* with the terms of the GPL V2 license must obtain a low cost commercial
* license before incorporating FreeRTOS+CLI into proprietary software for
* distribution in any form. Commercial licenses can be purchased from
* http://shop.freertos.org/cli and do not require any source files to be
* changed.
*
* FreeRTOS+CLI is distributed in the hope that it will be useful. You cannot
* use FreeRTOS+CLI unless you agree that you use the software 'as is'.
* FreeRTOS+CLI 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!
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://www.FreeRTOS.org/FreeRTOS-Plus
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/* Standard includes. */
@@ -51,6 +36,16 @@
/* Utils includes. */
#include "FreeRTOS_CLI.h"
/* If the application writer needs to place the buffer used by the CLI at a
fixed address then set configAPPLICATION_PROVIDES_cOutputBuffer to 1 in
FreeRTOSConfig.h, then declare an array with the following name and size in
one of the application files:
char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
*/
#ifndef configAPPLICATION_PROVIDES_cOutputBuffer
#define configAPPLICATION_PROVIDES_cOutputBuffer 0
#endif
typedef struct xCOMMAND_INPUT_LIST
{
const CLI_Command_Definition_t *pxCommandLineDefinition;
@@ -93,8 +88,17 @@ command interpreter by UART and by Ethernet. Sharing a buffer is done purely
to save RAM. Note, however, that the command console itself is not re-entrant,
so only one command interpreter interface can be used at any one time. For that
reason, no attempt at providing mutual exclusion to the cOutputBuffer array is
attempted. */
static char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
attempted.
configAPPLICATION_PROVIDES_cOutputBuffer is provided to allow the application
writer to provide their own cOutputBuffer declaration in cases where the
buffer needs to be placed at a fixed address (rather than by the linker). */
#if( configAPPLICATION_PROVIDES_cOutputBuffer == 0 )
static char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
#else
extern char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
#endif
/*-----------------------------------------------------------*/
@@ -1,43 +1,28 @@
/*
* FreeRTOS+CLI V1.0.3 (C) 2014 Real Time Engineers ltd. All rights reserved.
* FreeRTOS+CLI V1.0.4
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* This file is part of the FreeRTOS+CLI distribution. The FreeRTOS+CLI license
* terms are different to the FreeRTOS license terms.
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* FreeRTOS+CLI uses a dual license model that allows the software to be used
* under a standard GPL open source license, or a commercial license. The
* standard GPL license (unlike the modified GPL license under which FreeRTOS
* itself is distributed) requires that all software statically linked with
* FreeRTOS+CLI is also distributed under the same GPL V2 license terms.
* Details of both license options follow:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* - Open source licensing -
* FreeRTOS+CLI is a free download and may be used, modified, evaluated and
* distributed without charge provided the user adheres to version two of the
* GNU General Public License (GPL) and does not remove the copyright notice or
* this text. The GPL V2 text is available on the gnu.org web site, and on the
* following URL: http://www.FreeRTOS.org/gpl-2.0.txt.
*
* - Commercial licensing -
* Businesses and individuals that for commercial or other reasons cannot comply
* with the terms of the GPL V2 license must obtain a low cost commercial
* license before incorporating FreeRTOS+CLI into proprietary software for
* distribution in any form. Commercial licenses can be purchased from
* http://shop.freertos.org/cli and do not require any source files to be
* changed.
*
* FreeRTOS+CLI is distributed in the hope that it will be useful. You cannot
* use FreeRTOS+CLI unless you agree that you use the software 'as is'.
* FreeRTOS+CLI 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!
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://www.FreeRTOS.org/FreeRTOS-Plus
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef COMMAND_INTERPRETER_H
@@ -1,3 +1,8 @@
Changes between V1.0.3 and V1.0.4 released
+ Update to use stdint and the FreeRTOS specific typedefs that were
introduced in FreeRTOS V8.0.0.
Changes between V1.0.2 and V1.0.3 released
+ Previously, and in line with good software engineering practice, the
@@ -1,7 +1,19 @@
Note the FreeRTOS+CLI license terms are different to the FreeRTOS license terms.
FreeRTOS+CLI is released under the following MIT license.
FreeRTOS+CLI is dual licensed. The files are provided here under an unmodified
open source GNU GPL license. Commercial licenses are also available, and are
provided free for some hardware platforms. See http://www.FreeRTOS.org/cli
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -580,8 +580,24 @@ NetworkBufferDescriptor_t *pxNetworkBuffer;
}
}
#endif
if( xIsCallingFromIPTask() != 0 )
{
/* Only the IP-task is allowed to call this function directly. */
xNetworkInterfaceOutput( pxNetworkBuffer, pdTRUE );
}
else
{
IPStackEvent_t xSendEvent;
xNetworkInterfaceOutput( pxNetworkBuffer, pdTRUE );
/* Send a message to the IP-task to send this ARP packet. */
xSendEvent.eEventType = eNetworkTxEvent;
xSendEvent.pvData = ( void * ) pxNetworkBuffer;
if( xSendEventStructToIPTask( &xSendEvent, ( TickType_t ) portMAX_DELAY ) == pdFAIL )
{
/* Failed to send the message, so release the network buffer. */
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
}
}
}
}
@@ -589,6 +605,12 @@ void vARPGenerateRequestPacket( NetworkBufferDescriptor_t * const pxNetworkBuffe
{
ARPPacket_t *pxARPPacket;
/* Buffer allocation ensures that buffers always have space
for an ARP packet. See buffer allocation implementations 1
and 2 under portable/BufferManagement. */
configASSERT( pxNetworkBuffer );
configASSERT( pxNetworkBuffer->xDataLength >= sizeof(ARPPacket_t) );
pxARPPacket = ( ARPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
/* memcpy the const part of the header information into the correct
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -84,9 +84,9 @@
/* Offsets into the transmitted DHCP options fields at which various parameters
are located. */
#define dhcpCLIENT_IDENTIFIER_OFFSET ( 5 )
#define dhcpREQUESTED_IP_ADDRESS_OFFSET ( 13 )
#define dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ( 19 )
#define dhcpCLIENT_IDENTIFIER_OFFSET ( 6 )
#define dhcpREQUESTED_IP_ADDRESS_OFFSET ( 14 )
#define dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ( 20 )
/* Values used in the DHCP packets. */
#define dhcpREQUEST_OPCODE ( 1 )
@@ -354,9 +354,7 @@ BaseType_t xGivingUp = pdFALSE;
if( xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )
{
xDHCPData.ulTransactionId = ipconfigRAND32( );
if( 0 != xDHCPData.ulTransactionId )
if( xApplicationGetRandomNumber( &( xDHCPData.ulTransactionId ) ) != pdFALSE )
{
xDHCPData.xDHCPTxTime = xTaskGetTickCount( );
xDHCPData.xUseBroadcast = !xDHCPData.xUseBroadcast;
@@ -589,10 +587,9 @@ static void prvInitialiseDHCP( void )
/* Initialise the parameters that will be set by the DHCP process. Per
https://www.ietf.org/rfc/rfc2131.txt, Transaction ID should be a random
value chosen by the client. */
xDHCPData.ulTransactionId = ipconfigRAND32();
/* Check for random number generator API failure. */
if( 0 != xDHCPData.ulTransactionId )
if( xApplicationGetRandomNumber( &( xDHCPData.ulTransactionId ) ) != pdFALSE )
{
xDHCPData.xUseBroadcast = 0;
xDHCPData.ulOfferedIPAddress = 0UL;
@@ -604,6 +601,10 @@ static void prvInitialiseDHCP( void )
FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );
vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
}
else
{
/* There was a problem with the randomiser. */
}
}
/*-----------------------------------------------------------*/
@@ -642,8 +643,8 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
/* Walk through the options until the dhcpOPTION_END_BYTE byte
is found, taking care not to walk off the end of the options. */
pucByte = &( pxDHCPMessage->ucFirstOptionByte );
/* Maintain a pointer to the last valid byte (i.e. not the first
invalid byte). */
/* Maintain a pointer to the last valid byte (i.e. not the first
invalid byte). */
pucLastByte = pucUDPPayload + lBytes - 1;
while( pucByte <= pucLastByte )
@@ -665,7 +666,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
/* Stop if the response is malformed. */
if( pucByte < pucLastByte )
{
/* There are at least two bytes left. */
/* There are at least two bytes left. */
ucLength = pucByte[ 1 ];
pucByte += 2;
@@ -904,7 +905,7 @@ static const uint8_t ucDHCPRequestOptions[] =
dhcpCLIENT_IDENTIFIER_OFFSET, dhcpREQUESTED_IP_ADDRESS_OFFSET and
dhcpDHCP_SERVER_IP_ADDRESS_OFFSET. */
dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST, /* Message type option. */
dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
dhcpCLIENT_IDENTIFIER_OPTION_CODE, 7, 1, 0, 0, 0, 0, 0, 0, /* Client identifier. */
dhcpREQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address being requested. */
dhcpSERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address of the DHCP server. */
dhcpOPTION_END_BYTE
@@ -942,7 +943,7 @@ static const uint8_t ucDHCPDiscoverOptions[] =
{
/* Do not change the ordering without also changing dhcpCLIENT_IDENTIFIER_OFFSET. */
dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER, /* Message type option. */
dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
dhcpCLIENT_IDENTIFIER_OPTION_CODE, 7, 1, 0, 0, 0, 0, 0, 0, /* Client identifier. */
dhcpPARAMETER_REQUEST_OPTION_CODE, 3, dhcpSUBNET_MASK_OPTION_CODE, dhcpGATEWAY_OPTION_CODE, dhcpDNS_SERVER_OPTIONS_CODE, /* Parameter request option. */
dhcpOPTION_END_BYTE
};
@@ -968,13 +969,16 @@ size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
static void prvPrepareLinkLayerIPLookUp( void )
{
uint8_t ucLinkLayerIPAddress[ 2 ];
uint32_t ulNumbers[ 2 ];
/* After DHCP has failed to answer, prepare everything to start
trying-out LinkLayer IP-addresses, using the random method. */
xDHCPData.xDHCPTxTime = xTaskGetTickCount();
ucLinkLayerIPAddress[ 0 ] = ( uint8_t )1 + ( uint8_t )( ipconfigRAND32() % 0xFDu ); /* get value 1..254 for IP-address 3rd byte of IP address to try. */
ucLinkLayerIPAddress[ 1 ] = ( uint8_t )1 + ( uint8_t )( ipconfigRAND32() % 0xFDu ); /* get value 1..254 for IP-address 4th byte of IP address to try. */
xApplicationGetRandomNumber( &( ulNumbers[ 0 ] ) );
xApplicationGetRandomNumber( &( ulNumbers[ 1 ] ) );
ucLinkLayerIPAddress[ 0 ] = ( uint8_t )1 + ( uint8_t )( ulNumbers[ 0 ] % 0xFDu ); /* get value 1..254 for IP-address 3rd byte of IP address to try. */
ucLinkLayerIPAddress[ 1 ] = ( uint8_t )1 + ( uint8_t )( ulNumbers[ 1 ] % 0xFDu ); /* get value 1..254 for IP-address 4th byte of IP address to try. */
xNetworkAddressing.ulGatewayAddress = FreeRTOS_htonl( 0xA9FE0203 );
@@ -995,9 +999,15 @@ size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
xNetworkAddressing.ulBroadcastAddress = ( xDHCPData.ulOfferedIPAddress & xNetworkAddressing.ulNetMask ) | ~xNetworkAddressing.ulNetMask;
/* Close socket to ensure packets don't queue on it. not needed anymore as DHCP failed. but still need timer for ARP testing. */
vSocketClose( xDHCPData.xDHCPSocket );
xDHCPData.xDHCPSocket = NULL;
xDHCPData.xDHCPTxPeriod = pdMS_TO_TICKS( 3000ul + ( ipconfigRAND32() & 0x3fful ) ); /* do ARP test every (3 + 0-1024mS) seconds. */
if( xDHCPData.xDHCPSocket != NULL )
{
/* Close socket to ensure packets don't queue on it. */
vSocketClose( xDHCPData.xDHCPSocket );
xDHCPData.xDHCPSocket = NULL;
}
xApplicationGetRandomNumber( &( ulNumbers[ 0 ] ) );
xDHCPData.xDHCPTxPeriod = pdMS_TO_TICKS( 3000ul + ( ulNumbers[ 0 ] & 0x3ffuL ) ); /* do ARP test every (3 + 0-1024mS) seconds. */
xARPHadIPClash = pdFALSE; /* reset flag that shows if have ARP clash. */
vARPSendGratuitous();
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -65,7 +65,9 @@ a constant. */
/* Time delay between repeated attempts to initialise the network hardware. */
#define ipINITIALISATION_RETRY_DELAY ( pdMS_TO_TICKS( 3000 ) )
#ifndef ipINITIALISATION_RETRY_DELAY
#define ipINITIALISATION_RETRY_DELAY ( pdMS_TO_TICKS( 3000 ) )
#endif
/* Defines how often the ARP timer callback function is executed. The time is
shorted in the Windows simulator as simulated time is not real time. */
@@ -394,6 +396,12 @@ struct freertos_sockaddr xAddress;
prvHandleEthernetPacket( ( NetworkBufferDescriptor_t * ) ( xReceivedEvent.pvData ) );
break;
case eNetworkTxEvent:
/* Send a network packet. The ownership will be transferred to
the driver, which will release it after delivery. */
xNetworkInterfaceOutput( ( NetworkBufferDescriptor_t * ) ( xReceivedEvent.pvData ), pdTRUE );
break;
case eARPTimerEvent :
/* The ARP timer has expired, process the ARP cache. */
vARPAgeCache();
@@ -820,20 +828,20 @@ void *pvReturn;
/*-----------------------------------------------------------*/
NetworkBufferDescriptor_t *pxDuplicateNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer,
BaseType_t xNewLength )
size_t uxNewLength )
{
NetworkBufferDescriptor_t * pxNewBuffer;
/* This function is only used when 'ipconfigZERO_COPY_TX_DRIVER' is set to 1.
The transmit routine wants to have ownership of the network buffer
descriptor, because it will pass the buffer straight to DMA. */
pxNewBuffer = pxGetNetworkBufferWithDescriptor( ( size_t ) xNewLength, ( TickType_t ) 0 );
pxNewBuffer = pxGetNetworkBufferWithDescriptor( uxNewLength, ( TickType_t ) 0 );
if( pxNewBuffer != NULL )
{
/* Set the actual packet size in case a bigger buffer than requested
was returned. */
pxNewBuffer->xDataLength = xNewLength;
pxNewBuffer->xDataLength = uxNewLength;
/* Copy the original packet information. */
pxNewBuffer->ulIPAddress = pxNetworkBuffer->ulIPAddress;
@@ -986,7 +994,10 @@ BaseType_t xReturn = pdFALSE;
/* Added to prevent ARP flood to gateway. Ensure the
gateway is on the same subnet as the IP address. */
configASSERT( ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) == ( xNetworkAddressing.ulGatewayAddress & xNetworkAddressing.ulNetMask ) );
if( xNetworkAddressing.ulGatewayAddress != 0ul )
{
configASSERT( ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) == ( xNetworkAddressing.ulGatewayAddress & xNetworkAddressing.ulNetMask ) );
}
}
#endif /* ipconfigUSE_DHCP == 1 */
@@ -1111,7 +1122,8 @@ void FreeRTOS_SetAddressConfiguration( const uint32_t *pulIPAddress, const uint3
pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ] = FREERTOS_SO_UDPCKSUM_OUT;
pxNetworkBuffer->ulIPAddress = ulIPAddress;
pxNetworkBuffer->usPort = ipPACKET_CONTAINS_ICMP_DATA;
pxNetworkBuffer->xDataLength = xNumberOfBytesToSend + sizeof( ICMPHeader_t );
/* xDataLength is the size of the total packet, including the Ethernet header. */
pxNetworkBuffer->xDataLength = xNumberOfBytesToSend + sizeof( ICMPPacket_t );
/* Send to the stack. */
xStackTxEvent.pvData = pxNetworkBuffer;
@@ -1600,23 +1612,24 @@ uint8_t ucProtocol;
/* Only proceed if the payload length indicated in the header
appears to be valid. */
if ( pxNetworkBuffer->xDataLength >= sizeof( UDPPacket_t ) )
if ( ( pxNetworkBuffer->xDataLength >= sizeof( UDPPacket_t ) ) && ( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) >= sizeof( UDPHeader_t ) ) )
{
/* Ensure that downstream UDP packet handling has the lesser
* of: the actual network buffer Ethernet frame length, or
* the sender's UDP packet header payload length, minus the
* size of the UDP header.
*
* The size of the UDP packet structure in this implementation
* includes the size of the Ethernet header, the size of
* the IP header, and the size of the UDP header.
size_t uxPayloadSize_1, uxPayloadSize_2;
/* The UDP payload size can be calculated by subtracting the
* header size from `xDataLength`.
* However, the `xDataLength` may be longer that expected,
* e.g. when a small packet is padded with zero's.
* The UDP header contains a field `usLength` reflecting
* the payload size plus the UDP header ( 8 bytes ).
* Set `xDataLength` to the size of the headers,
* plus the lower of the two calculated payload sizes.
*/
pxNetworkBuffer->xDataLength -= sizeof( UDPPacket_t );
if( ( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) - sizeof( UDPHeader_t ) ) <
pxNetworkBuffer->xDataLength )
uxPayloadSize_1 = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
uxPayloadSize_2 = FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) - sizeof( UDPHeader_t );
if( uxPayloadSize_1 > uxPayloadSize_2 )
{
pxNetworkBuffer->xDataLength = FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) - sizeof( UDPHeader_t );
pxNetworkBuffer->xDataLength = uxPayloadSize_2 + sizeof( UDPPacket_t );
}
/* Fields in pxNetworkBuffer (usPort, ulIPAddress) are network order. */
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -385,7 +385,7 @@ Socket_t xReturn;
}
}
return ( SocketSet_t * ) pxSocketSet;
return ( SocketSet_t ) pxSocketSet;
}
#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
@@ -702,9 +702,11 @@ EventBits_t xEventBits = ( EventBits_t ) 0;
}
taskEXIT_CRITICAL();
/* The returned value is the data length, which may have been capped to
the receive buffer size. */
lReturn = ( int32_t ) pxNetworkBuffer->xDataLength;
/* The returned value is the length of the payload data, which is
calculated at the total packet size minus the headers.
The validity of `xDataLength` prvProcessIPPacket has been confirmed
in 'prvProcessIPPacket()'. */
lReturn = ( int32_t ) ( pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t ) );
if( pxSourceAddress != NULL )
{
@@ -833,7 +835,8 @@ FreeRTOS_Socket_t *pxSocket;
if( pxNetworkBuffer != NULL )
{
pxNetworkBuffer->xDataLength = xTotalDataLength;
/* xDataLength is the size of the total packet, including the Ethernet header. */
pxNetworkBuffer->xDataLength = xTotalDataLength + sizeof( UDPPacket_t );
pxNetworkBuffer->usPort = pxDestinationAddress->sin_port;
pxNetworkBuffer->usBoundPort = ( uint16_t ) socketGET_SOCKET_PORT( pxSocket );
pxNetworkBuffer->ulIPAddress = pxDestinationAddress->sin_addr;
@@ -854,7 +857,7 @@ FreeRTOS_Socket_t *pxSocket;
{
if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xUDP.pxHandleSent ) )
{
pxSocket->u.xUDP.pxHandleSent( (Socket_t *)pxSocket, xTotalDataLength );
pxSocket->u.xUDP.pxHandleSent( ( Socket_t )pxSocket, xTotalDataLength );
}
}
#endif /* ipconfigUSE_CALLBACKS */
@@ -1421,7 +1424,7 @@ FreeRTOS_Socket_t *pxSocket;
break;
#endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK != 0 ) || ( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT != 0 )
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK != 0 )
case FREERTOS_SO_WAKEUP_CALLBACK:
{
/* Each socket can have a callback function that is executed
@@ -1433,16 +1436,6 @@ FreeRTOS_Socket_t *pxSocket;
break;
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT != 0 )
case FREERTOS_SO_WAKE_CALLBACK_CONTEXT:
{
/* Each socket wake callback may be passed a user context. */
pxSocket->pvUserWakeCallbackContext = ( void * ) pvOptionValue;
xReturn = 0;
}
break;
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT */
case FREERTOS_SO_SET_LOW_HIGH_WATER:
{
LowHighWater_t *pxLowHighWater = ( LowHighWater_t * ) pvOptionValue;
@@ -1664,7 +1657,6 @@ const uint16_t usEphemeralPortCount =
uint16_t usIterations = usEphemeralPortCount;
uint32_t ulRandomSeed = 0;
uint16_t usResult = 0;
BaseType_t xGotZeroOnce = pdFALSE;
const List_t *pxList;
#if ipconfigUSE_TCP == 1
@@ -1685,21 +1677,10 @@ const List_t *pxList;
point. */
do
{
/* Generate a random seed. */
ulRandomSeed = ipconfigRAND32( );
/* Only proceed if the random number generator succeeded. */
if( 0 == ulRandomSeed )
if( xApplicationGetRandomNumber( &( ulRandomSeed ) ) == pdFALSE )
{
if( pdFALSE == xGotZeroOnce )
{
xGotZeroOnce = pdTRUE;
continue;
}
else
{
break;
}
break;
}
/* Map the random to a candidate port. */
@@ -1904,16 +1885,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
pxSocket->pxUserWakeCallback( pxSocket );
}
}
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT == 1 )
{
if( pxSocket->pxUserWakeCallback != NULL )
{
pxSocket->pxUserWakeCallback( pxSocket, pxSocket->pvUserWakeCallbackContext );
}
}
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT */
#endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
{
@@ -2432,8 +2404,8 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
xResult = -pdFREERTOS_ERRNO_ENOMEM;
}
else if( pxSocket->u.xTCP.ucTCPState == eCLOSED ||
pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ||
pxSocket->u.xTCP.ucTCPState == eCLOSING )
pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ||
pxSocket->u.xTCP.ucTCPState == eCLOSING )
{
xResult = -pdFREERTOS_ERRNO_ENOTCONN;
}
@@ -2472,25 +2444,25 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
'*pxLength' will contain the number of bytes that may be written. */
uint8_t *FreeRTOS_get_tx_head( Socket_t xSocket, BaseType_t *pxLength )
{
uint8_t *pucReturn = NULL;
uint8_t *pucReturn = NULL;
FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
StreamBuffer_t *pxBuffer = NULL;
*pxLength = 0;
*pxLength = 0;
/* Confirm that this is a TCP socket before dereferencing structure
member pointers. */
if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
{
pxBuffer = pxSocket->u.xTCP.txStream;
if( pxBuffer != NULL )
{
BaseType_t xSpace = ( BaseType_t )uxStreamBufferGetSpace( pxBuffer );
BaseType_t xRemain = ( BaseType_t )( pxBuffer->LENGTH - pxBuffer->uxHead );
/* Confirm that this is a TCP socket before dereferencing structure
member pointers. */
if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
{
pxBuffer = pxSocket->u.xTCP.txStream;
if( pxBuffer != NULL )
{
BaseType_t xSpace = ( BaseType_t )uxStreamBufferGetSpace( pxBuffer );
BaseType_t xRemain = ( BaseType_t )( pxBuffer->LENGTH - pxBuffer->uxHead );
*pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );
pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;
}
*pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );
pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;
}
}
return pucReturn;
@@ -2923,20 +2895,20 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
#if( ipconfigUSE_TCP == 1 )
const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket )
{
FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * )xSocket;
struct xSTREAM_BUFFER *pxReturn = NULL;
const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket )
{
FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * )xSocket;
struct xSTREAM_BUFFER *pxReturn = NULL;
/* Confirm that this is a TCP socket before dereferencing structure
member pointers. */
if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
{
pxReturn = pxSocket->u.xTCP.rxStream;
}
/* Confirm that this is a TCP socket before dereferencing structure
member pointers. */
if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
{
pxReturn = pxSocket->u.xTCP.rxStream;
}
return pxReturn;
}
return pxReturn;
}
#endif /* ipconfigUSE_TCP */
/*-----------------------------------------------------------*/
@@ -3100,7 +3072,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
break;
}
pxSocket->u.xTCP.pxHandleReceive( (Socket_t *)pxSocket, ( void* )ucReadPtr, ( size_t ) ulCount );
pxSocket->u.xTCP.pxHandleReceive( ( Socket_t )pxSocket, ( void* )ucReadPtr, ( size_t ) ulCount );
uxStreamBufferGet( pxStream, 0ul, NULL, ( size_t ) ulCount, pdFALSE );
}
} else
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -675,17 +675,17 @@ const int32_t l500ms = 500;
#if( ipconfigUSE_TCP_WIN == 1 )
void vTCPSegmentCleanup( void )
{
/* Free and clear the TCP segments pointer. This function should only be called
* once FreeRTOS+TCP will no longer be used. No thread-safety is provided for this
* function. */
if( xTCPSegments != NULL )
{
vPortFreeLarge( xTCPSegments );
xTCPSegments = NULL;
}
}
void vTCPSegmentCleanup( void )
{
/* Free and clear the TCP segments pointer. This function should only be called
* once FreeRTOS+TCP will no longer be used. No thread-safety is provided for this
* function. */
if( xTCPSegments != NULL )
{
vPortFreeLarge( xTCPSegments );
xTCPSegments = NULL;
}
}
#endif /* ipconfgiUSE_TCP_WIN == 1 */
/*-----------------------------------------------------------*/
@@ -805,20 +805,20 @@ const int32_t l500ms = 500;
{
ulSavedSequenceNumber = ulCurrentSequenceNumber;
/* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
If the server is forced to retransmit packets several time in a row it might send a batch of concatenated packet for speed.
So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
clean them out. */
do
{
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
/* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
If the server is forced to retransmit packets several time in a row it might send a batch of concatenated packet for speed.
So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
clean them out. */
do
{
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
if ( pxFound != NULL )
{
/* Remove it because it will be passed to user directly. */
vTCPWindowFree( pxFound );
}
} while ( pxFound );
if ( pxFound != NULL )
{
/* Remove it because it will be passed to user directly. */
vTCPWindowFree( pxFound );
}
} while ( pxFound );
/* Check for following segments that are already in the
queue and increment ulCurrentSequenceNumber. */
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -78,10 +78,22 @@ UDPPacket_t *pxUDPPacket;
IPHeader_t *pxIPHeader;
eARPLookupResult_t eReturned;
uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
size_t uxPayloadSize;
/* Map the UDP packet onto the start of the frame. */
pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
#if ipconfigSUPPORT_OUTGOING_PINGS == 1
if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )
{
uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( ICMPPacket_t );
}
else
#endif
{
uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
}
/* Determine the ARP cache status for the requested IP address. */
eReturned = eARPGetCacheEntry( &( ulIPAddress ), &( pxUDPPacket->xEthernetHeader.xDestinationAddress ) );
@@ -109,7 +121,7 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
pxUDPHeader->usDestinationPort = pxNetworkBuffer->usPort;
pxUDPHeader->usSourcePort = pxNetworkBuffer->usBoundPort;
pxUDPHeader->usLength = ( uint16_t ) ( pxNetworkBuffer->xDataLength + sizeof( UDPHeader_t ) );
pxUDPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( UDPHeader_t ) );
pxUDPHeader->usLength = FreeRTOS_htons( pxUDPHeader->usLength );
pxUDPHeader->usChecksum = 0u;
}
@@ -143,16 +155,14 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )
{
pxIPHeader->ucProtocol = ipPROTOCOL_ICMP;
pxIPHeader->usLength = ( uint16_t ) ( pxNetworkBuffer->xDataLength + sizeof( IPHeader_t ) );
pxIPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( IPHeader_t ) + sizeof( ICMPHeader_t ) );
}
else
#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
{
pxIPHeader->usLength = ( uint16_t ) ( pxNetworkBuffer->xDataLength + sizeof( IPHeader_t ) + sizeof( UDPHeader_t ) );
pxIPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( IPHeader_t ) + sizeof( UDPHeader_t ) );
}
/* The total transmit size adds on the Ethernet header. */
pxNetworkBuffer->xDataLength = pxIPHeader->usLength + sizeof( EthernetHeader_t );
pxIPHeader->usLength = FreeRTOS_htons( pxIPHeader->usLength );
/* HT:endian: changed back to network endian */
pxIPHeader->ulDestinationIPAddress = pxNetworkBuffer->ulIPAddress;
@@ -240,13 +250,12 @@ BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer
{
BaseType_t xReturn = pdPASS;
FreeRTOS_Socket_t *pxSocket;
UDPPacket_t *pxUDPPacket;
configASSERT(pxNetworkBuffer);
configASSERT(pxNetworkBuffer->pucEthernetBuffer);
configASSERT( pxNetworkBuffer );
configASSERT( pxNetworkBuffer->pucEthernetBuffer );
pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
/* Caller must check for minimum packet size. */
pxSocket = pxUDPSocketLookup( usPort );
@@ -271,7 +280,8 @@ UDPPacket_t *pxUDPPacket;
destinationAddress.sin_port = usPort;
destinationAddress.sin_addr = pxUDPPacket->xIPHeader.ulDestinationIPAddress;
if( xHandler( ( Socket_t * ) pxSocket, ( void* ) pcData, ( size_t ) pxNetworkBuffer->xDataLength,
/* The value of 'xDataLength' was proven to be at least the size of a UDP packet in prvProcessIPPacket(). */
if( xHandler( ( Socket_t ) pxSocket, ( void* ) pcData, ( size_t ) ( pxNetworkBuffer->xDataLength - ipUDP_PAYLOAD_OFFSET_IPv4 ),
&xSourceAddress, &destinationAddress ) )
{
xReturn = pdFAIL; /* FAIL means that we did not consume or release the buffer */
@@ -351,6 +361,19 @@ UDPPacket_t *pxUDPPacket;
/* There is no socket listening to the target port, but still it might
be for this node. */
#if( ipconfigUSE_DNS == 1 ) && ( ipconfigDNS_USE_CALLBACKS == 1 )
/* A DNS reply, check for the source port. Although the DNS client
does open a UDP socket to send a messages, this socket will be
closed after a short timeout. Messages that come late (after the
socket is closed) will be treated here. */
if( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usSourcePort ) == ipDNS_PORT )
{
vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
xReturn = ( BaseType_t )ulDNSHandlePacket( pxNetworkBuffer );
}
else
#endif
#if( ipconfigUSE_LLMNR == 1 )
/* a LLMNR request, check for the destination port. */
if( ( usPort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) ||
@@ -1,7 +1,3 @@
Changes in V2.0.11
+ Updates some drivers in the portable layer.
Changes between 160919 and 180821 releases:
+ Multiple security improvements and fixes in packet parsing routines, DNS
@@ -9,17 +5,7 @@ Changes between 160919 and 180821 releases:
+ Disable NBNS and LLMNR by default.
+ Add TCP hang protection by default.
We thank Ori Karliner of Zimperium zLabs Team for reporting these issues.
+ Update FreeRTOS_gethostbyname() to allow an IP address to be passed in -
in which case it is just returned as a uint32_t.
+ Introduce ipconfigSOCKET_HAS_USER_WAKE_CALLBACK to FreeRTOS_Sockets.c to
allow a user supposed callback function to be executed when socket events
occur in the same way that the socket semaphore is currently used.
+ Update xNetworkBuffersInitialise() to ensure the semaphore created by the
function is not accessed until after the NULL check.
+ Improve print messages output by the Win32 port layer version of
prvPrintAvailableNetworkInterfaces().
We thank Ori Karliner of Zimperium zLabs Team for reporting these issues.
Changes between 160908 and 160919 releases:
@@ -188,4 +174,4 @@ Changes between 141019 and 150825
+ Fix: Previously if a listening socket was reused, and a connection
failed, the TCP/IP stack closed the socket, now the socket is correctly
left unclosed as it is owned by the application.
+ Various other formatting and minor fix alterations.
+ Various other formatting and minor fix alterations.
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -169,6 +169,14 @@ from the FreeRTOSIPConfig.h configuration header file. */
#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME portMAX_DELAY
#endif
#ifndef ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS
#define ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS pdMS_TO_TICKS( 500u )
#endif
#ifndef ipconfigDNS_SEND_BLOCK_TIME_TICKS
#define ipconfigDNS_SEND_BLOCK_TIME_TICKS pdMS_TO_TICKS( 500u )
#endif
/*
* FreeRTOS debug logging routine (proposal)
* The macro will be called in the printf() style. Users can define
@@ -375,6 +383,14 @@ from the FreeRTOSIPConfig.h configuration header file. */
#endif /* _WINDOWS_ */
#endif /* ipconfigMAXIMUM_DISCOVER_TX_PERIOD */
#if( ipconfigUSE_DNS == 0 )
/* The DNS module will not be included. */
#if( ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) )
/* LLMNR and NBNS depend on DNS because those protocols share a lot of code. */
#error When either LLMNR or NBNS is used, ipconfigUSE_DNS must be defined
#endif
#endif
#ifndef ipconfigUSE_DNS
#define ipconfigUSE_DNS 1
#endif
@@ -408,13 +424,6 @@ from the FreeRTOSIPConfig.h configuration header file. */
#define ipconfigUSE_LLMNR ( 0 )
#endif
#if( !defined( ipconfigUSE_DNS ) )
#if( ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) )
/* LLMNR and NBNS depend on DNS because those protocols share a lot of code. */
#error When either LLMNR or NBNS is used, ipconfigUSE_DNS must be defined
#endif
#endif
#ifndef ipconfigREPLY_TO_INCOMING_PINGS
#define ipconfigREPLY_TO_INCOMING_PINGS 1
#endif
@@ -507,14 +516,6 @@ from the FreeRTOSIPConfig.h configuration header file. */
#define ipconfigSOCKET_HAS_USER_WAKE_CALLBACK 0
#endif
#ifndef ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT
#define ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT 0
#endif
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK != 0 ) && ( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT != 0 )
#error ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT cannot be used with ipconfigSOCKET_HAS_USER_WAKE_CALLBACK - undefine one of them
#endif
#ifndef ipconfigSUPPORT_SELECT_FUNCTION
#define ipconfigSUPPORT_SELECT_FUNCTION 0
#endif
@@ -535,7 +536,7 @@ from the FreeRTOSIPConfig.h configuration header file. */
#define ipconfigUSE_NBNS 0
#endif
/* As an attack surface reduction for ports that listen for inbound
/* As an attack surface reduction for ports that listen for inbound
connections, hang protection can help reduce the impact of SYN floods. */
#ifndef ipconfigTCP_HANG_PROTECTION
#define ipconfigTCP_HANG_PROTECTION 1
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -42,9 +42,9 @@ extern "C" {
typedef struct xARP_CACHE_TABLE_ROW
{
uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
MACAddress_t xMACAddress; /* The MAC address of an ARP cache entry. */
MACAddress_t xMACAddress; /* The MAC address of an ARP cache entry. */
uint8_t ucAge; /* A value that is periodically decremented but can also be refreshed by active communication. The ARP cache entry is removed if the value reaches zero. */
uint8_t ucValid; /* pdTRUE: xMACAddress is valid, pdFALSE: waiting for ARP reply */
uint8_t ucValid; /* pdTRUE: xMACAddress is valid, pdFALSE: waiting for ARP reply */
} ARPCacheRow_t;
typedef enum
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -84,12 +84,12 @@ uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer );
#if( ipconfigUSE_DNS_CACHE != 0 )
/* Look for the indicated host name in the DNS cache. Returns the IPv4
address if present, or 0x0 otherwise. */
/* Look for the indicated host name in the DNS cache. Returns the IPv4
address if present, or 0x0 otherwise. */
uint32_t FreeRTOS_dnslookup( const char *pcHostName );
/* Remove all entries from the DNS cache. */
void FreeRTOS_dnsclear();
/* Remove all entries from the DNS cache. */
void FreeRTOS_dnsclear();
#endif /* ipconfigUSE_DNS_CACHE != 0 */
#if( ipconfigDNS_USE_CALLBACKS != 0 )
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -275,6 +275,15 @@ void FreeRTOS_ClearARP( void );
#endif /* ipconfigDHCP_REGISTER_HOSTNAME */
/* This xApplicationGetRandomNumber() will set *pulNumber to a random number,
and return pdTRUE. When the random number generator is broken, it shall return
pdFALSE.
The function is defined in 'iot_secure_sockets.c'.
If that module is not included in the project, the application must provide an
implementation of it.
The macro's ipconfigRAND32() and configRAND32() are not in use anymore. */
BaseType_t xApplicationGetRandomNumber( uint32_t *pulNumber );
/* For backward compatibility define old structure names to the newer equivalent
structure name. */
#ifndef ipconfigENABLE_BACKWARD_COMPATIBILITY
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -41,10 +41,6 @@ extern "C" {
#include "FreeRTOS_TCP_IP.h"
#endif
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
#include "semphr.h"
#endif
#include "event_groups.h"
typedef struct xNetworkAddressingParameters
@@ -248,16 +244,17 @@ typedef enum
eNoEvent = -1,
eNetworkDownEvent, /* 0: The network interface has been lost and/or needs [re]connecting. */
eNetworkRxEvent, /* 1: The network interface has queued a received Ethernet frame. */
eARPTimerEvent, /* 2: The ARP timer expired. */
eStackTxEvent, /* 3: The software stack has queued a packet to transmit. */
eDHCPEvent, /* 4: Process the DHCP state machine. */
eTCPTimerEvent, /* 5: See if any TCP socket needs attention. */
eTCPAcceptEvent, /* 6: Client API FreeRTOS_accept() waiting for client connections. */
eTCPNetStat, /* 7: IP-task is asked to produce a netstat listing. */
eSocketBindEvent, /* 8: Send a message to the IP-task to bind a socket to a port. */
eSocketCloseEvent, /* 9: Send a message to the IP-task to close a socket. */
eSocketSelectEvent, /*10: Send a message to the IP-task for select(). */
eSocketSignalEvent, /*11: A socket must be signalled. */
eNetworkTxEvent, /* 2: Let the IP-task send a network packet. */
eARPTimerEvent, /* 3: The ARP timer expired. */
eStackTxEvent, /* 4: The software stack has queued a packet to transmit. */
eDHCPEvent, /* 5: Process the DHCP state machine. */
eTCPTimerEvent, /* 6: See if any TCP socket needs attention. */
eTCPAcceptEvent, /* 7: Client API FreeRTOS_accept() waiting for client connections. */
eTCPNetStat, /* 8: IP-task is asked to produce a netstat listing. */
eSocketBindEvent, /* 9: Send a message to the IP-task to bind a socket to a port. */
eSocketCloseEvent, /*10: Send a message to the IP-task to close a socket. */
eSocketSelectEvent, /*11: Send a message to the IP-task for select(). */
eSocketSignalEvent, /*12: A socket must be signalled. */
} eIPEvent_t;
typedef struct IP_TASK_COMMANDS
@@ -441,15 +438,15 @@ uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t
/* Socket related private functions. */
/*
* The caller must ensure that pxNetworkBuffer->xDataLength is the UDP packet
* payload size (excluding packet headers) and that the packet in pucEthernetBuffer
* is at least the size of UDPPacket_t.
/*
* The caller must ensure that pxNetworkBuffer->xDataLength is the UDP packet
* payload size (excluding packet headers) and that the packet in pucEthernetBuffer
* is at least the size of UDPPacket_t.
*/
BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort );
/*
* Initialize the socket list data structures for TCP and UDP.
* Initialize the socket list data structures for TCP and UDP.
*/
BaseType_t vNetworkSocketsInit( void );
@@ -460,13 +457,8 @@ BaseType_t vNetworkSocketsInit( void );
BaseType_t xIPIsNetworkTaskReady( void );
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
struct XSOCKET;
typedef void (*SocketWakeupCallback_t)( struct XSOCKET * pxSocket );
#endif
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT == 1 )
struct XSOCKET;
typedef void( *SocketWakeupCallback_t )( struct XSOCKET * pxSocket, void * pvContext );
struct xSOCKET;
typedef void (*SocketWakeupCallback_t)( struct xSOCKET * pxSocket );
#endif
#if( ipconfigUSE_TCP == 1 )
@@ -553,7 +545,7 @@ BaseType_t xIPIsNetworkTaskReady( void );
* This counter is separate from the xmitCount in the
* TCP win segments */
uint8_t ucTCPState; /* TCP state: see eTCP_STATE */
struct XSOCKET *pxPeerSocket; /* for server socket: child, for child socket: parent */
struct xSOCKET *pxPeerSocket; /* for server socket: child, for child socket: parent */
#if( ipconfigTCP_KEEP_ALIVE == 1 )
uint8_t ucKeepRepCount;
TickType_t xLastAliveTime;
@@ -620,7 +612,7 @@ typedef enum eSOCKET_EVENT {
eSOCKET_ALL = 0x007F,
} eSocketEvent_t;
typedef struct XSOCKET
typedef struct xSOCKET
{
EventBits_t xEventBits;
EventGroupHandle_t xEventGroup;
@@ -635,12 +627,9 @@ typedef struct XSOCKET
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
SemaphoreHandle_t pxUserSemaphore;
#endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 ) || ( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT == 1 )
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
SocketWakeupCallback_t pxUserWakeCallback;
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT == 1 )
void * pvUserWakeCallbackContext;
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT */
#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
struct xSOCKET_SET *pxSocketSet;
@@ -823,3 +812,16 @@ void vIPNetworkUpCalls( void );
#endif
#endif /* FREERTOS_IP_PRIVATE_H */
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -55,7 +55,7 @@ extern "C" {
/* Assigned to an Socket_t variable when the socket is not valid, probably
because it could not be created. */
#define FREERTOS_INVALID_SOCKET ( ( void * ) ~0U )
#define FREERTOS_INVALID_SOCKET ( ( Socket_t ) ~0U )
/* API function error values. As errno is supported, the FreeRTOS sockets
functions return error codes rather than just a pass or fail indication. */
@@ -126,16 +126,12 @@ FreeRTOS_setsockopt(). */
#define FREERTOS_SO_UDP_MAX_RX_PACKETS ( 16 ) /* This option helps to limit the maximum number of packets a UDP socket will buffer */
#endif
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 ) || ( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT == 1 )
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
#define FREERTOS_SO_WAKEUP_CALLBACK ( 17 )
#endif
#define FREERTOS_SO_SET_LOW_HIGH_WATER ( 18 )
#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT == 1 )
#define FREERTOS_SO_WAKE_CALLBACK_CONTEXT ( 19 )
#endif
#define FREERTOS_NOT_LAST_IN_FRAGMENTED_PACKET ( 0x80 ) /* For internal use only, but also part of an 8-bit bitwise value. */
#define FREERTOS_FRAGMENTED_PACKET ( 0x40 ) /* For internal use only, but also part of an 8-bit bitwise value. */
@@ -217,11 +213,13 @@ struct freertos_sockaddr
#endif /* ipconfigBYTE_ORDER */
/* The socket type itself. */
typedef void *Socket_t;
struct xSOCKET;
typedef struct xSOCKET *Socket_t;
/* The SocketSet_t type is the equivalent to the fd_set type used by the
Berkeley API. */
typedef void *SocketSet_t;
struct xSOCKET_SET;
typedef struct xSOCKET_SET *SocketSet_t;
/**
* FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE
@@ -389,3 +387,16 @@ void FreeRTOS_netstat( void );
#endif
#endif /* FREERTOS_SOCKETS_H */
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -157,31 +157,6 @@ size_t uxSize = uxStreamBufferMidSpace( pxBuffer );
}
}
/*-----------------------------------------------------------*/
static portINLINE BaseType_t xStreamBufferIsEmpty( const StreamBuffer_t *pxBuffer );
static portINLINE BaseType_t xStreamBufferIsEmpty( const StreamBuffer_t *pxBuffer )
{
BaseType_t xReturn;
/* True if no item is available */
if( pxBuffer->uxHead == pxBuffer->uxTail )
{
xReturn = pdTRUE;
}
else
{
xReturn = pdFALSE;
}
return xReturn;
}
/*-----------------------------------------------------------*/
static portINLINE BaseType_t xStreamBufferIsFull( const StreamBuffer_t *pxBuffer );
static portINLINE BaseType_t xStreamBufferIsFull( const StreamBuffer_t *pxBuffer )
{
/* True if the available space equals zero. */
return ( BaseType_t ) ( uxStreamBufferGetSpace( pxBuffer ) == 0u );
}
/*-----------------------------------------------------------*/
static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight );
static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight )
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -47,7 +47,7 @@ UBaseType_t uxGetMinimumFreeNetworkBuffers( void );
/* Copy a network buffer into a bigger buffer. */
NetworkBufferDescriptor_t *pxDuplicateNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer,
BaseType_t xNewLength);
size_t uxNewLength);
/* Increase the size of a Network Buffer.
In case BufferAllocation_2.c is used, the new space must be allocated. */
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -280,13 +280,6 @@ UBaseType_t uxCount;
pxReturn->pxNextBuffer = NULL;
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
if( xTCPWindowLoggingLevel > 3 )
{
FreeRTOS_debug_printf( ( "BUF_GET[%ld]: %p (%p)\n",
bIsValidNetworkDescriptor( pxReturn ),
pxReturn, pxReturn->pucEthernetBuffer ) );
}
}
iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
}
@@ -390,11 +383,6 @@ BaseType_t xListItemAlreadyInFreeList;
{
xSemaphoreGive( xNetworkBufferSemaphore );
prvShowWarnings();
if( xTCPWindowLoggingLevel > 3 )
FreeRTOS_debug_printf( ( "BUF_PUT[%ld]: %p (%p) (now %lu)\n",
bIsValidNetworkDescriptor( pxNetworkBuffer ),
pxNetworkBuffer, pxNetworkBuffer->pucEthernetBuffer,
uxGetNumberOfFreeNetworkBuffers( ) ) );
}
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
}
@@ -1,6 +1,6 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.0.11
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -0,0 +1,33 @@
/*
FreeRTOS+TCP V2.0.11
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
http://aws.amazon.com/freertos
http://www.FreeRTOS.org
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
;
#pragma pack(pop)
@@ -0,0 +1,48 @@
/*
FreeRTOS+TCP V2.0.11
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
http://aws.amazon.com/freertos
http://www.FreeRTOS.org
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
#pragma pack(push,1)
@@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/
FreeRTOS+TCP V2.0.11
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
http://aws.amazon.com/freertos
http://www.FreeRTOS.org
*/
/* Standard includes. */
#include <stdint.h>
@@ -83,10 +82,6 @@ expansion. */
#error Please define GMAC_USES_TX_CALLBACK as 1
#endif
#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
#warning The EMAC of SAM4E has fixed-size RX buffers so ZERO_COPY_RX is not possible
#endif
/* Default the size of the stack used by the EMAC deferred handler task to 4x
the size of the stack used by the idle task - but allow this to be overridden in
FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
@@ -239,7 +234,7 @@ const TickType_t x5_Seconds = 5000UL;
configASSERT( xTXDescriptorSemaphore );
}
/* When returning non-zero, the stack will become active and
start DHCP (in configured) */
start DHCP (in configured) */
return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
}
/*-----------------------------------------------------------*/
@@ -418,11 +413,11 @@ const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );
if ( xProtPacket->xTCPPacket.xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
{
IPHeader_t *pxIPHeader = &( xProtPacket->xTCPPacket.xIPHeader );
IPHeader_t *pxIPHeader = &(xProtPacket->xTCPPacket.xIPHeader);
/* Calculate the IP header checksum. */
pxIPHeader->usHeaderChecksum = 0x00;
pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0u, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
/* Calculate the TCP checksum for an outgoing packet. */
@@ -504,43 +499,15 @@ static IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
}
/*-----------------------------------------------------------*/
void vCheckBuffersAndQueue( void )
{
static UBaseType_t uxLastMinBufferCount = 0;
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
static UBaseType_t uxLastMinQueueSpace;
#endif
static UBaseType_t uxCurrentCount;
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
{
uxCurrentCount = uxGetMinimumIPQueueSpace();
if( uxLastMinQueueSpace != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinQueueSpace = uxCurrentCount;
FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
}
}
#endif /* ipconfigCHECK_IP_QUEUE_SPACE */
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
if( uxLastMinBufferCount != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinBufferCount = uxCurrentCount;
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
}
}
static void prvEMACHandlerTask( void *pvParameters )
{
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
UBaseType_t uxCount;
UBaseType_t uxLastMinBufferCount = 0, uxCount;
UBaseType_t uxCurrentCount;
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
UBaseType_t uxLastMinQueueSpace;
#endif
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
NetworkBufferDescriptor_t *pxBuffer;
#endif
@@ -559,7 +526,28 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
for( ;; )
{
vCheckBuffersAndQueue();
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
if( uxLastMinBufferCount != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinBufferCount = uxCurrentCount;
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
}
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
{
uxCurrentCount = uxGetMinimumIPQueueSpace();
if( uxLastMinQueueSpace != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinQueueSpace = uxCurrentCount;
FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
}
}
#endif /* ipconfigCHECK_IP_QUEUE_SPACE */
if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
{
@@ -429,7 +429,6 @@ void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
* GMAC_DCFGR_TXCOEN: (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable.
* Note: tha SAM4E does have RX checksum offloading
* but TX checksum offloading has NOT been implemented.
* http://community.atmel.com/forum/sam4e-gmac-transmit-checksum-offload-enablesolved
*/
gmac_set_dma(p_gmac,
@@ -658,7 +657,7 @@ uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
}
#else
{
/* Or memcopy... */
/* Or Memcopy... */
memcpy((void *)p_tx_td->addr, p_buffer, ul_size);
}
#endif /* ipconfigZERO_COPY_TX_DRIVER */
@@ -1,28 +1,3 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/
/*
* Handling of Ethernet PHY's
* PHY's communicate with an EMAC either through
@@ -57,14 +32,29 @@
#endif
#ifndef ipconfigPHY_LS_HIGH_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
/* Check if the LinkStatus in the PHY is still high after 15 seconds of not
receiving packets. */
#define ipconfigPHY_LS_HIGH_CHECK_TIME_MS 15000
#define ipconfigPHY_LS_HIGH_CHECK_TIME_MS 15000uL
#endif
#ifndef ipconfigPHY_LS_LOW_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still low every second. */
#define ipconfigPHY_LS_LOW_CHECK_TIME_MS 1000
/* Check if the LinkStatus in the PHY is still low every second. */
#define ipconfigPHY_LS_LOW_CHECK_TIME_MS 1000uL
#endif
/* As the following 3 macro's are OK in most situations, and so they're not
included in 'FreeRTOSIPConfigDefaults.h'.
Users can change their values in the project's 'FreeRTOSIPConfig.h'. */
#ifndef phyPHY_MAX_RESET_TIME_MS
#define phyPHY_MAX_RESET_TIME_MS 1000uL
#endif
#ifndef phyPHY_MAX_NEGOTIATE_TIME_MS
#define phyPHY_MAX_NEGOTIATE_TIME_MS 3000uL
#endif
#ifndef phySHORT_DELAY_MS
#define phySHORT_DELAY_MS 50uL
#endif
/* Naming and numbering of basic PHY registers. */
@@ -113,16 +103,18 @@
* Description of all capabilities that can be advertised to
* the peer (usually a switch or router).
*/
#define phyADVERTISE_CSMA 0x0001u /* Only selector supported. */
#define phyADVERTISE_CSMA 0x0001u /* Supports IEEE 802.3u: Fast Ethernet at 100 Mbit/s */
#define phyADVERTISE_10HALF 0x0020u /* Try for 10mbps half-duplex. */
#define phyADVERTISE_10FULL 0x0040u /* Try for 10mbps full-duplex. */
#define phyADVERTISE_100HALF 0x0080u /* Try for 100mbps half-duplex. */
#define phyADVERTISE_100FULL 0x0100u /* Try for 100mbps full-duplex. */
#define phyADVERTISE_ALL ( phyADVERTISE_10HALF | phyADVERTISE_10FULL | \
phyADVERTISE_100HALF | phyADVERTISE_100FULL )
phyADVERTISE_100HALF | phyADVERTISE_100FULL | \
phyADVERTISE_CSMA )
/* Send a reset commando to a set of PHY-ports. */
/* Send a reset command to a set of PHY-ports. */
static uint32_t xPhyReset( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask );
static BaseType_t xHas_1F_PHYSPCS( uint32_t ulPhyID )
@@ -224,7 +216,7 @@ BaseType_t xPhyAddress;
}
/*-----------------------------------------------------------*/
/* Send a reset commando to a set of PHY-ports. */
/* Send a reset command to a set of PHY-ports. */
static uint32_t xPhyReset( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
{
uint32_t ulDoneMask, ulConfig;
@@ -232,7 +224,7 @@ TickType_t xRemainingTime;
TimeOut_t xTimer;
BaseType_t xPhyIndex;
/* A bit-mask ofPHY ports that are ready. */
/* A bit-mask of PHY ports that are ready. */
ulDoneMask = 0ul;
/* Set the RESET bits high. */
@@ -245,7 +237,7 @@ BaseType_t xPhyIndex;
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig | phyBMCR_RESET );
}
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 1000UL );
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( phyPHY_MAX_RESET_TIME_MS );
vTaskSetTimeOutState( &xTimer );
/* The reset should last less than a second. */
@@ -272,19 +264,23 @@ BaseType_t xPhyIndex;
break;
}
/* Block for a while */
vTaskDelay( pdMS_TO_TICKS( 50ul ) );
vTaskDelay( pdMS_TO_TICKS( phySHORT_DELAY_MS ) );
}
/* Clear the reset bits. */
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
if( ( ulDoneMask & ( 1ul << xPhyIndex ) ) == 0uL )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig & ~phyBMCR_RESET );
/* The reset operation timed out, clear the bit manually. */
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig & ~phyBMCR_RESET );
}
}
vTaskDelay( pdMS_TO_TICKS( 50ul ) );
vTaskDelay( pdMS_TO_TICKS( phySHORT_DELAY_MS ) );
return ulDoneMask;
}
@@ -297,7 +293,7 @@ BaseType_t xPhyIndex;
if( pxPhyObject->xPortCount < 1 )
{
FreeRTOS_printf( ( "xPhyResetAll: No PHY's detected.\n" ) );
FreeRTOS_printf( ( "xPhyConfigure: No PHY's detected.\n" ) );
return -1;
}
@@ -308,11 +304,12 @@ BaseType_t xPhyIndex;
/* Set advertise register. */
if( ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO ) && ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO ) )
{
ulAdvertise = phyADVERTISE_CSMA | phyADVERTISE_ALL;
ulAdvertise = phyADVERTISE_ALL;
/* Reset auto-negotiation capability. */
}
else
{
/* Always select protocol 802.3u. */
ulAdvertise = phyADVERTISE_CSMA;
if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO )
@@ -361,7 +358,7 @@ BaseType_t xPhyIndex;
}
}
/* Send a reset commando to a set of PHY-ports. */
/* Send a reset command to a set of PHY-ports. */
xPhyReset( pxPhyObject, xPhyGetMask( pxPhyObject ) );
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
@@ -450,6 +447,10 @@ BaseType_t xPhyIndex;
}
/*-----------------------------------------------------------*/
/* xPhyFixedValue(): this function is called in case auto-negotiation is disabled.
The caller has set the values in 'xPhyPreferences' (ucDuplex and ucSpeed).
The PHY register phyREG_00_BMCR will be set for every connected PHY that matches
with ulPhyMask. */
BaseType_t xPhyFixedValue( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
{
BaseType_t xPhyIndex;
@@ -480,6 +481,9 @@ uint32_t ulValue, ulBitMask = ( uint32_t )1u;
}
/*-----------------------------------------------------------*/
/* xPhyStartAutoNegotiation() is the alternative xPhyFixedValue():
It sets the BMCR_AN_RESTART bit and waits for the auto-negotiation completion
( phyBMSR_AN_COMPLETE ). */
BaseType_t xPhyStartAutoNegotiation( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
{
uint32_t xPhyIndex, ulDoneMask, ulBitMask;
@@ -491,7 +495,7 @@ TimeOut_t xTimer;
{
return 0;
}
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
for( xPhyIndex = 0; xPhyIndex < ( uint32_t ) pxPhyObject->xPortCount; xPhyIndex++ )
{
if( ( ulPhyMask & ( 1lu << xPhyIndex ) ) != 0lu )
{
@@ -502,14 +506,14 @@ TimeOut_t xTimer;
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue | phyBMCR_AN_RESTART );
}
}
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 3000UL );
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( phyPHY_MAX_NEGOTIATE_TIME_MS );
vTaskSetTimeOutState( &xTimer );
ulDoneMask = 0;
/* Wait until the auto-negotiation will be completed */
for( ;; )
{
ulBitMask = ( uint32_t )1u;
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
for( xPhyIndex = 0; xPhyIndex < ( uint32_t ) pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
if( ( ulPhyMask & ulBitMask ) != 0lu )
{
@@ -531,17 +535,17 @@ TimeOut_t xTimer;
}
if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
{
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
FreeRTOS_printf( ( "xPhyStartAutoNegotiation: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
break;
}
vTaskDelay( pdMS_TO_TICKS( 50 ) );
vTaskDelay( pdMS_TO_TICKS( phySHORT_DELAY_MS ) );
}
if( ulDoneMask != ( uint32_t)0u )
{
ulBitMask = ( uint32_t )1u;
pxPhyObject->ulLinkStatusMask &= ~( ulDoneMask );
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
for( xPhyIndex = 0; xPhyIndex < ( uint32_t ) pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
uint32_t ulPhyID = pxPhyObject->ulPhyIDs[ xPhyIndex ];
@@ -623,7 +627,7 @@ TimeOut_t xTimer;
pxPhyObject->fnPhyRead( xPhyAddress, PHYREG_10_PHYSTS, &ulRegValue);
}
FreeRTOS_printf( ( ">> Autonego ready: %08lx: %s duplex %u mbit %s status\n",
FreeRTOS_printf( ( "Autonego ready: %08lx: %s duplex %u mbit %s status\n",
ulRegValue,
( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
@@ -676,6 +680,9 @@ BaseType_t xNeedCheck = pdFALSE;
}
else if( xTaskCheckForTimeOut( &( pxPhyObject->xLinkStatusTimer ), &( pxPhyObject->xLinkStatusRemaining ) ) != pdFALSE )
{
/* Frequent checking the PHY Link Status can affect for the performance of Ethernet controller.
As long as packets are received, no polling is needed.
Otherwise, polling will be done when the 'xLinkStatusTimer' expires. */
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
@@ -700,10 +707,12 @@ BaseType_t xNeedCheck = pdFALSE;
vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
if( ( pxPhyObject->ulLinkStatusMask & phyBMSR_LINK_STATUS ) != 0 )
{
/* The link status is high, so don't poll the PHY too often. */
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
}
else
{
/* The link status is low, polling may be done more frequently. */
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_LOW_CHECK_TIME_MS );
}
}
@@ -0,0 +1,331 @@
/*
FreeRTOS+TCP V2.0.11
Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
http://aws.amazon.com/freertos
http://www.FreeRTOS.org
*/
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "list.h"
#include "queue.h"
#include "semphr.h"
#include "task.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
#include "m480_eth.h"
/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
driver will filter incoming packets and only pass the stack those packets it
considers need processing. */
#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
#else
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
#endif
/* Default the size of the stack used by the EMAC deferred handler task to twice
the size of the stack used by the idle task - but allow this to be overridden in
FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
#ifndef configEMAC_TASK_STACK_SIZE
#define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
#endif
static SemaphoreHandle_t xTXMutex = NULL;
/* The handle of the task that processes Rx packets. The handle is required so
the task can be notified when new packets arrive. */
static TaskHandle_t xRxHanderTask = NULL;
static TimerHandle_t xPhyHandlerTask = NULL;
/*
* A task that processes received frames.
*/
static void prvEMACHandlerTask( void *pvParameters );
static void prvPhyTmrCallback( TimerHandle_t xTimer );
/* The size of each buffer when BufferAllocation_1 is used:
http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
#define niBUFFER_1_PACKET_SIZE 1536
#ifdef __ICCARM__
#pragma data_alignment=4
static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ]
#else
static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ((aligned(4)));
#endif
BaseType_t xNetworkInterfaceInitialise( void )
{
uint8_t hwaddr[6];
BaseType_t xReturn = pdPASS;
/* Init ETH */
numaker_mac_address(hwaddr);
FreeRTOS_UpdateMACAddress(hwaddr);
FreeRTOS_printf( ("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", hwaddr[0], hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]) );
/* Enable clock & set EMAC configuration */
/* Enable MAC and DMA transmission and reception */
if( numaker_eth_init(hwaddr) < 0)
{
xReturn = pdFAIL;
} else {
xReturn = pdPASS;
/* Guard against the task being created more than once and the
descriptors being initialized more than once. */
/* Timer task to monitor PHY Link status */
if( xPhyHandlerTask == NULL )
{
xPhyHandlerTask = xTimerCreate( "TimerPhy", pdMS_TO_TICKS( 1000 ), pdTRUE, 0, prvPhyTmrCallback );
configASSERT(xPhyHandlerTask);
xReturn = xTimerStart( xPhyHandlerTask, 0 ) ;
configASSERT( xReturn );
}
/* Rx task */
if( xRxHanderTask == NULL )
{
xReturn = xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xRxHanderTask );
configASSERT( xReturn );
}
if( xTXMutex == NULL )
{
xTXMutex = xSemaphoreCreateMutex();
configASSERT( xTXMutex );
}
}
NVIC_SetPriority( EMAC_RX_IRQn, configMAC_INTERRUPT_PRIORITY );
NVIC_SetPriority( EMAC_TX_IRQn, configMAC_INTERRUPT_PRIORITY );
numaker_eth_enable_interrupts();
FreeRTOS_printf( ("ETH-RX priority:%d\n",NVIC_GetPriority( EMAC_RX_IRQn)) );
return xReturn;
}
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t xReleaseAfterSend )
{
uint8_t *buffer=NULL;
// FreeRTOS_printf(("<-- dataLength=%d\n",pxDescriptor->xDataLength));
if( pxDescriptor->xDataLength >= PACKET_BUFFER_SIZE )
{
FreeRTOS_printf(("TX buffer length %d over %d\n", pxDescriptor->xDataLength, PACKET_BUFFER_SIZE));
return pdFALSE;
}
buffer = numaker_eth_get_tx_buf();
if( buffer == NULL )
{
NU_DEBUGF(("Eth TX slots are busy\n"));
return pdFALSE;
}
/* Get exclusive access */
xSemaphoreTake(xTXMutex, portMAX_DELAY);
NU_DEBUGF(("%s ... buffer=0x%x\r\n",__FUNCTION__, buffer));
//SendData: pt = pxDescriptor->pucBuffer, length = pxDescriptor->xDataLength
memcpy(buffer, pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength);
numaker_eth_trigger_tx(pxDescriptor->xDataLength, NULL);
/* 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 );
}
xSemaphoreGive(xTXMutex);
return pdTRUE;
}
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
{
uint8_t *ucRAMBuffer = ucNetworkPackets;
uint32_t ul;
for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
{
pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
*( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
}
}
BaseType_t xGetPhyLinkStatus( void )
{
BaseType_t xReturn;
if( numaker_eth_link_ok() )
{
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
static void prvPhyTmrCallback( TimerHandle_t xTimer )
{
IPStackEvent_t xRxEvent;
static BaseType_t lastLink = pdFAIL;
BaseType_t currLink = xGetPhyLinkStatus();
if( currLink != lastLink )
{
FreeRTOS_printf(("PHY Link %s\n", (currLink) ? "Up" : "Down"));
if( !currLink )
{
xRxEvent.eEventType = eNetworkDownEvent;
xSendEventStructToIPTask( &xRxEvent, 0 );
}
lastLink = currLink;
}
}
static void prvEMACHandlerTask( void *pvParameters )
{
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
UBaseType_t uxLastMinBufferCount = 0;
UBaseType_t uxCurrentCount;
BaseType_t xResult = 0;
uint32_t ulStatus;
uint16_t dataLength = 0;
uint8_t *buffer = NULL;
NetworkBufferDescriptor_t *pxBufferDescriptor = NULL;
IPStackEvent_t xRxEvent;
const TickType_t xBlockTime = pdMS_TO_TICKS( 5000ul );
/* Remove compiler warnings about unused parameters. */
( void ) pvParameters;
/* A possibility to set some additional task properties. */
for( ;; )
{
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
if( uxLastMinBufferCount != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinBufferCount = uxCurrentCount;
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
}
/* No events to process now, wait for the next. */
ulTaskNotifyTake( pdFALSE, portMAX_DELAY );
while(1)
{
/* get received frame */
if ( numaker_eth_get_rx_buf(&dataLength, &buffer) != 0) {
/* The event was lost because a network buffer was not available.
Call the standard trace macro to log the occurrence. */
iptraceETHERNET_RX_EVENT_LOST();
break;
}
/* 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. */
pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( PACKET_BUFFER_SIZE, 0 );
if( pxBufferDescriptor != NULL )
{
memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer, dataLength );
// FreeRTOS_printf(("--> dataLength=%d\n",dataLength));
pxBufferDescriptor->xDataLength = dataLength;
} else {
numaker_eth_rx_next();
iptraceETHERNET_RX_EVENT_LOST();
break;
}
/* 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 * ) pxBufferDescriptor;
/* 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( pxBufferDescriptor );
/* 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();
}
numaker_eth_rx_next();
}
numaker_eth_trigger_rx();
}
}
void xNetworkCallback(char event)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
switch (event)
{
case 'R': //For RX event
/* Wakeup the prvEMACHandlerTask. */
if( xRxHanderTask != NULL )
{
vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
break;
case 'T': //For TX event
// ack of tx done, no-op in this stage
break;
default:
break;
}
}
@@ -0,0 +1,448 @@
/**************************************************************************//**
* @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of Nuvoton Technology Corp. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include "FreeRTOS.h"
#include "list.h"
#include "FreeRTOS_IP.h"
#include "m480_eth.h"
#define ETH_TRIGGER_RX() do{EMAC->RXST = 0;}while(0)
#define ETH_TRIGGER_TX() do{EMAC->TXST = 0;}while(0)
#define ETH_ENABLE_TX() do{EMAC->CTL |= EMAC_CTL_TXON;}while(0)
#define ETH_ENABLE_RX() do{EMAC->CTL |= EMAC_CTL_RXON;}while(0)
#define ETH_DISABLE_TX() do{EMAC->CTL &= ~EMAC_CTL_TXON;}while(0)
#define ETH_DISABLE_RX() do{EMAC->CTL &= ~EMAC_CTL_RXON;}while(0)
struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
#ifdef __ICCARM__
#pragma data_alignment=4
struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM];
struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM];
uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
#else
struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE] __attribute__ ((aligned(4)));
uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE] __attribute__ ((aligned(4)));
#endif
struct eth_descriptor volatile *cur_tx_desc_ptr, *cur_rx_desc_ptr, *fin_tx_desc_ptr;
// PTP source clock is 84MHz (Real chip using PLL). Each tick is 11.90ns
// Assume we want to set each tick to 100ns.
// Increase register = (100 * 2^31) / (10^9) = 214.71 =~ 215 = 0xD7
// Addend register = 2^32 * tick_freq / (84MHz), where tick_freq = (2^31 / 215) MHz
// From above equation, addend register = 2^63 / (84M * 215) ~= 510707200 = 0x1E70C600
static void mdio_write(uint8_t addr, uint8_t reg, uint16_t val)
{
EMAC->MIIMDAT = val;
EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_WRITE_Msk | EMAC_MIIMCTL_MDCON_Msk;
while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
}
static uint16_t mdio_read(uint8_t addr, uint8_t reg)
{
EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_MDCON_Msk;
while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
return(EMAC->MIIMDAT);
}
static int reset_phy(void)
{
uint16_t reg;
uint32_t delayCnt;
mdio_write(CONFIG_PHY_ADDR, MII_BMCR, BMCR_RESET);
delayCnt = 2000;
while(delayCnt-- > 0) {
if((mdio_read(CONFIG_PHY_ADDR, MII_BMCR) & BMCR_RESET) == 0)
break;
}
if(delayCnt == 0) {
NU_DEBUGF(("Reset phy failed\n"));
return(-1);
}
mdio_write(CONFIG_PHY_ADDR, MII_ADVERTISE, ADVERTISE_CSMA |
ADVERTISE_10HALF |
ADVERTISE_10FULL |
ADVERTISE_100HALF |
ADVERTISE_100FULL);
reg = mdio_read(CONFIG_PHY_ADDR, MII_BMCR);
mdio_write(CONFIG_PHY_ADDR, MII_BMCR, reg | BMCR_ANRESTART);
delayCnt = 200000;
while(delayCnt-- > 0) {
if((mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
== (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
break;
}
if(delayCnt == 0) {
NU_DEBUGF(("AN failed. Set to 100 FULL\n"));
EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
return(-1);
} else {
reg = mdio_read(CONFIG_PHY_ADDR, MII_LPA);
if(reg & ADVERTISE_100FULL) {
NU_DEBUGF(("100 full\n"));
EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
} else if(reg & ADVERTISE_100HALF) {
NU_DEBUGF(("100 half\n"));
EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_FUDUP_Msk) | EMAC_CTL_OPMODE_Msk;
} else if(reg & ADVERTISE_10FULL) {
NU_DEBUGF(("10 full\n"));
EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_OPMODE_Msk) | EMAC_CTL_FUDUP_Msk;
} else {
NU_DEBUGF(("10 half\n"));
EMAC->CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
}
}
FreeRTOS_printf(("PHY ID 1:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID1)));
FreeRTOS_printf(("PHY ID 2:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID2)));
return(0);
}
static void init_tx_desc(void)
{
uint32_t i;
cur_tx_desc_ptr = fin_tx_desc_ptr = &tx_desc[0];
for(i = 0; i < TX_DESCRIPTOR_NUM; i++) {
tx_desc[i].status1 = TXFD_PADEN | TXFD_CRCAPP | TXFD_INTEN;
tx_desc[i].buf = &tx_buf[i][0];
tx_desc[i].status2 = 0;
tx_desc[i].next = &tx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
}
EMAC->TXDSA = (unsigned int)&tx_desc[0];
return;
}
static void init_rx_desc(void)
{
uint32_t i;
cur_rx_desc_ptr = &rx_desc[0];
for(i = 0; i < RX_DESCRIPTOR_NUM; i++) {
rx_desc[i].status1 = OWNERSHIP_EMAC;
rx_desc[i].buf = &rx_buf[i][0];
rx_desc[i].status2 = 0;
rx_desc[i].next = &rx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
}
EMAC->RXDSA = (unsigned int)&rx_desc[0];
return;
}
void numaker_set_mac_addr(uint8_t *addr)
{
EMAC->CAM0M = (addr[0] << 24) |
(addr[1] << 16) |
(addr[2] << 8) |
addr[3];
EMAC->CAM0L = (addr[4] << 24) |
(addr[5] << 16);
}
static void __eth_clk_pin_init()
{
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable IP clock */
CLK_EnableModuleClock(EMAC_MODULE);
// Configure MDC clock rate to HCLK / (127 + 1) = 1.25 MHz if system is running at 160 MH
CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
/* Update System Core Clock */
SystemCoreClockUpdate();
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
// Configure RMII pins
SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA6MFP_Msk | SYS_GPA_MFPL_PA7MFP_Msk);
SYS->GPA_MFPL |= SYS_GPA_MFPL_PA6MFP_EMAC_RMII_RXERR | SYS_GPA_MFPL_PA7MFP_EMAC_RMII_CRSDV;
SYS->GPC_MFPL &= ~(SYS_GPC_MFPL_PC6MFP_Msk | SYS_GPC_MFPL_PC7MFP_Msk);
SYS->GPC_MFPL |= SYS_GPC_MFPL_PC6MFP_EMAC_RMII_RXD1 | SYS_GPC_MFPL_PC7MFP_EMAC_RMII_RXD0;
SYS->GPC_MFPH &= ~SYS_GPC_MFPH_PC8MFP_Msk;
SYS->GPC_MFPH |= SYS_GPC_MFPH_PC8MFP_EMAC_RMII_REFCLK;
SYS->GPE_MFPH &= ~(SYS_GPE_MFPH_PE8MFP_Msk | SYS_GPE_MFPH_PE9MFP_Msk | SYS_GPE_MFPH_PE10MFP_Msk |
SYS_GPE_MFPH_PE11MFP_Msk | SYS_GPE_MFPH_PE12MFP_Msk);
SYS->GPE_MFPH |= SYS_GPE_MFPH_PE8MFP_EMAC_RMII_MDC |
SYS_GPE_MFPH_PE9MFP_EMAC_RMII_MDIO |
SYS_GPE_MFPH_PE10MFP_EMAC_RMII_TXD0 |
SYS_GPE_MFPH_PE11MFP_EMAC_RMII_TXD1 |
SYS_GPE_MFPH_PE12MFP_EMAC_RMII_TXEN;
// Enable high slew rate on all RMII TX output pins
PE->SLEWCTL = (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN10_Pos) |
(GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN11_Pos) |
(GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN12_Pos);
/* Lock protected registers */
SYS_LockReg();
}
int numaker_eth_init(uint8_t *mac_addr)
{
int ret = 0;
// init CLK & pins
__eth_clk_pin_init();
// Reset MAC
EMAC->CTL = EMAC_CTL_RST_Msk;
while(EMAC->CTL & EMAC_CTL_RST_Msk) {}
init_tx_desc();
init_rx_desc();
numaker_set_mac_addr(mac_addr); // need to reconfigure hardware address 'cos we just RESET emc...
/* Configure the MAC interrupt enable register. */
EMAC->INTEN = EMAC_INTEN_RXIEN_Msk |
EMAC_INTEN_TXIEN_Msk |
EMAC_INTEN_RXGDIEN_Msk |
EMAC_INTEN_TXCPIEN_Msk |
EMAC_INTEN_RXBEIEN_Msk |
EMAC_INTEN_TXBEIEN_Msk |
EMAC_INTEN_RDUIEN_Msk |
EMAC_INTEN_TSALMIEN_Msk |
EMAC_INTEN_WOLIEN_Msk;
/* Configure the MAC control register. */
EMAC->CTL = EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RMIIEN_Msk;
/* Accept packets for us and all broadcast and multicast packets */
EMAC->CAMCTL = EMAC_CAMCTL_CMPEN_Msk |
EMAC_CAMCTL_AMP_Msk |
EMAC_CAMCTL_ABP_Msk;
EMAC->CAMEN = 1; // Enable CAM entry 0
ret= reset_phy();
EMAC_ENABLE_RX();
EMAC_ENABLE_TX();
return ret;
}
void ETH_halt(void)
{
EMAC->CTL &= ~(EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk);
}
unsigned int m_status;
void EMAC_RX_IRQHandler(void)
{
// NU_DEBUGF(("%s ... \r\n", __FUNCTION__));
m_status = EMAC->INTSTS & 0xFFFF;
EMAC->INTSTS = m_status;
if (m_status & EMAC_INTSTS_RXBEIF_Msk) {
// Shouldn't goes here, unless descriptor corrupted
NU_DEBUGF(("RX descriptor corrupted \r\n"));
//return;
}
// FIX ME: for rx-event, to ack rx_isr into event queue
xNetworkCallback('R');
}
void numaker_eth_trigger_rx(void)
{
ETH_TRIGGER_RX();
}
int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
{
unsigned int cur_entry, status;
cur_entry = EMAC->CRXDSA;
if ((cur_entry == (uint32_t)cur_rx_desc_ptr) && (!(m_status & EMAC_INTSTS_RDUIF_Msk))) // cur_entry may equal to cur_rx_desc_ptr if RDU occures
return -1;
status = cur_rx_desc_ptr->status1;
if(status & OWNERSHIP_EMAC)
return -1;
if (status & RXFD_RXGD) {
*buf = cur_rx_desc_ptr->buf;
*len = status & 0xFFFF;
}
return 0;
}
void numaker_eth_rx_next(void)
{
cur_rx_desc_ptr->status1 = OWNERSHIP_EMAC;
cur_rx_desc_ptr = cur_rx_desc_ptr->next;
}
void EMAC_TX_IRQHandler(void)
{
unsigned int cur_entry, status;
status = EMAC->INTSTS & 0xFFFF0000;
EMAC->INTSTS = status;
if(status & EMAC_INTSTS_TXBEIF_Msk) {
// Shouldn't goes here, unless descriptor corrupted
return;
}
cur_entry = EMAC->CTXDSA;
while (cur_entry != (uint32_t)fin_tx_desc_ptr) {
fin_tx_desc_ptr = fin_tx_desc_ptr->next;
}
// FIX ME: for tx-event, no-op at this stage
xNetworkCallback('T');
}
uint8_t *numaker_eth_get_tx_buf(void)
{
if(cur_tx_desc_ptr->status1 & OWNERSHIP_EMAC)
return(NULL);
else
return(cur_tx_desc_ptr->buf);
}
void numaker_eth_trigger_tx(uint16_t length, void *p)
{
struct eth_descriptor volatile *desc;
cur_tx_desc_ptr->status2 = (unsigned int)length;
desc = cur_tx_desc_ptr->next; // in case TX is transmitting and overwrite next pointer before we can update cur_tx_desc_ptr
cur_tx_desc_ptr->status1 |= OWNERSHIP_EMAC;
cur_tx_desc_ptr = desc;
ETH_TRIGGER_TX();
}
int numaker_eth_link_ok(void)
{
/* first, a dummy read to latch */
mdio_read(CONFIG_PHY_ADDR, MII_BMSR);
if(mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & BMSR_LSTATUS)
return 1;
return 0;
}
//void numaker_eth_set_cb(eth_callback_t eth_cb, void *userData)
//{
// nu_eth_txrx_cb = eth_cb;
// nu_userData = userData;
//}
// Provide ethernet devices with a semi-unique MAC address
void numaker_mac_address(uint8_t *mac)
{
uint32_t uID1;
// Fetch word 0
uint32_t word0 = *(uint32_t *)0x7F804; // 2KB Data Flash at 0x7F800
// Fetch word 1
// we only want bottom 16 bits of word1 (MAC bits 32-47)
// and bit 9 forced to 1, bit 8 forced to 0
// Locally administered MAC, reduced conflicts
// http://en.wikipedia.org/wiki/MAC_address
uint32_t word1 = *(uint32_t *)0x7F800; // 2KB Data Flash at 0x7F800
if( word0 == 0xFFFFFFFF ) // Not burn any mac address at 1st 2 words of Data Flash
{
// with a semi-unique MAC address from the UUID
/* Enable FMC ISP function */
SYS_UnlockReg();
FMC_Open();
// = FMC_ReadUID(0);
uID1 = FMC_ReadUID(1);
word1 = (uID1 & 0x003FFFFF) | ((uID1 & 0x030000) << 6) >> 8;
word0 = ((FMC_ReadUID(0) >> 4) << 20) | ((uID1 & 0xFF)<<12) | (FMC_ReadUID(2) & 0xFFF);
/* Disable FMC ISP function */
FMC_Close();
/* Lock protected registers */
SYS_LockReg();
}
word1 |= 0x00000200;
word1 &= 0x0000FEFF;
mac[0] = (word1 & 0x0000ff00) >> 8;
mac[1] = (word1 & 0x000000ff);
mac[2] = (word0 & 0xff000000) >> 24;
mac[3] = (word0 & 0x00ff0000) >> 16;
mac[4] = (word0 & 0x0000ff00) >> 8;
mac[5] = (word0 & 0x000000ff);
NU_DEBUGF(("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", mac[0], mac[1],mac[2],mac[3],mac[4],mac[5]));
}
void numaker_eth_enable_interrupts(void) {
EMAC->INTEN |= EMAC_INTEN_RXIEN_Msk |
EMAC_INTEN_TXIEN_Msk ;
NVIC_EnableIRQ(EMAC_RX_IRQn);
NVIC_EnableIRQ(EMAC_TX_IRQn);
}
void numaker_eth_disable_interrupts(void) {
NVIC_DisableIRQ(EMAC_RX_IRQn);
NVIC_DisableIRQ(EMAC_TX_IRQn);
}
@@ -0,0 +1,164 @@
/**************************************************************************//**
* @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of Nuvoton Technology Corp. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include "M480.h"
#ifndef _M480_ETH_
#define _M480_ETH_
/* Generic MII registers. */
#define MII_BMCR 0x00 /* Basic mode control register */
#define MII_BMSR 0x01 /* Basic mode status register */
#define MII_PHYSID1 0x02 /* PHYS ID 1 */
#define MII_PHYSID2 0x03 /* PHYS ID 2 */
#define MII_ADVERTISE 0x04 /* Advertisement control reg */
#define MII_LPA 0x05 /* Link partner ability reg */
#define MII_EXPANSION 0x06 /* Expansion register */
#define MII_DCOUNTER 0x12 /* Disconnect counter */
#define MII_FCSCOUNTER 0x13 /* False carrier counter */
#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
#define MII_RERRCOUNTER 0x15 /* Receive error counter */
#define MII_SREVISION 0x16 /* Silicon revision */
#define MII_RESV1 0x17 /* Reserved... */
#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
#define MII_PHYADDR 0x19 /* PHY address */
#define MII_RESV2 0x1a /* Reserved... */
#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
#define MII_NCONFIG 0x1c /* Network interface config */
/* Basic mode control register. */
#define BMCR_RESV 0x007f /* Unused... */
#define BMCR_CTST 0x0080 /* Collision test */
#define BMCR_FULLDPLX 0x0100 /* Full duplex */
#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
#define BMCR_RESET 0x8000 /* Reset the DP83840 */
/* Basic mode status register. */
#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
#define BMSR_JCD 0x0002 /* Jabber detected */
#define BMSR_LSTATUS 0x0004 /* Link status */
#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
#define BMSR_RFAULT 0x0010 /* Remote fault detected */
#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
#define BMSR_RESV 0x07c0 /* Unused... */
#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
/* Advertisement control register. */
#define ADVERTISE_SLCT 0x001f /* Selector bits */
#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
#define ADVERTISE_RESV 0x1c00 /* Unused... */
#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
#define RX_DESCRIPTOR_NUM 4 //8 // Max Number of Rx Frame Descriptors
#define TX_DESCRIPTOR_NUM 2 //4 // Max number of Tx Frame Descriptors
#define PACKET_BUFFER_SIZE 1520
#define CONFIG_PHY_ADDR 1
// Frame Descriptor's Owner bit
#define OWNERSHIP_EMAC 0x80000000 // 1 = EMAC
//#define OWNERSHIP_CPU 0x7fffffff // 0 = CPU
// Rx Frame Descriptor Status
#define RXFD_RXGD 0x00100000 // Receiving Good Packet Received
#define RXFD_RTSAS 0x00800000 // RX Time Stamp Available
// Tx Frame Descriptor's Control bits
#define TXFD_TTSEN 0x08 // Tx Time Stamp Enable
#define TXFD_INTEN 0x04 // Interrupt Enable
#define TXFD_CRCAPP 0x02 // Append CRC
#define TXFD_PADEN 0x01 // Padding Enable
// Tx Frame Descriptor Status
#define TXFD_TXCP 0x00080000 // Transmission Completion
#define TXFD_TTSAS 0x08000000 // TX Time Stamp Available
// Tx/Rx buffer descriptor structure
struct eth_descriptor;
struct eth_descriptor {
uint32_t status1;
uint8_t *buf;
uint32_t status2;
struct eth_descriptor *next;
#ifdef TIME_STAMPING
uint32_t backup1;
uint32_t backup2;
uint32_t reserved1;
uint32_t reserved2;
#endif
};
#ifdef TIME_STAMPING
#define ETH_TS_ENABLE() do{EMAC->TSCTL = EMAC_TSCTL_TSEN_Msk;}while(0)
#define ETH_TS_START() do{EMAC->TSCTL |= (EMAC_TSCTL_TSMODE_Msk | EMAC_TSCTL_TSIEN_Msk);}while(0)
s32_t ETH_settime(u32_t sec, u32_t nsec);
s32_t ETH_gettime(u32_t *sec, u32_t *nsec);
s32_t ETH_updatetime(u32_t neg, u32_t sec, u32_t nsec);
s32_t ETH_adjtimex(int ppm);
void ETH_setinc(void);
#endif
#ifdef NU_TRACE
#define NU_DEBUGF(x) { printf x; }
#else
#define NU_DEBUGF(x)
#endif
void numaker_set_mac_addr(uint8_t *addr);
int numaker_eth_init(uint8_t *mac_addr);
uint8_t *numaker_eth_get_tx_buf(void);
void numaker_eth_trigger_tx(uint16_t length, void *p);
int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf);
void numaker_eth_rx_next(void);
void numaker_eth_trigger_rx(void);
int numaker_eth_link_ok(void);
void numaker_mac_address(uint8_t *mac);
void numaker_eth_enable_interrupts(void);
void numaker_eth_disable_interrupts(void);
#endif /* _M480_ETH_ */
@@ -0,0 +1,177 @@
/***********************************************************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
* applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
* this software. By using this software, you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
*
* Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
***********************************************************************************************************************/
/***********************************************************************************************************************
* File Name : ether_callback.c
* Version : ----
* Description : This module solves all the world's problems
***********************************************************************************************************************/
/**********************************************************************************************************************
* History : DD.MM.YYYY Version Description
* : 05.01.2015 ---- Clean up source code.
***********************************************************************************************************************/
/***********************************************************************************************************************
Includes <System Includes> , "Project Includes"
***********************************************************************************************************************/
#include "r_ether_rx_if.h"
/***********************************************************************************************************************
Private global variables and functions
***********************************************************************************************************************/
int32_t callback_ether_regist(void);
void callback_ether(void * pparam);
static void callback_wakeon_lan(uint32_t channel);
static void callback_link_on(uint32_t channel);
static void callback_link_off(uint32_t channel);
volatile uint8_t pause_enable = ETHER_FLAG_OFF;
volatile uint8_t magic_packet_detect[ETHER_CHANNEL_MAX];
volatile uint8_t link_detect[ETHER_CHANNEL_MAX];
void EINT_Trig_isr(void *);
/*
* When that Link Status changes, the following function will be called:
*/
void prvLinkStatusChange( BaseType_t xStatus );
/***********************************************************************************************************************
* Function Name: callback_ether
* Description : Regist of callback function
* Arguments : -
* Return Value : 0: success, -1:failed
***********************************************************************************************************************/
int32_t callback_ether_regist(void)
{
ether_param_t param;
ether_cb_t cb_func;
int32_t ret;
/* Set the callback function (LAN cable connect/disconnect event) */
cb_func.pcb_func = &callback_ether;
param.ether_callback = cb_func;
ret = R_ETHER_Control(CONTROL_SET_CALLBACK, param);
if (ETHER_SUCCESS != ret)
{
return -1;
}
/* Set the callback function (Ether interrupt event) */
cb_func.pcb_int_hnd = &EINT_Trig_isr;
param.ether_callback = cb_func;
ret = R_ETHER_Control(CONTROL_SET_INT_HANDLER, param);
if (ETHER_SUCCESS != ret)
{
return -1;
}
return 0;
} /* End of function callback_ether_regist() */
/***********************************************************************************************************************
* Function Name: callback_ether
* Description : Sample of the callback function
* Arguments : pparam -
*
* Return Value : none
***********************************************************************************************************************/
void callback_ether(void * pparam)
{
ether_cb_arg_t * pdecode;
uint32_t channel;
pdecode = (ether_cb_arg_t *)pparam;
channel = pdecode->channel; /* Get Ethernet channel number */
switch (pdecode->event_id)
{
/* Callback function that notifies user to have detected magic packet. */
case ETHER_CB_EVENT_ID_WAKEON_LAN:
callback_wakeon_lan(channel);
break;
/* Callback function that notifies user to have become Link up. */
case ETHER_CB_EVENT_ID_LINK_ON:
callback_link_on(channel);
break;
/* Callback function that notifies user to have become Link down. */
case ETHER_CB_EVENT_ID_LINK_OFF:
callback_link_off(channel);
break;
default:
break;
}
} /* End of function callback_ether() */
/***********************************************************************************************************************
* Function Name: callback_wakeon_lan
* Description :
* Arguments : channel -
* Ethernet channel number
* Return Value : none
***********************************************************************************************************************/
static void callback_wakeon_lan(uint32_t channel)
{
if (ETHER_CHANNEL_MAX > channel)
{
magic_packet_detect[channel] = 1;
/* Please add necessary processing when magic packet is detected. */
}
} /* End of function callback_wakeon_lan() */
/***********************************************************************************************************************
* Function Name: callback_link_on
* Description :
* Arguments : channel -
* Ethernet channel number
* Return Value : none
***********************************************************************************************************************/
static void callback_link_on(uint32_t channel)
{
if (ETHER_CHANNEL_MAX > channel)
{
link_detect[channel] = ETHER_FLAG_ON_LINK_ON;
/* Please add necessary processing when becoming Link up. */
prvLinkStatusChange( 1 );
}
} /* End of function callback_link_on() */
/***********************************************************************************************************************
* Function Name: callback_link_off
* Description :
* Arguments : channel -
* Ethernet channel number
* Return Value : none
***********************************************************************************************************************/
static void callback_link_off(uint32_t channel)
{
if (ETHER_CHANNEL_MAX > channel)
{
link_detect[channel] = ETHER_FLAG_ON_LINK_OFF;
/* Please add necessary processing when becoming Link down. */
prvLinkStatusChange( 0 );
}
} /* End of function ether_cb_link_off() */
/* End of File */
@@ -4,8 +4,8 @@
*/
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* FreeRTOS+TCP V2.0.11
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -18,3 +18,43 @@ It is assumed that one of these words are defined:
STM32F439xx
The driver has been tested on both Eval and Discovery boards with both STM32F4 and STM32F7.
Recommened settings for STM32Fxx Network Interface:
// Defined in FreeRTOSIPConfig.h
#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
#define ipconfigZERO_COPY_RX_DRIVER 1
#define ipconfigZERO_COPY_TX_DRIVER 1
#define ipconfigUSE_LINKED_RX_MESSAGES 1
// Defined in stm32f4xx_hal_conf.h
#define ETH_RXBUFNB 3 or 4
#define ETH_TXBUFNB 2 or 3
#define ETH_RX_BUF_SIZE ( ipconfigNETWORK_MTU + 36 )
#define ETH_TX_BUF_SIZE ( ipconfigNETWORK_MTU + 36 )
The best size for 'ETH_RXBUFNB' and 'ETH_TXBUFNB' depends on the speed of the CPU. These macro's define the number of DMA buffers for reception and for transmission.
In general, if the CPU is very fast, you will need less buffers. You can obtain an estimate empirically.
The optimal value of 'ETH_RX_BUF_SIZE' and 'ETH_TX_BUF_SIZE' depends on the actual value of 'ipconfigNETWORK_MTU'.
When MTU is 1500, MTU+36 becomes a well-aligned buffer of 1536 bytes ( 0x600 ).
When MTU is 1200, MTU+48 will make 1248 ( 0x4E0 ), which is also well aligned.
Having well aligned buffers is important for CPU with memory cache. Often the caching system divides memory in blocks of 32 bytes. When two buffers share the same cache buffer, you are bound to see data errors.
Without memory caching, let the size be at least a multiple of 8 ( for DMA ), and make it at least "ipconfigNETWORK_MTU + 14".
The driver contains these files:
stm32fxx_hal_eth.c
stm32f2xx_hal_eth.h
stm32f4xx_hal_eth.h
stm32f7xx_hal_eth.h
stm32fxx_hal_eth.h
These files are copied from ST's HAL library. These work both for STM32F4 and STM32F7.
Please remove or rename these files from the HAL distribution that you are using.
@@ -44,6 +44,14 @@
#define __STM32F4xx_HAL_ETH_H
#define __STM32F7xx_HAL_ETH_H
#if defined(STM32F7xx)
#include "stm32f7xx_hal_def.h"
#elif defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
#include "stm32f4xx_hal_def.h"
#elif defined(STM32F2xx)
#include "stm32f2xx_hal_def.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -367,6 +375,33 @@
* @}
*/
#ifdef _lint
#ifdef __IO
#undef __IO
#endif
#define __IO
#ifdef ETH_TypeDef
#undef ETH_TypeDef
#endif
#define ETH_TypeDef void
#ifdef HAL_LockTypeDef
#undef HAL_LockTypeDef
#endif
#define HAL_LockTypeDef unsigned
#ifdef ETH_RX_BUF_SIZE
#undef ETH_RX_BUF_SIZE
#endif
#define ETH_RX_BUF_SIZE 1536
#ifdef ETH_TX_BUF_SIZE
#undef ETH_TX_BUF_SIZE
#endif
#define ETH_TX_BUF_SIZE 1536
#endif
/* Exported types ------------------------------------------------------------*/
/** @defgroup ETH_Exported_Types ETH Exported Types
* @{
@@ -1244,33 +1279,37 @@ typedef struct
/** @defgroup ETH_MAC_Debug_flags ETH MAC Debug flags
* @{
*/
#define ETH_MAC_TXFIFO_FULL ((uint32_t)0x02000000) /* Tx FIFO full */
#define ETH_MAC_TXFIFONOT_EMPTY ((uint32_t)0x01000000) /* Tx FIFO not empty */
#define ETH_MAC_TXFIFO_WRITE_ACTIVE ((uint32_t)0x00400000) /* Tx FIFO write active */
#define ETH_MAC_TXFIFO_IDLE ((uint32_t)0x00000000) /* Tx FIFO read status: Idle */
#define ETH_MAC_TXFIFO_READ ((uint32_t)0x00100000) /* Tx FIFO read status: Read (transferring data to the MAC transmitter) */
#define ETH_MAC_TXFIFO_WAITING ((uint32_t)0x00200000) /* Tx FIFO read status: Waiting for TxStatus from MAC transmitter */
#define ETH_MAC_TXFIFO_WRITING ((uint32_t)0x00300000) /* Tx FIFO read status: Writing the received TxStatus or flushing the TxFIFO */
#define ETH_MAC_TRANSMISSION_PAUSE ((uint32_t)0x00080000) /* MAC transmitter in pause */
#define ETH_MAC_TRANSMITFRAMECONTROLLER_IDLE ((uint32_t)0x00000000) /* MAC transmit frame controller: Idle */
#define ETH_MAC_TRANSMITFRAMECONTROLLER_WAITING ((uint32_t)0x00020000) /* MAC transmit frame controller: Waiting for Status of previous frame or IFG/backoff period to be over */
#define ETH_MAC_TRANSMITFRAMECONTROLLER_GENRATING_PCF ((uint32_t)0x00040000) /* MAC transmit frame controller: Generating and transmitting a Pause control frame (in full duplex mode) */
#define ETH_MAC_TRANSMITFRAMECONTROLLER_TRANSFERRING ((uint32_t)0x00060000) /* MAC transmit frame controller: Transferring input frame for transmission */
#define ETH_MAC_MII_TRANSMIT_ACTIVE ((uint32_t)0x00010000) /* MAC MII transmit engine active */
#define ETH_MAC_RXFIFO_EMPTY ((uint32_t)0x00000000) /* Rx FIFO fill level: empty */
#define ETH_MAC_RXFIFO_BELOW_THRESHOLD ((uint32_t)0x00000100) /* Rx FIFO fill level: fill-level below flow-control de-activate threshold */
#define ETH_MAC_RXFIFO_ABOVE_THRESHOLD ((uint32_t)0x00000200) /* Rx FIFO fill level: fill-level above flow-control activate threshold */
#define ETH_MAC_RXFIFO_FULL ((uint32_t)0x00000300) /* Rx FIFO fill level: full */
#define ETH_MAC_READCONTROLLER_IDLE ((uint32_t)0x00000060) /* Rx FIFO read controller IDLE state */
#define ETH_MAC_READCONTROLLER_READING_DATA ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame data */
#define ETH_MAC_READCONTROLLER_READING_STATUS ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame status (or time-stamp) */
#define ETH_MAC_READCONTROLLER_ FLUSHING ((uint32_t)0x00000060) /* Rx FIFO read controller Flushing the frame data and status */
#define ETH_MAC_RXFIFO_WRITE_ACTIVE ((uint32_t)0x00000010) /* Rx FIFO write controller active */
#define ETH_MAC_SMALL_FIFO_NOTACTIVE ((uint32_t)0x00000000) /* MAC small FIFO read / write controllers not active */
#define ETH_MAC_SMALL_FIFO_READ_ACTIVE ((uint32_t)0x00000002) /* MAC small FIFO read controller active */
#define ETH_MAC_SMALL_FIFO_WRITE_ACTIVE ((uint32_t)0x00000004) /* MAC small FIFO write controller active */
#define ETH_MAC_SMALL_FIFO_RW_ACTIVE ((uint32_t)0x00000006) /* MAC small FIFO read / write controllers active */
#define ETH_MAC_MII_RECEIVE_PROTOCOL_ACTIVE ((uint32_t)0x00000001) /* MAC MII receive protocol engine active */
#ifndef ETH_MAC_TXFIFO_FULL
#define ETH_MAC_TXFIFO_FULL ((uint32_t)0x02000000) /* Tx FIFO full */
#define ETH_MAC_TXFIFONOT_EMPTY ((uint32_t)0x01000000) /* Tx FIFO not empty */
#define ETH_MAC_TXFIFO_WRITE_ACTIVE ((uint32_t)0x00400000) /* Tx FIFO write active */
#define ETH_MAC_TXFIFO_IDLE ((uint32_t)0x00000000) /* Tx FIFO read status: Idle */
#define ETH_MAC_TXFIFO_READ ((uint32_t)0x00100000) /* Tx FIFO read status: Read (transferring data to the MAC transmitter) */
#define ETH_MAC_TXFIFO_WAITING ((uint32_t)0x00200000) /* Tx FIFO read status: Waiting for TxStatus from MAC transmitter */
#define ETH_MAC_TXFIFO_WRITING ((uint32_t)0x00300000) /* Tx FIFO read status: Writing the received TxStatus or flushing the TxFIFO */
#define ETH_MAC_TRANSMISSION_PAUSE ((uint32_t)0x00080000) /* MAC transmitter in pause */
#define ETH_MAC_TRANSMITFRAMECONTROLLER_IDLE ((uint32_t)0x00000000) /* MAC transmit frame controller: Idle */
#define ETH_MAC_TRANSMITFRAMECONTROLLER_WAITING ((uint32_t)0x00020000) /* MAC transmit frame controller: Waiting for Status of previous frame or IFG/backoff period to be over */
#define ETH_MAC_TRANSMITFRAMECONTROLLER_GENRATING_PCF ((uint32_t)0x00040000) /* MAC transmit frame controller: Generating and transmitting a Pause control frame (in full duplex mode) */
#define ETH_MAC_TRANSMITFRAMECONTROLLER_TRANSFERRING ((uint32_t)0x00060000) /* MAC transmit frame controller: Transferring input frame for transmission */
#define ETH_MAC_MII_TRANSMIT_ACTIVE ((uint32_t)0x00010000) /* MAC MII transmit engine active */
#define ETH_MAC_RXFIFO_EMPTY ((uint32_t)0x00000000) /* Rx FIFO fill level: empty */
#define ETH_MAC_RXFIFO_BELOW_THRESHOLD ((uint32_t)0x00000100) /* Rx FIFO fill level: fill-level below flow-control de-activate threshold */
#define ETH_MAC_RXFIFO_ABOVE_THRESHOLD ((uint32_t)0x00000200) /* Rx FIFO fill level: fill-level above flow-control activate threshold */
#define ETH_MAC_RXFIFO_FULL ((uint32_t)0x00000300) /* Rx FIFO fill level: full */
#define ETH_MAC_READCONTROLLER_IDLE ((uint32_t)0x00000060) /* Rx FIFO read controller IDLE state */
#define ETH_MAC_READCONTROLLER_READING_DATA ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame data */
#define ETH_MAC_READCONTROLLER_READING_STATUS ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame status (or time-stamp) */
#define ETH_MAC_READCONTROLLER_ FLUSHING ((uint32_t)0x00000060) /* Rx FIFO read controller Flushing the frame data and status */
#define ETH_MAC_RXFIFO_WRITE_ACTIVE ((uint32_t)0x00000010) /* Rx FIFO write controller active */
#define ETH_MAC_SMALL_FIFO_NOTACTIVE ((uint32_t)0x00000000) /* MAC small FIFO read / write controllers not active */
#define ETH_MAC_SMALL_FIFO_READ_ACTIVE ((uint32_t)0x00000002) /* MAC small FIFO read controller active */
#define ETH_MAC_SMALL_FIFO_WRITE_ACTIVE ((uint32_t)0x00000004) /* MAC small FIFO write controller active */
#define ETH_MAC_SMALL_FIFO_RW_ACTIVE ((uint32_t)0x00000006) /* MAC small FIFO read / write controllers active */
#define ETH_MAC_MII_RECEIVE_PROTOCOL_ACTIVE ((uint32_t)0x00000001) /* MAC MII receive protocol engine active */
#else
/* stm32_hal_legacy.h has probably been included. That file defines 'ETH_MAC_TXFIFO_FULL' and all macro's here below. */
#endif
/**
* @}
*/
@@ -77,7 +77,8 @@ return pxNetworkBufferIn;
if( ulCallCount > ulNextFaultCallCount )
{
ulNextFaultCallCount = ipconfigRAND32() % xMAX_FAULT_INJECTION_RATE;
xApplicationGetRandomNumber( &( ulNextFaultCallCount ) );
ulNextFaultCallCount = ulNextFaultCallCount % xMAX_FAULT_INJECTION_RATE;
if( ulNextFaultCallCount < xMIN_FAULT_INJECTION_RATE )
{
ulNextFaultCallCount = xMIN_FAULT_INJECTION_RATE;
@@ -85,7 +86,8 @@ return pxNetworkBufferIn;
ulCallCount = 0;
ulFault = ipconfigRAND32() % xNUM_FAULT_TYPES;
xApplicationGetRandomNumber( &( ulFault ) );
ulFault = ulFault % xNUM_FAULT_TYPES;
if( ulFaultLogIndex < xFAULT_LOG_SIZE )
{
@@ -1,27 +1,27 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/
FreeRTOS+TCP V2.0.11
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
http://aws.amazon.com/freertos
http://www.FreeRTOS.org
*/
/* Standard includes. */
#include <stdint.h>
@@ -50,12 +50,10 @@
/* Provided memory configured as uncached. */
#include "uncached_memory.h"
#ifndef niEMAC_HANDLER_TASK_PRIORITY
#define niEMAC_HANDLER_TASK_PRIORITY configMAX_PRIORITIES - 1
#ifndef BMSR_LINK_STATUS
#define BMSR_LINK_STATUS 0x0004UL
#endif
#define niBMSR_LINK_STATUS 0x0004UL
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
receiving packets. */
@@ -190,7 +188,7 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
possible priority to ensure the interrupt handler can return directly
to it. The task's handle is stored in xEMACTaskHandle so interrupts can
notify the task when there is something to process. */
xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle );
xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
}
else
{
@@ -208,27 +206,7 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
{
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
{
ProtocolPacket_t *pxPacket;
/* If the peripheral must calculate the checksum, it wants
the protocol checksum to have a value of zero. */
pxPacket = ( ProtocolPacket_t * ) ( pxBuffer->pucEthernetBuffer );
if( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ipPROTOCOL_ICMP )
{
IPHeader_t *pxIPHeader = &( pxPacket->xUDPPacket.xIPHeader );
pxPacket->xICMPPacket.xICMPHeader.usChecksum = ( uint16_t )0u;
pxIPHeader->usHeaderChecksum = 0u;
pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0UL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
usGenerateProtocolChecksum( (uint8_t*)&( pxPacket->xUDPPacket ), pxBuffer->xDataLength, pdTRUE );
}
}
#endif /* ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM */
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0 )
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
{
iptraceNETWORK_INTERFACE_TRANSMIT();
emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
@@ -271,7 +249,7 @@ BaseType_t xReturn;
}
ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0 )
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
{
xReturn = pdTRUE;
break;
@@ -303,7 +281,7 @@ BaseType_t xGetPhyLinkStatus( void )
{
BaseType_t xReturn;
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0 )
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
{
xReturn = pdFALSE;
}
@@ -320,12 +298,11 @@ static void prvEMACHandlerTask( void *pvParameters )
{
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
UBaseType_t uxLastMinBufferCount = 0;
UBaseType_t uxCurrentCount;
BaseType_t xResult = 0;
uint32_t xStatus;
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
UBaseType_t uxLastMinBufferCount = 0;
UBaseType_t uxCurrentBufferCount = 0;
/* Remove compiler warnings about unused parameters. */
( void ) pvParameters;
@@ -339,14 +316,14 @@ UBaseType_t uxCurrentBufferCount = 0;
for( ;; )
{
uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
if( uxLastMinBufferCount != uxCurrentBufferCount )
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
if( uxLastMinBufferCount != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinBufferCount = uxCurrentBufferCount;
uxLastMinBufferCount = uxCurrentCount;
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) );
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
}
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
@@ -395,22 +372,19 @@ UBaseType_t uxCurrentBufferCount = 0;
vTaskSetTimeOutState( &xPhyTime );
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
xResult = 0;
/* Indicate that the Link Status is high, so that
xNetworkInterfaceOutput() can send packets. */
ulPHYLinkStatus |= niBMSR_LINK_STATUS;
}
else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
{
xStatus = ulReadMDIO( PHY_REG_01_BMSR );
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != ( xStatus & niBMSR_LINK_STATUS ) )
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
{
ulPHYLinkStatus = xStatus;
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0 ) );
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
}
vTaskSetTimeOutState( &xPhyTime );
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0 )
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
{
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
}
@@ -35,6 +35,7 @@ extern "C" {
#include "xil_exception.h"
#include "xpseudo_asm.h"
#include "xil_cache.h"
#include "xil_printf.h"
#include "xuartps.h"
#include "xscugic.h"
#include "xemacps.h" /* defines XEmacPs API */
@@ -1,27 +1,36 @@
/*
* FreeRTOS+TCP 191100 experimental
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/
FreeRTOS+TCP V2.0.11
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
http://aws.amazon.com/freertos
http://www.FreeRTOS.org
*/
#include "Zynq/x_emacpsif.h"
#include "Zynq/x_topology.h"
#include "xstatus.h"
#include "xparameters.h"
#include "xparameters_ps.h"
#include "xil_exception.h"
#include "xil_mmu.h"
#include "FreeRTOS.h"
#include "task.h"
@@ -34,15 +43,6 @@
#include "FreeRTOS_IP_Private.h"
#include "NetworkBufferManagement.h"
#include "Zynq/x_emacpsif.h"
#include "Zynq/x_topology.h"
#include "xstatus.h"
#include "xparameters.h"
#include "xparameters_ps.h"
#include "xil_exception.h"
#include "xil_mmu.h"
#include "uncached_memory.h"
/* Two defines used to set or clear the EMAC interrupt */
@@ -56,6 +56,8 @@
#endif
#define TX_OFFSET ipconfigPACKET_FILLER_SIZE
#define RX_BUFFER_ALIGNMENT 14
/* Defined in NetworkInterface.c */
extern TaskHandle_t xEMACTaskHandle;
@@ -119,6 +121,7 @@ size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount
break;
}
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
#warning ipconfigZERO_COPY_TX_DRIVER is defined
{
void *pvBuffer = pxDMA_tx_buffers[ tail ];
NetworkBufferDescriptor_t *pxBuffer;
@@ -289,8 +292,6 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
/* Start transmit */
xemacpsif->txBusy = pdTRUE;
XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
/* Reading it back is important compiler is optimised. */
XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET );
}
dsb();
@@ -313,35 +314,33 @@ void emacps_recv_handler(void *arg)
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )
static NetworkBufferDescriptor_t *ethMsg = NULL;
static NetworkBufferDescriptor_t *ethLast = NULL;
static void passEthMessages( void )
{
IPStackEvent_t xRxEvent;
xRxEvent.eEventType = eNetworkRxEvent;
xRxEvent.pvData = ( void * ) pxDescriptor;
xRxEvent.pvData = ( void * ) ethMsg;
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
{
/* The buffer could not be sent to the stack so must be released again.
This is a deferred handler taskr, not a real interrupt, so it is ok to
use the task level function here. */
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
do
{
do
{
NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
pxDescriptor = pxNext;
} while( pxDescriptor != NULL );
}
#else
{
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
vReleaseNetworkBufferAndDescriptor( ethMsg );
ethMsg = xNext;
} while( ethMsg != NULL );
iptraceETHERNET_RX_EVENT_LOST();
FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) );
FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
}
ethMsg = ethLast = NULL;
}
int emacps_check_rx( xemacpsif_s *xemacpsif )
@@ -350,10 +349,6 @@ NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
int rx_bytes;
volatile int msgCount = 0;
int head = xemacpsif->rxHead;
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
NetworkBufferDescriptor_t *pxFirstDescriptor = NULL;
NetworkBufferDescriptor_t *pxLastDescriptor = NULL;
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
/* There seems to be an issue (SI# 692601), see comments below. */
resetrx_on_no_rxdata(xemacpsif);
@@ -369,7 +364,7 @@ int head = xemacpsif->rxHead;
break;
}
pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, ( TickType_t ) 0 );
pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
if( pxNewBuffer == NULL )
{
/* A packet has been received, but there is no replacement for this Network Buffer.
@@ -390,6 +385,7 @@ int head = xemacpsif->rxHead;
rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK;
pxBuffer->xDataLength = rx_bytes;
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
{
Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)rx_bytes );
@@ -398,35 +394,26 @@ int head = xemacpsif->rxHead;
/* store it in the receive queue, where it'll be processed by a
different handler. */
iptraceNETWORK_INTERFACE_RECEIVE();
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
pxBuffer->pxNextBuffer = NULL;
if( ethMsg == NULL )
{
pxBuffer->pxNextBuffer = NULL;
if( pxFirstDescriptor == NULL )
{
// Becomes the first message
pxFirstDescriptor = pxBuffer;
}
else if( pxLastDescriptor != NULL )
{
// Add to the tail
pxLastDescriptor->pxNextBuffer = pxBuffer;
}
pxLastDescriptor = pxBuffer;
// Becomes the first message
ethMsg = pxBuffer;
}
#else
else if( ethLast != NULL )
{
prvPassEthMessages( pxBuffer );
// Add to the tail
ethLast->pxNextBuffer = pxBuffer;
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
ethLast = pxBuffer;
msgCount++;
}
{
if( ucIsCachedMemory( pxNewBuffer->pucEthernetBuffer ) != 0 )
{
Xil_DCacheInvalidateRange( ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE );
Xil_DCacheInvalidateRange( ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
}
{
uint32_t addr = ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
@@ -435,12 +422,8 @@ int head = xemacpsif->rxHead;
addr |= XEMACPS_RXBUF_WRAP_MASK;
}
/* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
xemacpsif->rxSegments[ head ].flags = 0;
xemacpsif->rxSegments[ head ].address = addr;
if (xemacpsif->rxSegments[ head ].address)
{
// Just to read it
}
xemacpsif->rxSegments[ head ].flags = 0;
}
}
@@ -451,14 +434,10 @@ int head = xemacpsif->rxHead;
xemacpsif->rxHead = head;
}
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
if( ethMsg != NULL )
{
if( pxFirstDescriptor != NULL )
{
prvPassEthMessages( pxFirstDescriptor );
}
passEthMessages( );
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
return msgCount;
}
@@ -477,9 +456,9 @@ unsigned char *ucTxBuffer;
xemacpsif->txSegments[ index ].address = ( uint32_t )ucTxBuffer;
xemacpsif->txSegments[ index ].flags = XEMACPS_TXBUF_USED_MASK;
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
pxDMA_tx_buffers[ index ] = ( unsigned char * )NULL;
pxDMA_tx_buffers[ index ] = ( void* )NULL;
#else
pxDMA_tx_buffers[ index ] = ( unsigned char * )( ucTxBuffer + TX_OFFSET );
pxDMA_tx_buffers[ index ] = ( void* )( ucTxBuffer + TX_OFFSET );
#endif
ucTxBuffer += xemacpsif->uTxUnitSize;
}
@@ -528,7 +507,7 @@ XStatus init_dma(xemacpsif_s *xemacpsif)
pxBuffer = pxDMA_rx_buffers[ iIndex ];
if( pxBuffer == NULL )
{
pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, ( TickType_t ) 0 );
pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
if( pxBuffer == NULL )
{
FreeRTOS_printf( ("Unable to allocate a network buffer in recv_handler\n" ) );
@@ -544,7 +523,7 @@ XStatus init_dma(xemacpsif_s *xemacpsif)
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
{
Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE,
(unsigned)ipTOTAL_ETHERNET_FRAME_SIZE );
(unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
}
}

Some files were not shown because too many files have changed in this diff Show More