Move the Zynq's lwIP example from the Full demo into its own configuration as having the lwIP tasks at a high priority made the self checking test tasks report failures, while having the lwIP tasks at a low priority slugged the throughput.

pull/4/head
Richard Barry 11 years ago
parent be8b0ed21d
commit e92795bcc8

@ -132,12 +132,6 @@ the queue empty. */
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
/*
* Called by main() to create the simply blinky style application if
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
*/
void main_blinky( void );
/*-----------------------------------------------------------*/
/* The queue used by both tasks. */

@ -207,7 +207,8 @@ Zynq MPU. */
/****** Network configuration settings. ***************************************/
#define configLWIP_TASK_PRIORITY ( 5 )
#define configMAC_INPUT_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configLWIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
/* MAC address configuration. */
#define configMAC_ADDR0 0x00

@ -165,7 +165,7 @@ static struct netif xNetIf;
use of the lwIP raw API. */
httpd_init();
sys_thread_new( "lwIP Input", xemacif_input_thread, &xNetIf, configMINIMAL_STACK_SIZE * 6, tskIDLE_PRIORITY );
sys_thread_new( "lwIP Input", xemacif_input_thread, &xNetIf, configMINIMAL_STACK_SIZE, configMAC_INPUT_TASK_PRIORITY );
/* Create the FreeRTOS defined basic command server. This demonstrates use
of the lwIP sockets API. */

@ -56,7 +56,7 @@ static int EmacIntrNum;
extern u8 _end;
#ifdef OS_IS_FREERTOS
long xInsideISR = 0;
extern BaseType_t xInsideISR;
#endif
#define XEMACPS_BD_TO_INDEX(ringptr, bdptr) \

