mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-15 16:15:08 -05:00
Sync up with Amazon-freertos repo (10th March 2020) (#34)
* Sync up with amazon-freertos * Sync up with amazon-freertos * Sync up with amazon-freertos
This commit is contained in:
parent
0acffef047
commit
ecf0f12aa1
28 changed files with 1645 additions and 7927 deletions
|
|
@ -1,27 +1,27 @@
|
|||
/*
|
||||
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
|
||||
*/
|
||||
* FreeRTOS V202002.00
|
||||
* Copyright (C) 2020 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>
|
||||
|
|
@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
|
|
@ -50,10 +51,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
/* Provided memory configured as uncached. */
|
||||
#include "uncached_memory.h"
|
||||
|
||||
#ifndef BMSR_LINK_STATUS
|
||||
#define BMSR_LINK_STATUS 0x0004UL
|
||||
#ifndef niEMAC_HANDLER_TASK_PRIORITY
|
||||
/* Define the priority of the task prvEMACHandlerTask(). */
|
||||
#define niEMAC_HANDLER_TASK_PRIORITY configMAX_PRIORITIES - 1
|
||||
#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. */
|
||||
|
|
@ -83,6 +87,13 @@ FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
|
|||
#define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
|
||||
#endif
|
||||
|
||||
#if( ipconfigZERO_COPY_RX_DRIVER == 0 || ipconfigZERO_COPY_TX_DRIVER == 0 )
|
||||
#error Please define both 'ipconfigZERO_COPY_RX_DRIVER' and 'ipconfigZERO_COPY_TX_DRIVER' as 1
|
||||
#endif
|
||||
|
||||
#if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 || ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
|
||||
#warning Please define both 'ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM' and 'ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM' as 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
|
@ -96,6 +107,10 @@ static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
|
|||
*/
|
||||
static void prvEMACHandlerTask( void *pvParameters );
|
||||
|
||||
#if ( ipconfigHAS_PRINTF != 0 )
|
||||
static void prvMonitorResources( void );
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* EMAC data/descriptions. */
|
||||
|
|
@ -119,7 +134,7 @@ XEmacPs_Config mac_config =
|
|||
extern int phy_detected;
|
||||
|
||||
/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
|
||||
static uint32_t ulPHYLinkStatus = 0;
|
||||
static uint32_t ulPHYLinkStatus = 0uL;
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
|
||||
|
|
@ -188,7 +203,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, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
|
||||
xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -206,7 +221,24 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
|
|||
|
||||
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
|
||||
{
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
|
||||
#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_UDP ) &&
|
||||
( pxPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_TCP ) )
|
||||
{
|
||||
/* The EMAC will calculate the checksum of the IP-header.
|
||||
It can only calculate protocol checksums of UDP and TCP,
|
||||
so for ICMP and other protocols it must be done manually. */
|
||||
usGenerateProtocolChecksum( (uint8_t*)&( pxPacket->xUDPPacket ), pxBuffer->xDataLength, pdTRUE );
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM */
|
||||
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )
|
||||
{
|
||||
iptraceNETWORK_INTERFACE_TRANSMIT();
|
||||
emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
|
||||
|
|
@ -249,7 +281,7 @@ BaseType_t xReturn;
|
|||
}
|
||||
ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
|
||||
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
|
||||
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
break;
|
||||
|
|
@ -281,7 +313,7 @@ BaseType_t xGetPhyLinkStatus( void )
|
|||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
|
||||
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0uL )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
|
@ -294,12 +326,58 @@ BaseType_t xReturn;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ipconfigHAS_PRINTF != 0 )
|
||||
static void prvMonitorResources()
|
||||
{
|
||||
static UBaseType_t uxLastMinBufferCount = 0u;
|
||||
static size_t uxMinLastSize = 0uL;
|
||||
UBaseType_t uxCurrentBufferCount;
|
||||
size_t uxMinSize;
|
||||
|
||||
uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
|
||||
|
||||
if( uxLastMinBufferCount != uxCurrentBufferCount )
|
||||
{
|
||||
/* The logging produced below may be helpful
|
||||
* while tuning +TCP: see how many buffers are in use. */
|
||||
uxLastMinBufferCount = uxCurrentBufferCount;
|
||||
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
|
||||
uxGetNumberOfFreeNetworkBuffers(),
|
||||
uxCurrentBufferCount ) );
|
||||
}
|
||||
|
||||
uxMinSize = xPortGetMinimumEverFreeHeapSize();
|
||||
|
||||
if( uxMinLastSize != uxMinSize )
|
||||
{
|
||||
uxMinLastSize = uxMinSize;
|
||||
FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", xPortGetFreeHeapSize(), uxMinSize ) );
|
||||
}
|
||||
|
||||
#if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
|
||||
{
|
||||
static UBaseType_t uxLastMinQueueSpace = 0;
|
||||
UBaseType_t uxCurrentCount = 0u;
|
||||
|
||||
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 */
|
||||
}
|
||||
#endif /* ( ipconfigHAS_PRINTF != 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
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 );
|
||||
|
|
@ -316,30 +394,11 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
|
|||
|
||||
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 ) );
|
||||
}
|
||||
|
||||
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
|
||||
{
|
||||
static UBaseType_t uxLastMinQueueSpace = 0;
|
||||
|
||||
uxCurrentCount = uxGetMinimumIPQueueSpace();
|
||||
if( uxLastMinQueueSpace != uxCurrentCount )
|
||||
#if ( ipconfigHAS_PRINTF != 0 )
|
||||
{
|
||||
/* 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 ) );
|
||||
prvMonitorResources();
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigCHECK_IP_QUEUE_SPACE */
|
||||
#endif /* ipconfigHAS_PRINTF != 0 ) */
|
||||
|
||||
if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )
|
||||
{
|
||||
|
|
@ -372,19 +431,26 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
|
|||
vTaskSetTimeOutState( &xPhyTime );
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
|
||||
xResult = 0;
|
||||
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0uL )
|
||||
{
|
||||
/* Indicate that the Link Status is high, so that
|
||||
xNetworkInterfaceOutput() can send packets. */
|
||||
ulPHYLinkStatus |= niBMSR_LINK_STATUS;
|
||||
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume 1\n" ) );
|
||||
}
|
||||
}
|
||||
else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
|
||||
{
|
||||
xStatus = ulReadMDIO( PHY_REG_01_BMSR );
|
||||
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
|
||||
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != ( xStatus & niBMSR_LINK_STATUS ) )
|
||||
{
|
||||
ulPHYLinkStatus = xStatus;
|
||||
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
|
||||
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL ) );
|
||||
}
|
||||
|
||||
vTaskSetTimeOutState( &xPhyTime );
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
|
||||
if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )
|
||||
{
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ NetworkInterface for Xilinx' Zynq
|
|||
Please include the following source files:
|
||||
|
||||
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/NetworkInterface.c
|
||||
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/uncached_memory.c
|
||||
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
|
||||
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
|
||||
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
|
||||
|
|
@ -23,3 +24,14 @@ The following source files are NOT used for the FreeRTOS+TCP interface:
|
|||
$(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_bdring.c
|
||||
$(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_hw.c
|
||||
$(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_sinit.c
|
||||
|
||||
It is recommended to have these defined :
|
||||
|
||||
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
|
||||
#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1
|
||||
#define ipconfigUSE_LINKED_RX_MESSAGES 1
|
||||
|
||||
It is obligatory to define:
|
||||
|
||||
#define ipconfigZERO_COPY_RX_DRIVER 1
|
||||
#define ipconfigZERO_COPY_TX_DRIVER 1
|
||||
|
|
|
|||
|
|
@ -1,10 +1,35 @@
|
|||
/*
|
||||
* FreeRTOS V202002.00
|
||||
* Copyright (C) 2020 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* uncached_memory.c
|
||||
*
|
||||
* This module will declare 1 MB of memory and switch off the caching for it.
|
||||
*
|
||||
* pucGetUncachedMemory( ulSize ) returns a trunc of this memory with a length
|
||||
* rounded up to a multiple of 4 KB
|
||||
* rounded up to a multiple of 4 KB.
|
||||
*
|
||||
* ucIsCachedMemory( pucBuffer ) returns non-zero if a given pointer is NOT
|
||||
* within the range of the 1 MB non-cached memory.
|
||||
|
|
@ -43,23 +68,35 @@
|
|||
|
||||
#include "uncached_memory.h"
|
||||
|
||||
#define UNCACHED_MEMORY_SIZE 0x100000ul
|
||||
/* Reserve 1 MB of memory. */
|
||||
#define uncMEMORY_SIZE 0x100000uL
|
||||
|
||||
/* Make sure that each pointer has an alignment of 4 KB. */
|
||||
#define uncALIGNMENT_SIZE 0x1000uL
|
||||
|
||||
#define DDR_MEMORY_END (XPAR_PS7_DDR_0_S_AXI_HIGHADDR+1)
|
||||
|
||||
#define uncMEMORY_ATTRIBUTE 0x1C02
|
||||
|
||||
static void vInitialiseUncachedMemory( void );
|
||||
|
||||
static uint8_t *pucHeadOfMemory;
|
||||
static uint32_t ulMemorySize;
|
||||
static uint8_t *pucStartOfMemory = NULL;
|
||||
|
||||
/* The linker file defines some pseudo variables. '_end' is one of them.
|
||||
It is located at the first free byte in RAM. */
|
||||
extern u8 _end;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint8_t ucIsCachedMemory( const uint8_t *pucBuffer )
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
|
||||
if( ( pucStartOfMemory != NULL ) &&
|
||||
( pucBuffer >= pucStartOfMemory ) &&
|
||||
( pucBuffer < ( pucStartOfMemory + UNCACHED_MEMORY_SIZE ) ) )
|
||||
( pucBuffer < ( pucStartOfMemory + uncMEMORY_SIZE ) ) )
|
||||
{
|
||||
ucReturn = pdFALSE;
|
||||
}
|
||||
|
|
@ -70,10 +107,12 @@ uint8_t ucReturn;
|
|||
|
||||
return ucReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint8_t *pucGetUncachedMemory( uint32_t ulSize )
|
||||
{
|
||||
uint8_t *pucReturn;
|
||||
uint32_t ulSkipSize;
|
||||
|
||||
if( pucStartOfMemory == NULL )
|
||||
{
|
||||
|
|
@ -85,48 +124,40 @@ uint8_t *pucReturn;
|
|||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulSkipSize;
|
||||
|
||||
pucReturn = pucHeadOfMemory;
|
||||
ulSkipSize = ( ulSize + 0x1000ul ) & ~0xffful;
|
||||
/* Make sure that the next pointer return will have a good alignment. */
|
||||
ulSkipSize = ( ulSize + uncALIGNMENT_SIZE ) & ~( uncALIGNMENT_SIZE - 1uL );
|
||||
pucHeadOfMemory += ulSkipSize;
|
||||
ulMemorySize -= ulSkipSize;
|
||||
}
|
||||
|
||||
return pucReturn;
|
||||
}
|
||||
|
||||
extern u8 _end;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vInitialiseUncachedMemory( )
|
||||
{
|
||||
/* At the end of program's space... */
|
||||
pucStartOfMemory = (uint8_t *) &_end;
|
||||
/*
|
||||
* Align the start address to 1 MB boundary.
|
||||
*/
|
||||
pucStartOfMemory = (uint8_t *)( ( ( uint32_t )pucStartOfMemory + UNCACHED_MEMORY_SIZE ) & ( ~( UNCACHED_MEMORY_SIZE - 1 ) ) );
|
||||
pucStartOfMemory = ( uint8_t * ) &( _end );
|
||||
|
||||
if( ( ( u32 )pucStartOfMemory ) + UNCACHED_MEMORY_SIZE > DDR_MEMORY_END )
|
||||
/* Align the start address to 1 MB boundary. */
|
||||
pucStartOfMemory = ( uint8_t * )( ( ( uint32_t )pucStartOfMemory + uncMEMORY_SIZE ) & ( ~( uncMEMORY_SIZE - 1 ) ) );
|
||||
|
||||
if( ( ( u32 )pucStartOfMemory ) + uncMEMORY_SIZE > DDR_MEMORY_END )
|
||||
{
|
||||
// vLoggingPrintf("vInitialiseUncachedMemory: Can not allocate uncached memory\n" );
|
||||
FreeRTOS_printf( ( "vInitialiseUncachedMemory: Can not allocate uncached memory\n" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Some objects want to be stored in uncached memory. Hence the 1 MB
|
||||
* address range that starts after "_end" is made uncached
|
||||
* by setting appropriate attributes in the translation table.
|
||||
*/
|
||||
/* FIXME claudio rossi. Modified to prevent data abort exception (misaligned access)
|
||||
* when application is compiled with -O1 or more optimization flag.
|
||||
*/
|
||||
/* Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0xc02 ); // addr, attr */
|
||||
Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0x1c02 ); // addr, attr
|
||||
/* Some objects want to be stored in uncached memory. Hence the 1 MB
|
||||
address range that starts after "_end" is made uncached by setting
|
||||
appropriate attributes in the translation table. */
|
||||
Xil_SetTlbAttributes( ( uint32_t ) pucStartOfMemory, uncMEMORY_ATTRIBUTE );
|
||||
|
||||
/* For experiments in the SDIO driver, make the remaining uncached memory public */
|
||||
/* For experiments in the SDIO driver, make the remaining uncached memory
|
||||
public */
|
||||
pucHeadOfMemory = pucStartOfMemory;
|
||||
ulMemorySize = UNCACHED_MEMORY_SIZE;
|
||||
memset( pucStartOfMemory, '\0', UNCACHED_MEMORY_SIZE );
|
||||
ulMemorySize = uncMEMORY_SIZE;
|
||||
memset( pucStartOfMemory, '\0', uncMEMORY_SIZE );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "sleep.h"
|
||||
#include "xparameters.h"
|
||||
#include "xparameters_ps.h" /* defines XPAR values */
|
||||
#include "xil_types.h"
|
||||
|
|
@ -35,7 +34,6 @@ 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,36 +1,27 @@
|
|||
/*
|
||||
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"
|
||||
* FreeRTOS V202002.00
|
||||
* Copyright (C) 2020 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 "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
|
@ -43,6 +34,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#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,7 +56,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#endif
|
||||
#define TX_OFFSET ipconfigPACKET_FILLER_SIZE
|
||||
|
||||
#define RX_BUFFER_ALIGNMENT 14
|
||||
#define dmaRX_TX_BUFFER_SIZE 1536
|
||||
|
||||
/* Defined in NetworkInterface.c */
|
||||
extern TaskHandle_t xEMACTaskHandle;
|
||||
|
|
@ -120,8 +120,6 @@ 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;
|
||||
|
|
@ -140,7 +138,6 @@ size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Clear all but the "used" and "wrap" bits. */
|
||||
if( tail < ipconfigNIC_N_TX_DESC - 1 )
|
||||
{
|
||||
|
|
@ -170,6 +167,11 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|||
|
||||
xemacpsif = (xemacpsif_s *)(arg);
|
||||
|
||||
/* This function is called from an ISR. The Xilinx ISR-handler has already
|
||||
cleared the TXCOMPL and TXSR_USEDREAD status bits in the XEMACPS_TXSR register.
|
||||
But it forgets to do a read-back. Do so now to avoid ever-returning ISR's. */
|
||||
( void ) XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_TXSR_OFFSET);
|
||||
|
||||
/* In this port for FreeRTOS+TCP, the EMAC interrupts will only set a bit in
|
||||
"isr_events". The task in NetworkInterface will wake-up and do the necessary work.
|
||||
*/
|
||||
|
|
@ -188,7 +190,7 @@ static BaseType_t xValidLength( BaseType_t xLength )
|
|||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
if( ( xLength >= ( BaseType_t ) sizeof( struct xARP_PACKET ) ) && ( ( ( uint32_t ) xLength ) <= ipTOTAL_ETHERNET_FRAME_SIZE ) )
|
||||
if( ( xLength >= ( BaseType_t ) sizeof( struct xARP_PACKET ) ) && ( ( ( uint32_t ) xLength ) <= dmaRX_TX_BUFFER_SIZE ) )
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
|
@ -207,12 +209,8 @@ int iHasSent = 0;
|
|||
uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
|
||||
TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
|
||||
|
||||
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
|
||||
{
|
||||
/* This driver wants to own all network buffers which are to be transmitted. */
|
||||
configASSERT( iReleaseAfterSend != pdFALSE );
|
||||
}
|
||||
#endif
|
||||
/* This driver wants to own all network buffers which are to be transmitted. */
|
||||
configASSERT( iReleaseAfterSend != pdFALSE );
|
||||
|
||||
/* Open a do {} while ( 0 ) loop to be able to call break. */
|
||||
do
|
||||
|
|
@ -235,7 +233,6 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
|
|||
break;
|
||||
}
|
||||
|
||||
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
|
||||
/* Pass the pointer (and its ownership) directly to DMA. */
|
||||
pxDMA_tx_buffers[ head ] = pxBuffer->pucEthernetBuffer;
|
||||
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
|
||||
|
|
@ -244,15 +241,7 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
|
|||
}
|
||||
/* Buffer has been transferred, do not release it. */
|
||||
iReleaseAfterSend = pdFALSE;
|
||||
#else
|
||||
if( pxDMA_tx_buffers[ head ] == NULL )
|
||||
{
|
||||
FreeRTOS_printf( ( "emacps_send_message: pxDMA_tx_buffers[ %d ] == NULL\n", head ) );
|
||||
break;
|
||||
}
|
||||
/* Copy the message to unbuffered space in RAM. */
|
||||
memcpy( pxDMA_tx_buffers[ head ], pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
|
||||
#endif
|
||||
|
||||
/* Packets will be sent one-by-one, so for each packet
|
||||
the TXBUF_LAST bit will be set. */
|
||||
ulFlags |= XEMACPS_TXBUF_LAST_MASK;
|
||||
|
|
@ -292,6 +281,8 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
|
|||
/* Start transmit */
|
||||
xemacpsif->txBusy = pdTRUE;
|
||||
XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
|
||||
/* Read back the register to make sure the data is flushed. */
|
||||
( void ) XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET );
|
||||
}
|
||||
dsb();
|
||||
|
||||
|
|
@ -306,6 +297,11 @@ void emacps_recv_handler(void *arg)
|
|||
xemacpsif = (xemacpsif_s *)(arg);
|
||||
xemacpsif->isr_events |= EMAC_IF_RX_EVENT;
|
||||
|
||||
/* The driver has already cleared the FRAMERX, BUFFNA and error bits
|
||||
in the XEMACPS_RXSR register,
|
||||
But it forgets to do a read-back. Do so now. */
|
||||
( void ) XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET);
|
||||
|
||||
if( xEMACTaskHandle != NULL )
|
||||
{
|
||||
vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
|
||||
|
|
@ -314,33 +310,35 @@ void emacps_recv_handler(void *arg)
|
|||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
static NetworkBufferDescriptor_t *ethMsg = NULL;
|
||||
static NetworkBufferDescriptor_t *ethLast = NULL;
|
||||
|
||||
static void passEthMessages( void )
|
||||
static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )
|
||||
{
|
||||
IPStackEvent_t xRxEvent;
|
||||
|
||||
xRxEvent.eEventType = eNetworkRxEvent;
|
||||
xRxEvent.pvData = ( void * ) ethMsg;
|
||||
xRxEvent.pvData = ( void * ) pxDescriptor;
|
||||
|
||||
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. */
|
||||
do
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
{
|
||||
NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
|
||||
vReleaseNetworkBufferAndDescriptor( ethMsg );
|
||||
ethMsg = xNext;
|
||||
} while( ethMsg != NULL );
|
||||
|
||||
do
|
||||
{
|
||||
NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;
|
||||
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
|
||||
pxDescriptor = pxNext;
|
||||
} while( pxDescriptor != NULL );
|
||||
}
|
||||
#else
|
||||
{
|
||||
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
|
||||
}
|
||||
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
|
||||
iptraceETHERNET_RX_EVENT_LOST();
|
||||
FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
|
||||
FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) );
|
||||
}
|
||||
|
||||
ethMsg = ethLast = NULL;
|
||||
}
|
||||
|
||||
int emacps_check_rx( xemacpsif_s *xemacpsif )
|
||||
|
|
@ -349,6 +347,10 @@ 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);
|
||||
|
|
@ -364,12 +366,12 @@ int head = xemacpsif->rxHead;
|
|||
break;
|
||||
}
|
||||
|
||||
pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
|
||||
pxNewBuffer = pxGetNetworkBufferWithDescriptor( dmaRX_TX_BUFFER_SIZE, ( TickType_t ) 0 );
|
||||
if( pxNewBuffer == NULL )
|
||||
{
|
||||
/* A packet has been received, but there is no replacement for this Network Buffer.
|
||||
The packet will be dropped, and it Network Buffer will stay in place. */
|
||||
FreeRTOS_printf( ("emacps_check_rx: unable to allocate a Netwrok Buffer\n" ) );
|
||||
FreeRTOS_printf( ("emacps_check_rx: unable to allocate a Network Buffer\n" ) );
|
||||
pxNewBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
|
||||
}
|
||||
else
|
||||
|
|
@ -394,26 +396,35 @@ int head = xemacpsif->rxHead;
|
|||
/* store it in the receive queue, where it'll be processed by a
|
||||
different handler. */
|
||||
iptraceNETWORK_INTERFACE_RECEIVE();
|
||||
pxBuffer->pxNextBuffer = NULL;
|
||||
|
||||
if( ethMsg == NULL )
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
{
|
||||
// Becomes the first message
|
||||
ethMsg = pxBuffer;
|
||||
}
|
||||
else if( ethLast != NULL )
|
||||
{
|
||||
// Add to the tail
|
||||
ethLast->pxNextBuffer = pxBuffer;
|
||||
}
|
||||
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;
|
||||
}
|
||||
#else
|
||||
{
|
||||
prvPassEthMessages( 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 + RX_BUFFER_ALIGNMENT);
|
||||
Xil_DCacheInvalidateRange( ( ( uint32_t ) pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, ( uint32_t ) dmaRX_TX_BUFFER_SIZE );
|
||||
}
|
||||
{
|
||||
uint32_t addr = ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
|
||||
|
|
@ -422,8 +433,10 @@ int head = xemacpsif->rxHead;
|
|||
addr |= XEMACPS_RXBUF_WRAP_MASK;
|
||||
}
|
||||
/* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
|
||||
xemacpsif->rxSegments[ head ].address = addr;
|
||||
xemacpsif->rxSegments[ head ].flags = 0;
|
||||
xemacpsif->rxSegments[ head ].address = addr;
|
||||
/* Make sure that the value has reached the peripheral by reading it back. */
|
||||
( void ) xemacpsif->rxSegments[ head ].address;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -434,10 +447,14 @@ int head = xemacpsif->rxHead;
|
|||
xemacpsif->rxHead = head;
|
||||
}
|
||||
|
||||
if( ethMsg != NULL )
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
{
|
||||
passEthMessages( );
|
||||
if( pxFirstDescriptor != NULL )
|
||||
{
|
||||
prvPassEthMessages( pxFirstDescriptor );
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
|
||||
|
||||
return msgCount;
|
||||
}
|
||||
|
|
@ -455,11 +472,7 @@ 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 ] = ( void* )NULL;
|
||||
#else
|
||||
pxDMA_tx_buffers[ index ] = ( void* )( ucTxBuffer + TX_OFFSET );
|
||||
#endif
|
||||
pxDMA_tx_buffers[ index ] = ( unsigned char * )NULL;
|
||||
ucTxBuffer += xemacpsif->uTxUnitSize;
|
||||
}
|
||||
xemacpsif->txSegments[ ipconfigNIC_N_TX_DESC - 1 ].flags =
|
||||
|
|
@ -479,8 +492,7 @@ XStatus init_dma(xemacpsif_s *xemacpsif)
|
|||
|
||||
xTxSize = ipconfigNIC_N_TX_DESC * sizeof( xemacpsif->txSegments[ 0 ] );
|
||||
|
||||
/* Also round-up to 4KB */
|
||||
xemacpsif->uTxUnitSize = ( ipTOTAL_ETHERNET_FRAME_SIZE + 0x1000ul ) & ~0xffful;
|
||||
xemacpsif->uTxUnitSize = dmaRX_TX_BUFFER_SIZE;
|
||||
/*
|
||||
* We allocate 65536 bytes for RX BDs which can accommodate a
|
||||
* maximum of 8192 BDs which is much more than any application
|
||||
|
|
@ -507,7 +519,7 @@ XStatus init_dma(xemacpsif_s *xemacpsif)
|
|||
pxBuffer = pxDMA_rx_buffers[ iIndex ];
|
||||
if( pxBuffer == NULL )
|
||||
{
|
||||
pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
|
||||
pxBuffer = pxGetNetworkBufferWithDescriptor( dmaRX_TX_BUFFER_SIZE, ( TickType_t ) 0 );
|
||||
if( pxBuffer == NULL )
|
||||
{
|
||||
FreeRTOS_printf( ("Unable to allocate a network buffer in recv_handler\n" ) );
|
||||
|
|
@ -523,7 +535,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 + RX_BUFFER_ALIGNMENT);
|
||||
(unsigned)dmaRX_TX_BUFFER_SIZE );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,19 +22,19 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
|
||||
///* FreeRTOS+TCP includes. */
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
|
||||
extern TaskHandle_t xEMACTaskHandle;
|
||||
|
||||
|
|
@ -42,8 +42,6 @@ extern TaskHandle_t xEMACTaskHandle;
|
|||
*** to run it on a PEEP board
|
||||
***/
|
||||
|
||||
unsigned int link_speed = 100;
|
||||
|
||||
void setup_isr( xemacpsif_s *xemacpsif )
|
||||
{
|
||||
/*
|
||||
|
|
@ -141,8 +139,6 @@ int xResult;
|
|||
return xResult;
|
||||
}
|
||||
|
||||
BaseType_t xNetworkInterfaceInitialise( void );
|
||||
|
||||
static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
|
||||
{
|
||||
xemacpsif_s *xemacpsif;
|
||||
|
|
@ -218,8 +214,6 @@ static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
|
|||
}
|
||||
}
|
||||
|
||||
extern XEmacPs_Config mac_config;
|
||||
|
||||
void HandleTxErrors(xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32 netctrlreg;
|
||||
|
|
|
|||
|
|
@ -53,24 +53,23 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
//#include "lwipopts.h"
|
||||
#include "xparameters_ps.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
///* FreeRTOS+TCP includes. */
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
#include "xparameters_ps.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
|
||||
int phy_detected = 0;
|
||||
|
||||
/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
|
||||
|
|
@ -99,6 +98,8 @@ int phy_detected = 0;
|
|||
|
||||
#define IEEE_CONTROL_REG_OFFSET 0
|
||||
#define IEEE_STATUS_REG_OFFSET 1
|
||||
#define IEEE_PHYSID1_OFFSET 2
|
||||
#define IEEE_PHYSID2_OFFSET 3
|
||||
#define IEEE_AUTONEGO_ADVERTISE_REG 4
|
||||
#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
|
||||
#define IEEE_1000_ADVERTISE_REG_OFFSET 9
|
||||
|
|
@ -135,9 +136,6 @@ int phy_detected = 0;
|
|||
#define IEEE_PAUSE_MASK 0x0400
|
||||
#define IEEE_AUTONEG_ERROR_MASK 0x8000
|
||||
|
||||
#define PHY_DETECT_REG 1
|
||||
#define PHY_DETECT_MASK 0x1808
|
||||
|
||||
#define XEMACPS_GMII2RGMII_SPEED1000_FD 0x140
|
||||
#define XEMACPS_GMII2RGMII_SPEED100_FD 0x2100
|
||||
#define XEMACPS_GMII2RGMII_SPEED10_FD 0x100
|
||||
|
|
@ -161,21 +159,24 @@ int phy_detected = 0;
|
|||
#define EMAC0_BASE_ADDRESS 0xE000B000
|
||||
#define EMAC1_BASE_ADDRESS 0xE000C000
|
||||
|
||||
#define PHY_ADDRESS_COUNT 32
|
||||
|
||||
#define MINIMUM_SLEEP_TIME 2
|
||||
|
||||
|
||||
static int detect_phy(XEmacPs *xemacpsp)
|
||||
{
|
||||
u16 phy_reg;
|
||||
u32 phy_addr;
|
||||
u16 id_lower, id_upper;
|
||||
u32 phy_addr, id;
|
||||
|
||||
for (phy_addr = 31; phy_addr > 0; phy_addr--) {
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,
|
||||
&phy_reg);
|
||||
for (phy_addr = 0; phy_addr < PHY_ADDRESS_COUNT; phy_addr++) {
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PHYSID1_OFFSET, &id_lower);
|
||||
|
||||
if ((phy_reg != 0xFFFF) &&
|
||||
((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
|
||||
/* Found a valid PHY address */
|
||||
FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected at address %d.\r\n",
|
||||
phy_addr));
|
||||
FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected.\n" ) );
|
||||
if ((id_lower != ( u16 )0xFFFFu) && (id_lower != ( u16 )0x0u)) {
|
||||
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PHYSID2_OFFSET, &id_upper);
|
||||
id = ( ( ( uint32_t ) id_upper ) << 16 ) | ( id_lower & 0xFFF0 );
|
||||
FreeRTOS_printf( ("XEmacPs detect_phy: %04lX at address %d.\n", id, phy_addr ) );
|
||||
phy_detected = phy_addr;
|
||||
return phy_addr;
|
||||
}
|
||||
|
|
@ -238,8 +239,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
|
||||
return 10;
|
||||
|
||||
xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
|
||||
__FUNCTION__);
|
||||
FreeRTOS_printf( ( "%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\n",
|
||||
__FUNCTION__ ) );
|
||||
return 10;
|
||||
|
||||
} else {
|
||||
|
|
@ -257,8 +258,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
case (IEEE_CTRL_LINKSPEED_10M):
|
||||
return 10;
|
||||
default:
|
||||
xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
|
||||
__FUNCTION__, phylinkspeed);
|
||||
FreeRTOS_printf( ( "%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\n",
|
||||
__FUNCTION__, phylinkspeed ) );
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
|
@ -282,7 +283,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
#else
|
||||
u32 phy_addr = detect_phy(xemacpsp);
|
||||
#endif
|
||||
xil_printf("Start PHY autonegotiation \r\n");
|
||||
FreeRTOS_printf( ( "Start PHY autonegotiation \n" ) );
|
||||
|
||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||
#else
|
||||
|
|
@ -338,24 +339,24 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
break;
|
||||
}
|
||||
#endif
|
||||
xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
|
||||
FreeRTOS_printf( ( "Waiting for PHY to complete autonegotiation.\n" ) );
|
||||
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
|
||||
sleep(1);
|
||||
vTaskDelay( MINIMUM_SLEEP_TIME );
|
||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||
#else
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
|
||||
&temp);
|
||||
if (temp & IEEE_AUTONEG_ERROR_MASK) {
|
||||
xil_printf("Auto negotiation error \r\n");
|
||||
FreeRTOS_printf( ( "Auto negotiation error \n" ) );
|
||||
}
|
||||
#endif
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
|
||||
&status);
|
||||
}
|
||||
|
||||
xil_printf("autonegotiation complete \r\n");
|
||||
FreeRTOS_printf( ( "autonegotiation complete \n" ) );
|
||||
|
||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||
#else
|
||||
|
|
@ -363,7 +364,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
#endif
|
||||
|
||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||
xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");
|
||||
FreeRTOS_printf( ( "Waiting for Link to be up; Polling for SGMII core Reg \n" ) );
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
|
||||
while(!(temp & 0x8000)) {
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
|
||||
|
|
@ -380,7 +381,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
|
||||
return 10;
|
||||
} else {
|
||||
xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\r\n");
|
||||
FreeRTOS_printf( ( "get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\n" ) );
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
|
||||
XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
|
||||
return 10;
|
||||
|
|
@ -560,26 +561,26 @@ unsigned Phy_Setup (XEmacPs *xemacpsp)
|
|||
link_speed = 1000;
|
||||
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
||||
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
|
||||
sleep(1);
|
||||
vTaskDelay( MINIMUM_SLEEP_TIME );
|
||||
#elif defined(ipconfigNIC_LINKSPEED100)
|
||||
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
|
||||
link_speed = 100;
|
||||
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
||||
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
|
||||
sleep(1);
|
||||
vTaskDelay( MINIMUM_SLEEP_TIME );
|
||||
#elif defined(ipconfigNIC_LINKSPEED10)
|
||||
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
|
||||
link_speed = 10;
|
||||
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
||||
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
|
||||
sleep(1);
|
||||
vTaskDelay( MINIMUM_SLEEP_TIME );
|
||||
#endif
|
||||
if (conv_present) {
|
||||
XEmacPs_PhyWrite(xemacpsp, convphyaddr,
|
||||
XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
|
||||
}
|
||||
|
||||
xil_printf("link speed: %d\r\n", link_speed);
|
||||
FreeRTOS_printf( ( "link speed: %d\n", link_speed ) );
|
||||
return link_speed;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue