mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Update the uIP_Task.c implementation for the RX62N/RDK/Renesas demo to use FreeRTOS software timers in place of the uIP timers.
This commit is contained in:
parent
968aa1b199
commit
753ba20386
|
@ -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,25 +98,29 @@
|
|||
*/
|
||||
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 )
|
||||
{
|
||||
return xTaskGetTickCount();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
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 )
|
||||
{
|
||||
vEMACWrite();
|
||||
}
|
||||
}
|
||||
|
||||
xDoneSomething = pdTRUE;
|
||||
}
|
||||
else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
|
||||
else
|
||||
{
|
||||
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;
|
||||
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,25 +206,83 @@ 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 )
|
||||
{
|
||||
/* 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 );
|
||||
ulUIP_Events &= ~uipARP_TIMER_EVENT;
|
||||
uip_arp_timer();
|
||||
}
|
||||
|
||||
if( ulUIP_Events == pdFALSE )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
Loading…
Reference in a new issue