@ -48,6 +48,11 @@
#include "lwip/mem.h"
#include "lwip/stats.h"
/* Very crude mechanism used to determine if the critical section handling
functions are being called from an interrupt context or not. This relies on
the interrupt handler setting this variable manually. */
BaseType_t xInsideISR = pdFALSE;
/*---------------------------------------------------------------------------*
* Routine: sys_mbox_new
*---------------------------------------------------------------------------*
@ -137,8 +142,19 @@ void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost )
err_t sys_mbox_trypost( sys_mbox_t *pxMailBox, void *pxMessageToPost )
{
err_t xReturn;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if( xQueueSend( *pxMailBox, &pxMessageToPost, 0UL ) == pdPASS )
if( xInsideISR != pdFALSE )
{
xReturn = xQueueSendFromISR( *pxMailBox, &pxMessageToPost, &xHigherPriorityTaskWoken );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
else
{
xReturn = xQueueSend( *pxMailBox, &pxMessageToPost, ( TickType_t ) 0 );
}
if( xReturn == pdPASS )
{
xReturn = ERR_OK;
}
@ -192,6 +208,8 @@ unsigned long ulReturn;
if( ulTimeOut != 0UL )
{
configASSERT( xInsideISR == ( portBASE_TYPE ) 0 );
if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), ulTimeOut/ portTICK_PERIOD_MS ) )
{
xEndTime = xTaskGetTickCount();
@ -241,13 +259,25 @@ u32_t sys_arch_mbox_tryfetch( sys_mbox_t *pxMailBox, void **ppvBuffer )
{
void *pvDummy;
unsigned long ulReturn;
long lResult;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if( ppvBuffer== NULL )
{
ppvBuffer = &pvDummy;
}
if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), 0UL ) )
if( xInsideISR != pdFALSE )
{
lResult = xQueueReceiveFromISR( *pxMailBox, &( *ppvBuffer ), &xHigherPriorityTaskWoken );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
else
{
lResult = xQueueReceive( *pxMailBox, &( *ppvBuffer ), 0UL );
}
if( lResult == pdPASS )
{
ulReturn = ERR_OK;
}
@ -276,10 +306,16 @@ err_t sys_sem_new( sys_sem_t *pxSemaphore, u8_t ucCount )
{
err_t xReturn = ERR_MEM;
//vSemaphoreCreateBinary( ( *pxSemaphore ) );
*pxSemaphore = xSemaphoreCreateCounting( 0xffff, ( unsigned long ) ucCount );
if( *pxSemaphore != NULL )
{
if( ucCount == 0U )
{
// xSemaphoreTake( *pxSemaphore, 1UL );
}
xReturn = ERR_OK;
SYS_STATS_INC_USED( sem );
}
@ -377,7 +413,20 @@ err_t xReturn = ERR_MEM;
* @param mutex the mutex to lock */
void sys_mutex_lock( sys_mutex_t *pxMutex )
{
while( xSemaphoreTake( *pxMutex, portMAX_DELAY ) != pdPASS );
BaseType_t xGotSemaphore;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if( xInsideISR == 0 )
{
while( xSemaphoreTake( *pxMutex, portMAX_DELAY ) != pdPASS );
}
else
{
#warning What happens if the mutex cannot be taken from an ISR in the code below
xGotSemaphore = xSemaphoreTakeFromISR( *pxMutex, &xHigherPriorityTaskWoken );
configASSERT( xGotSemaphore );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
}
/** Unlock a mutex
@ -407,7 +456,17 @@ void sys_mutex_free( sys_mutex_t *pxMutex )
*---------------------------------------------------------------------------*/
void sys_sem_signal( sys_sem_t *pxSemaphore )
{
xSemaphoreGive( *pxSemaphore );
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if( xInsideISR != pdFALSE )
{
xSemaphoreGiveFromISR( *pxSemaphore, &xHigherPriorityTaskWoken );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
else
{
xSemaphoreGive( *pxSemaphore );
}
}
/*---------------------------------------------------------------------------*
@ -498,7 +557,10 @@ sys_thread_t xReturn;
*---------------------------------------------------------------------------*/
sys_prot_t sys_arch_protect( void )
{
taskENTER_CRITICAL();
if( xInsideISR == pdFALSE )
{
taskENTER_CRITICAL();
}
return ( sys_prot_t ) 1;
}
@ -516,7 +578,10 @@ sys_prot_t sys_arch_protect( void )
void sys_arch_unprotect( sys_prot_t xValue )
{
(void) xValue;
taskEXIT_CRITICAL();
if( xInsideISR == pdFALSE )
{
taskEXIT_CRITICAL();
}
}
/*

@ -145,9 +145,6 @@
#include "IntQueue.h"
#include "EventGroupsDemo.h"
/* lwIP includes. */
#include "lwip/tcpip.h"
/* Priorities for the demo application tasks. */
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
@ -228,11 +225,6 @@ extern void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriori
*/
static void prvPseudoRandomiser( void *pvParameters );
/*
* Defined in lwIPApps.c.
*/
extern void lwIPAppsInit( void *pvArguments );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
@ -248,9 +240,6 @@ char *pcStatusMessage = "All tasks running without error";
void main_full( void )
{
/* Init lwIP and start lwIP tasks. */
tcpip_init( lwIPAppsInit, NULL );
/* Start all the other standard demo/test tasks. They have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */

@ -0,0 +1,184 @@
/*
FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that has become a de facto standard. *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book, reference *
* manual, or both from: http://www.FreeRTOS.org/Documentation *
* *
* Thank you! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available from the following
link: http://www.freertos.org/a00114.html
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong?" *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
/******************************************************************************
* NOTE 1: This project provides two demo applications. A simple blinky style
* project, and a more comprehensive test and demo application. The
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
* in main.c. This file implements the simply blinky style version.
*
* NOTE 2: This file only contains the source code that is specific to the
* basic demo. Generic functions, such FreeRTOS hook functions, and functions
* required to configure the hardware are defined in main.c.
******************************************************************************
*
* main_blinky() creates one queue, and two tasks. It then starts the
* scheduler.
*
* The Queue Send Task:
* The queue send task is implemented by the prvQueueSendTask() function in
* this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
* block for 200 milliseconds, before sending the value 100 to the queue that
* was created within main_blinky(). Once the value is sent, the task loops
* back around to block for another 200 milliseconds...and so on.
*
* The Queue Receive Task:
* The queue receive task is implemented by the prvQueueReceiveTask() function
* in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
* blocks on attempts to read data from the queue that was created within
* main_blinky(). When data is received, the task checks the value of the
* data, and if the value equals the expected 100, toggles an LED. The 'block
* time' parameter passed to the queue receive function specifies that the
* task should be held in the Blocked state indefinitely to wait for data to
* be available on the queue. The queue receive task will only leave the
* Blocked state when the queue send task writes to the queue. As the queue
* send task writes to the queue every 200 milliseconds, the queue receive
* task leaves the Blocked state every 200 milliseconds, and therefore toggles
* the LED every 200 milliseconds.
*/
#warning Need to update the comment above.
#warning Move lwIP code into the lwIP_Demo directory.
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
/* Standard demo includes. */
#include "partest.h"
/* lwIP includes. */
#include "lwip/tcpip.h"
/* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */
#define mainTIMER_PERIOD_MS ( 200 / portTICK_PERIOD_MS )
/* The LED toggled by the Rx task. */
#define mainTIMER_LED ( 0 )
/* A block time of zero just means "don't block". */
#define mainDONT_BLOCK ( 0 )
/*-----------------------------------------------------------*/
/*
* The callback for the timer that just toggles an LED to show the system is
* running.
*/
static void prvLEDToggleTimer( TimerHandle_t pxTimer );
/*
* Defined in lwIPApps.c.
*/
extern void lwIPAppsInit( void *pvArguments );
/*-----------------------------------------------------------*/
void main_lwIP( void )
{
TimerHandle_t xTimer;
/* Init lwIP and start lwIP tasks. */
tcpip_init( lwIPAppsInit, NULL );
/* A timer is used to toggle an LED just to show the application is
executing. */
xTimer = xTimerCreate( "LED", /* Text name to make debugging easier. */
mainTIMER_PERIOD_MS, /* The timer's period. */
pdTRUE, /* This is an auto reload timer. */
NULL, /* ID is not used. */
prvLEDToggleTimer ); /* The callback function. */
/* Start the timer. */
configASSERT( xTimer );
xTimerStart( xTimer, mainDONT_BLOCK );
/* Start the tasks and timer running. */
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */
for( ;; );
}
/*-----------------------------------------------------------*/
static void prvLEDToggleTimer( TimerHandle_t pxTimer )
{
/* Prevent compiler warnings. */
( void ) pxTimer;
/* Just toggle an LED to show the application is running. */
vParTestToggleLED( mainTIMER_LED );
}

@ -40,6 +40,7 @@ signed char *pcLwipBlockingGetTxBuffer( void );
void vLwipAppsReleaseTxBuffer( void );
#define CONFIG_LINKSPEED_AUTODETECT 1
#define OS_IS_FREERTOS
/* SSI options. */
#define TCPIP_THREAD_NAME "tcpip"
@ -148,10 +149,10 @@ a lot of data that needs to be copied, this should be set high. */
/* The following four are used only with the sequential API and can be
set to 0 if the application only will use the raw API. */
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
#define MEMP_NUM_NETBUF 8
#define MEMP_NUM_NETBUF 0
/* MEMP_NUM_NETCONN: the number of struct netconns. */
#define MEMP_NUM_NETCONN 16
#define MEMP_NUM_NETCONN 10
/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used
for sequential API communication and incoming packets. Used in
@ -198,13 +199,6 @@ a lot of data that needs to be copied, this should be set high. */
TCP_SND_BUF/TCP_MSS for things to work. */
#define TCP_SND_QUEUELEN (16 * TCP_SND_BUF/TCP_MSS)
#define CHECKSUM_GEN_TCP 0
#define CHECKSUM_GEN_UDP 0
#define CHECKSUM_GEN_IP 0
#define CHECKSUM_CHECK_TCP 0
#define CHECKSUM_CHECK_UDP 0
#define CHECKSUM_CHECK_IP 0
/* TCP writable space (bytes). This must be less than or equal
to TCP_SND_BUF. It is the amount of space which must be
available in the tcp snd_buf for select to return writable */
@ -225,6 +219,9 @@ a lot of data that needs to be copied, this should be set high. */
#define ARP_TABLE_SIZE 10
#define ARP_QUEUEING 1
#define ICMP_TTL 255
#define IP_OPTIONS 0
/* ---------- IP options ---------- */
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
@ -234,15 +231,10 @@ a lot of data that needs to be copied, this should be set high. */
/* IP reassembly and segmentation.These are orthogonal even
* if they both deal with IP fragments */
#define IP_REASSEMBLY 1
#define IP_REASS_MAX_PBUFS 128
#define IP_REASSEMBLY 0
#define IP_REASS_MAX_PBUFS 10
#define MEMP_NUM_REASSDATA 10
#define IP_FRAG 1
#define IP_OPTIONS 0
#define IP_FRAG_MAX_MTU 1500
#define IP_DEFAULT_TTL 255
#define LWIP_CHKSUM_ALGORITHM 3
#define IP_FRAG 0
/* ---------- ICMP options ---------- */
@ -290,15 +282,6 @@ a lot of data that needs to be copied, this should be set high. */
#endif /* LWIP_STATS */
#define NO_SYS_NO_TIMERS 1
#define MEMP_SEPARATE_POOLS 1
#define MEMP_NUM_FRAG_PBUF 256
#define IP_OPTIONS_ALLOWED 0
#define TCP_OVERSIZE TCP_MSS
#define LWIP_COMPAT_MUTEX 0
#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 1
/* ---------- PPP options ---------- */
#define PPP_SUPPORT 0 /* Set > 0 for PPP */

@ -113,7 +113,7 @@
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/
@ -157,9 +157,13 @@ XScuGic xInterruptController;
int main( void )
{
extern void main_lwIP( void );
/* Configure the hardware ready to run the demo. */
prvSetupHardware();
main_lwIP();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )

Loading…
Cancel
Save