From d00f372dfa1ab45dd1f0664a362913aba39ff7f0 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Sat, 23 Apr 2011 15:27:34 +0000 Subject: [PATCH] Update the uIP_Task.c implementation for the RX62N/RDK/Renesas demo to use FreeRTOS software timers in place of the uIP timers. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1378 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../RTOSDemo/uIP_Task.c | 215 +++++++++++------- 1 file changed, 139 insertions(+), 76 deletions(-) diff --git a/Demo/RX600_RX62N-RDK_Renesas/RTOSDemo/uIP_Task.c b/Demo/RX600_RX62N-RDK_Renesas/RTOSDemo/uIP_Task.c index 1521ef895..0873c9ed8 100644 --- a/Demo/RX600_RX62N-RDK_Renesas/RTOSDemo/uIP_Task.c +++ b/Demo/RX600_RX62N-RDK_Renesas/RTOSDemo/uIP_Task.c @@ -57,7 +57,8 @@ /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" -#include "semphr.h" +#include "timers.h" +#include "queue.h" /* uip includes. */ #include "net/uip.h" @@ -81,6 +82,15 @@ /* Standard constant. */ #define uipTOTAL_FRAME_HEADER_SIZE 54 +/* The ARP timer and the periodic timer share a callback function, so the +respective timer IDs are used to determine which timer actually expired. These +constants are assigned to the timer IDs. */ +#define uipARP_TIMER 0 +#define uipPERIODIC_TIMER 1 + +/* A block time of zero ticks simply means, "don't block". */ +#define uipDONT_BLOCK 0UL + /*-----------------------------------------------------------*/ /* @@ -88,23 +98,27 @@ */ static void prvSetMACAddress( void ); +/* + * Perform any uIP initialisation necessary. + */ +static void prvInitialise_uIP( void ); + +/* + * The callback function that is assigned to both the periodic timer and the + * ARP timer. + */ +static void prvUIPTimerCallback( xTimerHandle xTimer ); + /* * Port functions required by the uIP stack. */ -void clock_init( void ); clock_time_t clock_time( void ); /*-----------------------------------------------------------*/ -/* The semaphore used by the ISR to wake the uIP task. */ -xSemaphoreHandle xEMACSemaphore = NULL; - -/*-----------------------------------------------------------*/ +/* The queue used to send TCP/IP events to the uIP stack. */ +xQueueHandle xEMACEventQueue = NULL; -void clock_init(void) -{ - /* This is done when the scheduler starts. */ -} /*-----------------------------------------------------------*/ clock_time_t clock_time( void ) @@ -115,25 +129,14 @@ clock_time_t clock_time( void ) void vuIP_Task( void *pvParameters ) { -portBASE_TYPE i, xDoneSomething; -uip_ipaddr_t xIPAddr; -struct timer periodic_timer, arp_timer; +portBASE_TYPE i; +unsigned long ulNewEvent = 0UL; +unsigned long ulUIP_Events = 0UL; ( void ) pvParameters; - + /* Initialise the uIP stack. */ - timer_set( &periodic_timer, configTICK_RATE_HZ / 2 ); - timer_set( &arp_timer, configTICK_RATE_HZ * 10 ); - uip_init(); - uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 ); - uip_sethostaddr( &xIPAddr ); - uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 ); - uip_setnetmask( &xIPAddr ); - prvSetMACAddress(); - httpd_init(); - - /* Create the semaphore used to wake the uIP task. */ - vSemaphoreCreateBinary( xEMACSemaphore ); + prvInitialise_uIP(); /* Initialise the MAC. */ vInitEmac(); @@ -145,49 +148,51 @@ struct timer periodic_timer, arp_timer; for( ;; ) { - xDoneSomething = pdFALSE; - - /* Is there received data ready to be processed? */ - uip_len = ( unsigned short ) ulEMACRead(); - - if( ( uip_len > 0 ) && ( uip_buf != NULL ) ) - { - /* Standard uIP loop taken from the uIP manual. */ - if( xHeader->type == htons( UIP_ETHTYPE_IP ) ) + if( ( ulUIP_Events & uipETHERNET_RX_EVENT ) != 0UL ) + { + /* Is there received data ready to be processed? */ + uip_len = ( unsigned short ) ulEMACRead(); + + if( ( uip_len > 0 ) && ( uip_buf != NULL ) ) { - uip_arp_ipin(); - uip_input(); - - /* If the above function invocation resulted in data that - should be sent out on the network, the global variable - uip_len is set to a value > 0. */ - if( uip_len > 0 ) + /* Standard uIP loop taken from the uIP manual. */ + if( xHeader->type == htons( UIP_ETHTYPE_IP ) ) { - uip_arp_out(); - vEMACWrite(); + uip_arp_ipin(); + uip_input(); + + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if( uip_len > 0 ) + { + uip_arp_out(); + vEMACWrite(); + } } - - xDoneSomething = pdTRUE; - } - else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) ) - { - uip_arp_arpin(); - - /* If the above function invocation resulted in data that - should be sent out on the network, the global variable - uip_len is set to a value > 0. */ - if( uip_len > 0 ) + else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) ) { - vEMACWrite(); + uip_arp_arpin(); + + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if( uip_len > 0 ) + { + vEMACWrite(); + } } - - xDoneSomething = pdTRUE; + } + else + { + ulUIP_Events &= ~uipETHERNET_RX_EVENT; } } - - if( timer_expired( &periodic_timer ) && ( uip_buf != NULL ) ) + + if( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL ) { - timer_reset( &periodic_timer ); + ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT; + for( i = 0; i < UIP_CONNS; i++ ) { uip_periodic( i ); @@ -201,29 +206,87 @@ struct timer periodic_timer, arp_timer; vEMACWrite(); } } - - /* Call the ARP timer function every 10 seconds. */ - if( timer_expired( &arp_timer ) ) - { - timer_reset( &arp_timer ); - uip_arp_timer(); - } - - xDoneSomething = pdTRUE; } - if( xDoneSomething == pdFALSE ) + /* Call the ARP timer function every 10 seconds. */ + if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 ) + { + ulUIP_Events &= ~uipARP_TIMER_EVENT; + uip_arp_timer(); + } + + if( ulUIP_Events == pdFALSE ) { - /* We did not receive a packet, and there was no periodic - processing to perform. Block for a fixed period. If a packet - is received during this period we will be woken by the ISR - giving us the Semaphore. */ - xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 20 ); + xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY ); + ulUIP_Events |= ulNewEvent; } } } /*-----------------------------------------------------------*/ +static void prvInitialise_uIP( void ) +{ +xTimerHandle xARPTimer, xPeriodicTimer; +uip_ipaddr_t xIPAddr; +struct timer periodic_timer, arp_timer; +const unsigned long ul_uIPEventQueueLength = 10UL; + + /* Initialise the uIP stack. */ + uip_init(); + uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 ); + uip_sethostaddr( &xIPAddr ); + uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 ); + uip_setnetmask( &xIPAddr ); + prvSetMACAddress(); + httpd_init(); + + /* Create the queue used to sent TCP/IP events to the uIP stack. */ + xEMACEventQueue = xQueueCreate( ul_uIPEventQueueLength, sizeof( unsigned long ) ); + + /* Create and start the uIP timers. */ + xARPTimer = xTimerCreate( ( const signed char * const ) "ARPTimer", /* Just a name that is helpful for debugging, not used by the kernel. */ + ( 10000UL / portTICK_RATE_MS ), /* Timer period. */ + pdTRUE, /* Autor-reload. */ + ( void * ) uipARP_TIMER, + prvUIPTimerCallback + ); + + xPeriodicTimer = xTimerCreate( ( const signed char * const ) "PeriodicTimer", + ( 500 / portTICK_RATE_MS ), + pdTRUE, /* Autor-reload. */ + ( void * ) uipPERIODIC_TIMER, + prvUIPTimerCallback + ); + + configASSERT( xARPTimer ); + configASSERT( xPeriodicTimer ); + + xTimerStart( xARPTimer, portMAX_DELAY ); + xTimerStart( xPeriodicTimer, portMAX_DELAY ); +} +/*-----------------------------------------------------------*/ + +static void prvUIPTimerCallback( xTimerHandle xTimer ) +{ +static const unsigned long ulARPTimerExpired = uipARP_TIMER_EVENT; +static const unsigned long ulPeriodicTimerExpired = uipPERIODIC_TIMER_EVENT; + + /* This is a time callback, so calls to xQueueSend() must not attempt to + block. */ + switch( ( int ) pvTimerGetTimerID( xTimer ) ) + { + case uipARP_TIMER : xQueueSend( xEMACEventQueue, &ulARPTimerExpired, uipDONT_BLOCK ); + break; + + case uipPERIODIC_TIMER : xQueueSend( xEMACEventQueue, &ulPeriodicTimerExpired, uipDONT_BLOCK ); + break; + + default : /* Should not get here. */ + break; + } +} +/*-----------------------------------------------------------*/ + static void prvSetMACAddress( void ) { struct uip_eth_addr xAddr; -- 2.39.2