Update the demo directory (temporary) local copy of the MicroBlaze EthernetLite port layer.

pull/4/head
Richard Barry 14 years ago
parent 9d1c23f6da
commit 6c0fe51bf2

@ -32,6 +32,17 @@
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
#include "xparameters.h"
/* Define platform endianness (might already be defined) */
#ifndef BYTE_ORDER
#if XPAR_MICROBLAZE_0_ENDIANNESS == 1
#define BYTE_ORDER LITTLE_ENDIAN
#else
#define BYTE_ORDER BIG_ENDIAN
#endif
#endif /* BYTE_ORDER */
/* SSI options. */
#define TCPIP_THREAD_NAME "tcpip"
#define LWIP_HTTPD_MAX_TAG_NAME_LEN 20

@ -51,15 +51,14 @@
licensing and training services.
*/
#if 0
//_RB_
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* BSP includes. */
#include "xemaclite.h"
/* lwIP includes. */
#include "lwip/opt.h"
#include "lwip/def.h"
@ -69,87 +68,74 @@
#include <lwip/stats.h>
#include <lwip/snmp.h>
#include "netif/etharp.h"
#include "netif/ppp_oe.h"
/* Define those to better describe your network interface. */
#define IFNAME0 'w'
#define IFNAME1 'p'
#define IFNAME0 'e'
#define IFNAME1 'l'
#define netifMAX_MTU 1500
struct ethernetif
struct xEthernetIf
{
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
};
/* Forward declarations. */
static void ethernetif_input( const unsigned char * const pucInputData, long lLength );
static struct pbuf *low_level_input( const unsigned char * const pucInputData, long lDataLength );
/*
* Query the computer the simulation is being executed on to find the network
* interfaces it has installed.
* Place received packet in a pbuf and send a message to the tcpip task to let
* it know new data has arrived.
*/
static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );
static void prvEthernetInput( struct netif *pxNetIf, const unsigned char * const pucInputData, long lInputLength );
/*
* Open the network interface. The number of the interface to be opened is set
* by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
* Copy the received data into a pbuf.
*/
static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );
static struct pbuf *prvLowLevelInput( const unsigned char * const pucInputData, long lDataLength );
/*
* Interrupts cannot truely be simulated using WinPCap. In reality this task
* just polls the interface.
* Send data from a pbuf to the hardware.
*/
static void prvInterruptSimulator( void *pvParameters );
static err_t prvLowLevelOutput( struct netif *pxNetIf, struct pbuf *p );
/*
* Configure the capture filter to allow blocking reads, and to filter out
* packets that are not of interest to this demo.
* Perform any hardware and/or driver initialisation necessary.
*/
static void prvConfigureCaptureBehaviour( void );
/* The WinPCap interface being used. */
static pcap_t *pxOpenedInterfaceHandle = NULL;
static void prvLowLevelInit( struct netif *pxNetIf );
/* Parameter required for WinPCap API functions. */
static char cErrorBuffer[ PCAP_ERRBUF_SIZE ];
/* The network interface that was opened. */
static struct netif *xlwIPNetif = NULL;
/*-----------------------------------------------------------*/
/**
* In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param netif the already initialized lwip network interface structure
* for this ethernetif
* @param pxNetIf the already initialized lwip network interface structure
* for this etherpxNetIf
*/
static void low_level_init(struct netif *netif)
static void prvLowLevelInit( struct netif *pxNetIf )
{
pcap_if_t *pxAllNetworkInterfaces;
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
pxNetIf->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[ 0 ] = configMAC_ADDR0;
netif->hwaddr[ 1 ] = configMAC_ADDR1;
netif->hwaddr[ 2 ] = configMAC_ADDR2;
netif->hwaddr[ 3 ] = configMAC_ADDR3;
netif->hwaddr[ 4 ] = configMAC_ADDR4;
netif->hwaddr[ 5 ] = configMAC_ADDR5;
pxNetIf->hwaddr[ 0 ] = configMAC_ADDR0;
pxNetIf->hwaddr[ 1 ] = configMAC_ADDR1;
pxNetIf->hwaddr[ 2 ] = configMAC_ADDR2;
pxNetIf->hwaddr[ 3 ] = configMAC_ADDR3;
pxNetIf->hwaddr[ 4 ] = configMAC_ADDR4;
pxNetIf->hwaddr[ 5 ] = configMAC_ADDR5;
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
/* Query the computer the simulation is being executed on to find the
/* don't set pxNetIf_FLAG_ETHARP if this device is not an ethernet one */
pxNetIf->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
#if 0
_RB_
/* Query the computer the simulation is being executed on to find the
network interfaces it has installed. */
pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces();
/* Open the network interface. The number of the interface to be opened is
/* Open the network interface. The number of the interface to be opened is
set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
Calling this function will set the pxOpenedInterfaceHandle variable. If,
after calling this function, pxOpenedInterfaceHandle is equal to NULL, then
@ -159,9 +145,10 @@ pcap_if_t *pxAllNetworkInterfaces;
prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces );
}
/* Remember which interface was opened as it is used in the interrupt
/* Remember which interface was opened as it is used in the interrupt
simulator task. */
xlwIPNetif = netif;
pxlwIPNetIf = pxNetIf;
#endif
}
/**
@ -169,109 +156,120 @@ pcap_if_t *pxAllNetworkInterfaces;
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this ethernetif
* @param pxNetIf the lwip network interface structure for this etherpxNetIf
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
static err_t prvLowLevelOutput( struct netif *pxNetIf, struct pbuf *p )
{
/* This is taken from lwIP example code and therefore does not conform
to the FreeRTOS coding standard. */
struct pbuf *q;
static unsigned char buffer[ 1520 ];
unsigned char *buf = buffer;
unsigned char *ptr;
struct eth_hdr *ethhdr;
u16_t tot_len = p->tot_len - ETH_PAD_SIZE;
static unsigned char ucBuffer[ 1520 ];
unsigned char *pucBuffer = ucBuffer;
unsigned char *pucChar;
struct eth_hdr *pxHeader;
u16_t usTotalLength = p->tot_len - ETH_PAD_SIZE;
err_t xReturn = ERR_OK;
#if defined(LWIP_DEBUG) && LWIP_NETIF_TX_SINGLE_PBUF
LWIP_ASSERT("p->next == NULL && p->len == p->tot_len", p->next == NULL && p->len == p->tot_len);
LWIP_ASSERT("p->next == NULL && p->len == p->tot_len", p->next == NULL && p->len == p->tot_len);
#endif
/* initiate transfer */
if (p->len == p->tot_len)
/* Initiate transfer. */
if( p->len == p->tot_len )
{
/* no pbuf chain, don't have to copy -> faster */
buf = &((unsigned char*)p->payload)[ETH_PAD_SIZE];
/* No pbuf chain, don't have to copy -> faster. */
pucBuffer = &( ( unsigned char * ) p->payload )[ ETH_PAD_SIZE ];
}
else
{
/* pbuf chain, copy into contiguous buffer */
if (p->tot_len >= sizeof(buffer))
/* pbuf chain, copy into contiguous ucBuffer. */
if( p->tot_len >= sizeof( ucBuffer ) )
{
LINK_STATS_INC(link.lenerr);
LINK_STATS_INC(link.drop);
snmp_inc_ifoutdiscards(netif);
return ERR_BUF;
LINK_STATS_INC( link.lenerr );
LINK_STATS_INC( link.drop );
snmp_inc_ifoutdiscards( pxNetIf );
xReturn = ERR_BUF;
}
else
{
pucChar = ucBuffer;
ptr = buffer;
for( q = p; q != NULL; q = q->next )
{
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. */
/* send data from(q->payload, q->len); */
LWIP_DEBUGF( NETIF_DEBUG, ("NETIF: send pucChar %p q->payload %p q->len %i q->next %p\n", pucChar, q->payload, ( int ) q->len, ( void* ) q->next ) );
if( q == p )
{
memcpy( pucChar, &( ( char * ) q->payload )[ ETH_PAD_SIZE ], q->len - ETH_PAD_SIZE );
pucChar += q->len - ETH_PAD_SIZE;
}
else
{
memcpy( pucChar, q->payload, q->len );
pucChar += q->len;
}
}
}
}
for( q = p; q != NULL; q = q->next )
if( xReturn == ERR_OK )
{
#if 0
_RB_
/* signal that packet should be sent */
if( pcap_sendpacket( pxOpenedInterfaceHandle, pucBuffer, usTotalLength ) < 0 )
{
LINK_STATS_INC( link.memerr );
LINK_STATS_INC( link.drop );
snmp_inc_ifoutdiscards( pxNetIf );
xReturn = ERR_BUF;
}
else
{
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. */
/* send data from(q->payload, q->len); */
LWIP_DEBUGF(NETIF_DEBUG, ("netif: send ptr %p q->payload %p q->len %i q->next %p\n", ptr, q->payload, (int)q->len, (void*)q->next));
if (q == p)
LINK_STATS_INC( link.xmit );
snmp_add_ifoutoctets( pxNetIf, usTotalLength );
pxHeader = ( struct eth_hdr * )p->payload;
if( ( pxHeader->dest.addr[ 0 ] & 1 ) != 0 )
{
memcpy(ptr, &((char*)q->payload)[ETH_PAD_SIZE], q->len - ETH_PAD_SIZE);
ptr += q->len - ETH_PAD_SIZE;
/* broadcast or multicast packet*/
snmp_inc_ifoutnucastpkts( pxNetIf );
}
else
{
memcpy(ptr, q->payload, q->len);
ptr += q->len;
/* unicast packet */
snmp_inc_ifoutucastpkts( pxNetIf );
}
}
#endif
}
/* signal that packet should be sent */
if( pcap_sendpacket( pxOpenedInterfaceHandle, buf, tot_len ) < 0 )
{
LINK_STATS_INC(link.memerr);
LINK_STATS_INC(link.drop);
snmp_inc_ifoutdiscards(netif);
return ERR_BUF;
}
LINK_STATS_INC(link.xmit);
snmp_add_ifoutoctets(netif, tot_len);
ethhdr = (struct eth_hdr *)p->payload;
if( ( ethhdr->dest.addr[ 0 ] & 1 ) != 0 )
{
/* broadcast or multicast packet*/
snmp_inc_ifoutnucastpkts(netif);
}
else
{
/* unicast packet */
snmp_inc_ifoutucastpkts( netif );
}
return ERR_OK;
return xReturn;
}
/**
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this ethernetif
* @param pxNetIf the lwip network interface structure for this etherpxNetIf
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
* NULL on memory error
*/
static struct pbuf *low_level_input( const unsigned char * const pucInputData, long lDataLength )
static struct pbuf *prvLowLevelInput( const unsigned char * const pucInputData, long lDataLength )
{
struct pbuf *p = NULL, *q;
@ -287,7 +285,7 @@ struct pbuf *p = NULL, *q;
if( p != NULL )
{
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
pbuf_header( p, -ETH_PAD_SIZE ); /* drop the padding word */
#endif
/* We iterate over the pbuf chain until we have read the entire
@ -300,7 +298,7 @@ struct pbuf *p = NULL, *q;
* variable.
* This does not necessarily have to be a memcpy, you can also preallocate
* pbufs for a DMA-enabled MAC and after receiving truncate it to the
* actually received size. In this case, ensure the tot_len member of the
* actually received size. In this case, ensure the usTotalLength member of the
* pbuf is the sum of the chained pbuf len members.
*/
memcpy( q->payload, &( pucInputData[ lDataLength ] ), q->len );
@ -320,279 +318,110 @@ struct pbuf *p = NULL, *q;
/**
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* from the interface. It uses the function prvLowLevelInput() that
* should handle the actual reception of bytes from the network
* interface. Then the type of the received packet is determined and
* the appropriate input function is called.
*
* @param netif the lwip network interface structure for this ethernetif
* @param pxNetIf the lwip network interface structure for this etherpxNetIf
*/
static void ethernetif_input( const unsigned char * const pucInputData, long lInputLength )
static void prvEthernetInput( struct netif *pxNetIf, const unsigned char * const pucInputData, long lInputLength )
{
/* This is taken from lwIP example code and therefore does not conform
to the FreeRTOS coding standard. */
struct eth_hdr *ethhdr;
struct eth_hdr *pxHeader;
struct pbuf *p;
/* move received packet into a new pbuf */
p = low_level_input( pucInputData, lInputLength );
p = prvLowLevelInput( pucInputData, lInputLength );
/* no packet could be read, silently ignore this */
if( p == NULL )
if( p != NULL )
{
return;
}
/* points to packet payload, which starts with an Ethernet header */
pxHeader = p->payload;
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
switch( htons( ethhdr->type ) )
{
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_ARP:
/* full packet send to tcpip_thread to process */
if(xlwIPNetif->input( p, xlwIPNetif )!=ERR_OK )
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
switch( htons( pxHeader->type ) )
{
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_ARP:
/* full packet send to tcpip_thread to process */
if( pxNetIf->input( p, pxNetIf ) != ERR_OK )
{
LWIP_DEBUGF(NETIF_DEBUG, ( "ethernetif_input: IP input error\n" ) );
pbuf_free(p);
p = NULL;
}
break;
default:
pbuf_free( p );
p = NULL;
}
break;
default:
pbuf_free( p );
p = NULL;
break;
break;
}
}
}
/**
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* network interface. It calls the function prvLowLevelInit() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
* This function should be passed as a parameter to pxNetIf_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @param pxNetIf the lwip network interface structure for this etherpxNetIf
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t ethernetif_init( struct netif *netif )
err_t ethernetif_init( struct netif *pxNetIf )
{
err_t xReturn = ERR_OK;
/* This is taken from lwIP example code and therefore does not conform
to the FreeRTOS coding standard. */
struct ethernetif *ethernetif;
LWIP_ASSERT( "netif != NULL", ( netif != NULL ) );
ethernetif = mem_malloc( sizeof( struct ethernetif ) );
if (ethernetif == NULL)
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
return ERR_MEM;
}
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
netif->state = ethernetif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
netif->output = etharp_output;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
netif->hwaddr_len = ETHARP_HWADDR_LEN;
netif->mtu = netifMAX_MTU;
netif->linkoutput = low_level_output;
ethernetif->ethaddr = ( struct eth_addr * ) &( netif->hwaddr[ 0 ] );
/* initialize the hardware */
low_level_init( netif );
return ERR_OK;
}
/*-----------------------------------------------------------*/
static pcap_if_t * prvPrintAvailableNetworkInterfaces( void )
{
pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface;
long lInterfaceNumber = 1;
if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 )
{
printf( "\r\nCould not obtain a list of network interfaces\r\n%s\r\n", cErrorBuffer );
pxAllNetworkInterfaces = NULL;
}
if( pxAllNetworkInterfaces != NULL )
{
/* Print out the list of network interfaces. The first in the list
is interface '1', not interface '0'. */
for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next )
{
printf( "%d. %s", lInterfaceNumber, xInterface->name );
if( xInterface->description != NULL )
{
printf( " (%s)\r\n", xInterface->description );
}
else
{
printf( " (No description available)\r\n") ;
}
lInterfaceNumber++;
}
}
if( lInterfaceNumber == 1 )
{
/* The interface number was never incremented, so the above for() loop
did not execute meaning no interfaces were found. */
printf( " \r\nNo network interfaces were found.\r\n" );
pxAllNetworkInterfaces = NULL;
}
struct xEthernetIf *pxEthernetIf;
printf( "\r\nThe interface that will be opened is set by configNETWORK_INTERFACE_TO_USE which should be defined in FreeRTOSConfig.h\r\n" );
printf( "Attempting to open interface number %d.\r\n", configNETWORK_INTERFACE_TO_USE );
LWIP_ASSERT( "pxNetIf != NULL", ( pxNetIf != NULL ) );
if( ( configNETWORK_INTERFACE_TO_USE < 1L ) || ( configNETWORK_INTERFACE_TO_USE > lInterfaceNumber ) )
{
printf("\r\nconfigNETWORK_INTERFACE_TO_USE is not in the valid range.\r\n" );
if( pxAllNetworkInterfaces != NULL )
{
/* Free the device list, as no devices are going to be opened. */
pcap_freealldevs( pxAllNetworkInterfaces );
pxAllNetworkInterfaces = NULL;
}
}
return pxAllNetworkInterfaces;
}
/*-----------------------------------------------------------*/
static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
{
pcap_if_t *xInterface;
long x;
/* Walk the list of devices until the selected device is located. */
xInterface = pxAllNetworkInterfaces;
for( x = 0L; x < ( configNETWORK_INTERFACE_TO_USE - 1L ); x++ )
pxEthernetIf = mem_malloc( sizeof( struct xEthernetIf ) );
if( pxEthernetIf == NULL )
{
xInterface = xInterface->next;
LWIP_DEBUGF(NETIF_DEBUG, ( "ethernetif_init: out of memory\n" ) );
xReturn = ERR_MEM;
}
/* Open the selected interface. */
pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */
netifMAX_MTU, /* The size of the packet to capture. */
PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscious mode as the MAC and
IP address is going to be "simulated", and
not be the real MAC and IP address. This allows
trafic to the simulated IP address to be routed
to uIP, and trafic to the real IP address to be
routed to the Windows TCP/IP stack. */
0L, /* The read time out. This is going to block
until data is available. */
NULL, /* No authentication is required as this is
not a remote capture session. */
cErrorBuffer
);
if ( pxOpenedInterfaceHandle == NULL )
{
printf( "\r\n%s is not supported by WinPcap and cannot be opened\r\n", xInterface->name );
}
else
{
/* Configure the capture filter to allow blocking reads, and to filter
out packets that are not of interest to this demo. */
prvConfigureCaptureBehaviour();
}
/* The device list is no longer required. */
pcap_freealldevs( pxAllNetworkInterfaces );
}
/*-----------------------------------------------------------*/
static void prvInterruptSimulator( void *pvParameters )
{
static struct pcap_pkthdr *pxHeader;
const unsigned char *pucPacketData;
extern xQueueHandle xEMACEventQueue;
long lResult;
/* Just to kill the compiler warning. */
( void ) pvParameters;
for( ;; )
{
/* Get the next packet. */
lResult = pcap_next_ex( pxOpenedInterfaceHandle, &pxHeader, &pucPacketData );
if( lResult == 1 )
{
if( xlwIPNetif != NULL )
{
ethernetif_input( pucPacketData, pxHeader->len );
}
}
else
#if LWIP_NETIF_HOSTNAME
{
/* There is no real way of simulating an interrupt.
Make sure other tasks can run. */
vTaskDelay( 5 );
/* Initialize interface hostname */
pxNetIf->hostname = "lwip";
}
#endif /* LWIP_NETIF_HOSTNAME */
pxNetIf->state = pxEthernetIf;
pxNetIf->name[ 0 ] = IFNAME0;
pxNetIf->name[ 1 ] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
pxNetIf->output = etharp_output;
pxNetIf->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
pxNetIf->hwaddr_len = ETHARP_HWADDR_LEN;
pxNetIf->mtu = netifMAX_MTU;
pxNetIf->linkoutput = prvLowLevelOutput;
pxEthernetIf->ethaddr = ( struct eth_addr * ) &( pxNetIf->hwaddr[ 0 ] );
/* initialize the hardware */
prvLowLevelInit( pxNetIf );
}
}
/*-----------------------------------------------------------*/
static void prvConfigureCaptureBehaviour( void )
{
struct bpf_program xFilterCode;
const long lMinBytesToCopy = 10L, lBlocking = 1L;
unsigned long ulNetMask;
/* Unblock a read as soon as anything is received. */
pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy );
/* Allow blocking. */
pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer );
/* Set up a filter so only the packets of interest are passed to the lwIP
stack. cErrorBuffer is used for convenience to create the string. Don't
confuse this with an error message. */
sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0;
if( pcap_compile(pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 )
{
printf("\r\nThe packet filter string is invalid\r\n" );
}
else
{
if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 )
{
printf( "\r\nAn error occurred setting the packet filter.\r\n" );
}
}
/* Create a task that simulates an interrupt in a real system. This will
block waiting for packets, then send a message to the uIP task when data
is available. */
xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, configMAC_ISR_SIMULATOR_PRIORITY, NULL );
return xReturn;
}
#endif
/*-----------------------------------------------------------*/

@ -32,38 +32,23 @@
#ifndef __ARCH_CC_H__
#define __ARCH_CC_H__
#if 1
/* Include some files for defining library routines */
#include <stdio.h> /* printf, fflush, FILE */
#include <stdlib.h> /* abort */
#else
/* Declare fuction prototypes for assert/diag/error - leads to some warnings,
* but good to test if no includes are missing. */
int printf(const char *format, ...);
void abort(void);
struct _iobuf;
typedef struct _iobuf FILE;
int fflush(FILE *stream);
#endif
/** @todo fix some warnings: don't use #pragma if compiling with cygwin gcc */
#ifndef __GNUC__
#include <limits.h>
#pragma warning (disable: 4244) /* disable conversion warning (implicit integer promotion!) */
#pragma warning (disable: 4127) /* conditional expression is constant */
#pragma warning (disable: 4996) /* 'strncpy' was declared deprecated */
#pragma warning (disable: 4103) /* structure packing changed by including file */
#include <limits.h>
#pragma warning (disable: 4244) /* disable conversion warning (implicit integer promotion!) */
#pragma warning (disable: 4127) /* conditional expression is constant */
#pragma warning (disable: 4996) /* 'strncpy' was declared deprecated */
#pragma warning (disable: 4103) /* structure packing changed by including file */
#endif
#define LWIP_PROVIDE_ERRNO
/* Define platform endianness (might already be defined) */
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* BYTE_ORDER */
/* Define generic types used in lwIP */
typedef unsigned char u8_t;
typedef signed char s8_t;

@ -37,8 +37,8 @@
#include "queue.h"
#include "semphr.h"
#define SYS_MBOX_NULL (xQueueHandle)0
#define SYS_SEM_NULL (xSemaphoreHandle)0
#define SYS_MBOX_NULL ( ( xQueueHandle ) NULL )
#define SYS_SEM_NULL ( ( xSemaphoreHandle ) NULL )
#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
typedef xSemaphoreHandle sys_sem_t;
@ -46,18 +46,10 @@ typedef xSemaphoreHandle sys_mutex_t;
typedef xQueueHandle sys_mbox_t;
typedef xTaskHandle sys_thread_t;
typedef struct _sys_arch_state_t
{
// Task creation data.
char cTaskName[configMAX_TASK_NAME_LEN];
unsigned short nStackDepth;
unsigned short nTaskCount;
} sys_arch_state_t;
#define sys_mbox_valid( x ) ( (*x == NULL) ? 0 : 1 )
#define sys_mbox_set_invalid( x ) ( *x = NULL )
#define sys_sem_valid( x ) ( (*x == NULL) ? 0 : 1 )
#define sys_sem_set_invalid( x ) ( *x = NULL )
#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
#define sys_mbox_set_invalid( x ) ( ( *x ) = NULL )
#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
#define sys_sem_set_invalid( x ) ( ( *x ) = NULL )
#endif /* __ARCH_SYS_ARCH_H__ */

@ -48,28 +48,6 @@
#include "lwip/mem.h"
#include "lwip/stats.h"
/*---------------------------------------------------------------------------*
* Globals:
*---------------------------------------------------------------------------*/
#if 0
_RB_
struct timeoutlist
{
struct sys_timeouts timeouts;
xTaskHandle pid;
};
/* This is the number of threads that can be started with sys_thread_new() */
#define SYS_THREAD_MAX 4
static u16_t s_nextthread = 0;
static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX];
#endif
/*-----------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
* Routine: sys_mbox_new
*---------------------------------------------------------------------------*
@ -80,22 +58,23 @@ static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX];
* Outputs:
* sys_mbox_t -- Handle to new mailbox
*---------------------------------------------------------------------------*/
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
err_t sys_mbox_new( sys_mbox_t *pxMailBox, int iSize )
{
err_t lwip_err= ERR_MEM;
err_t xReturn = ERR_MEM;
*mbox = xQueueCreate( size, sizeof( void * ) );
*pxMailBox = xQueueCreate( iSize, sizeof( void * ) );
// Created succesfully?
if(*mbox != NULL)
if( *pxMailBox != NULL )
{
lwip_err = ERR_OK;
#if SYS_STATS
SYS_STATS_INC(mbox.used);
#endif /* SYS_STATS */
xReturn = ERR_OK;
#if SYS_STATS
{
SYS_STATS_INC( mbox.used );
}
#endif /* SYS_STATS */
}
return lwip_err;
return xReturn;
}
@ -111,23 +90,25 @@ err_t lwip_err= ERR_MEM;
* Outputs:
* sys_mbox_t -- Handle to new mailbox
*---------------------------------------------------------------------------*/
void sys_mbox_free(sys_mbox_t *mbox)
void sys_mbox_free( sys_mbox_t *pxMailBox )
{
unsigned portBASE_TYPE uxMessagesWaiting;
unsigned long ulMessagesWaiting;
uxMessagesWaiting = uxQueueMessagesWaiting( *mbox );
configASSERT( ( uxMessagesWaiting == 0 ) );
ulMessagesWaiting = uxQueueMessagesWaiting( *pxMailBox );
configASSERT( ( ulMessagesWaiting == 0 ) );
#if SYS_STATS
if (uxMessagesWaiting != 0U)
#if SYS_STATS
{
SYS_STATS_INC(mbox.err);
}
if( ulMessagesWaiting != 0UL )
{
SYS_STATS_INC( mbox.err );
}
SYS_STATS_DEC(mbox.used);
#endif /* SYS_STATS */
SYS_STATS_DEC( mbox.used );
}
#endif /* SYS_STATS */
vQueueDelete( *mbox );
vQueueDelete( *pxMailBox );
}
/*---------------------------------------------------------------------------*
@ -139,9 +120,9 @@ unsigned portBASE_TYPE uxMessagesWaiting;
* sys_mbox_t mbox -- Handle of mailbox
* void *data -- Pointer to data to post
*---------------------------------------------------------------------------*/
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost )
{
while( xQueueSendToBack( *mbox, &msg, portMAX_DELAY ) != pdTRUE );
while( xQueueSendToBack( *pxMailBox, &pxMessageToPost, portMAX_DELAY ) != pdTRUE );
}
/*---------------------------------------------------------------------------*
@ -157,23 +138,26 @@ void sys_mbox_post(sys_mbox_t *mbox, void *msg)
* err_t -- ERR_OK if message posted, else ERR_MEM
* if not.
*---------------------------------------------------------------------------*/
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
err_t sys_mbox_trypost( sys_mbox_t *pxMailBox, void *pxMessageToPost )
{
err_t result;
err_t xReturn;
if ( xQueueSend( *mbox, &msg, 0 ) == pdPASS )
if( xQueueSend( *pxMailBox, &pxMessageToPost, 0UL ) == pdPASS )
{
result = ERR_OK;
xReturn = ERR_OK;
}
else
{
// could not post, queue must be full
result = ERR_MEM;
#if SYS_STATS
SYS_STATS_INC(mbox.err);
#endif /* SYS_STATS */
/* The queue was already full. */
xReturn = ERR_MEM;
#if SYS_STATS
{
SYS_STATS_INC( mbox.err );
}
#endif /* SYS_STATS */
}
return result;
return xReturn;
}
/*---------------------------------------------------------------------------*
@ -201,48 +185,50 @@ err_t result;
* u32_t -- SYS_ARCH_TIMEOUT if timeout, else number
* of milliseconds until received.
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
u32_t sys_arch_mbox_fetch( sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut )
{
void *dummyptr;
portTickType StartTime, EndTime, Elapsed;
void *pvDummy;
portTickType xStartTime, xEndTime, xElapsed;
unsigned long ulReturn;
StartTime = xTaskGetTickCount();
xStartTime = xTaskGetTickCount();
if (NULL == msg)
if( NULL == ppvBuffer )
{
msg = &dummyptr;
ppvBuffer = &pvDummy;
}
if (timeout != 0)
if( ulTimeOut != 0UL )
{
if ( pdTRUE == xQueueReceive( *mbox, &(*msg), timeout / portTICK_RATE_MS ) )
if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), ulTimeOut/ portTICK_RATE_MS ) )
{
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS;
return ( Elapsed );
ulReturn = xElapsed;
}
else // timed out blocking for message
else
{
*msg = NULL;
return SYS_ARCH_TIMEOUT;
/* Timed out. */
*ppvBuffer = NULL;
ulReturn = SYS_ARCH_TIMEOUT;
}
}
else
{
while( pdTRUE != xQueueReceive( mbox, &(*msg), portMAX_DELAY ) ); // time is arbitrary
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
while( pdTRUE != xQueueReceive( pxMailBox, &( *ppvBuffer ), portMAX_DELAY ) );
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS;
if (Elapsed == 0)
if( xElapsed == 0UL )
{
Elapsed = 1;
xElapsed = 1UL;
}
// return time blocked TBD test
return (Elapsed);
ulReturn = xElapsed;
}
return ulReturn;
}
/*---------------------------------------------------------------------------*
@ -259,66 +245,72 @@ portTickType StartTime, EndTime, Elapsed;
* u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise,
* return ERR_OK.
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
u32_t sys_arch_mbox_tryfetch( sys_mbox_t *pxMailBox, void **ppvBuffer )
{
void *dummyptr;
void *pvDummy;
unsigned long ulReturn;
if (msg == NULL)
if( ppvBuffer== NULL )
{
msg = &dummyptr;
ppvBuffer = &pvDummy;
}
if ( pdTRUE == xQueueReceive( *mbox, &(*msg), 0 ) )
if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), 0UL ) )
{
return ERR_OK;
ulReturn = ERR_OK;
}
else
{
return SYS_MBOX_EMPTY;
ulReturn = SYS_MBOX_EMPTY;
}
return ulReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_new
*---------------------------------------------------------------------------*
* Description:
* Creates and returns a new semaphore. The "count" argument specifies
* Creates and returns a new semaphore. The "ucCount" argument specifies
* the initial state of the semaphore.
* NOTE: Currently this routine only creates counts of 1 or 0
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* u8_t count -- Initial count of semaphore (1 or 0)
* u8_t ucCount -- Initial ucCount of semaphore (1 or 0)
* Outputs:
* sys_sem_t -- Created semaphore or 0 if could not create.
*---------------------------------------------------------------------------*/
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
err_t sys_sem_new( sys_sem_t *pxSemaphore, u8_t ucCount )
{
err_t lwip_err = ERR_MEM;
err_t xReturn = ERR_MEM;
vSemaphoreCreateBinary( (*sem) );
vSemaphoreCreateBinary( ( *pxSemaphore ) );
if( *sem != NULL )
if( *pxSemaphore != NULL )
{
// Means it can't be taken
if (count == 0)
if( ucCount == 0U )
{
xSemaphoreTake(*sem, 1);
xSemaphoreTake( *pxSemaphore, 1UL );
}
lwip_err = ERR_OK;
xReturn = ERR_OK;
#if SYS_STATS
SYS_STATS_INC(sem.used);
#endif
#if SYS_STATS
{
SYS_STATS_INC( sem.used );
}
#endif
}
else
{
#if SYS_STATS
SYS_STATS_INC(sem.err);
#endif
#if SYS_STATS
{
SYS_STATS_INC( sem.err );
}
#endif
}
return lwip_err;
return xReturn;
}
/*---------------------------------------------------------------------------*
@ -344,92 +336,98 @@ err_t sys_sem_new(sys_sem_t *sem, u8_t count)
* Outputs:
* u32_t -- Time elapsed or SYS_ARCH_TIMEOUT.
*---------------------------------------------------------------------------*/
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
u32_t sys_arch_sem_wait( sys_sem_t *pxSemaphore, u32_t ulTimeout )
{
portTickType StartTime, EndTime, Elapsed;
portTickType xStartTime, xEndTime, xElapsed;
unsigned long ulReturn;
StartTime = xTaskGetTickCount();
xStartTime = xTaskGetTickCount();
if (timeout != 0)
if( ulTimeout != 0UL )
{
if( xSemaphoreTake( *sem, timeout / portTICK_RATE_MS ) == pdTRUE )
if( xSemaphoreTake( *pxSemaphore, ulTimeout / portTICK_RATE_MS ) == pdTRUE )
{
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
return (Elapsed); // return time blocked TODO test
xEndTime = xTaskGetTickCount();
xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS;
ulReturn = xElapsed;
}
else
{
return SYS_ARCH_TIMEOUT;
ulReturn = SYS_ARCH_TIMEOUT;
}
}
else
{
while( xSemaphoreTake( sem, portMAX_DELAY ) != pdTRUE );
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
while( xSemaphoreTake( pxSemaphore, portMAX_DELAY ) != pdTRUE );
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS;
if (Elapsed == 0)
if( xElapsed == 0UL )
{
Elapsed = 1;
xElapsed = 1UL;
}
// return time blocked
return (Elapsed);
ulReturn = xElapsed;
}
return ulReturn;
}
/** Create a new mutex
* @param mutex pointer to the mutex to create
* @return a new mutex */
err_t sys_mutex_new(sys_mutex_t *mutex)
err_t sys_mutex_new( sys_mutex_t *pxMutex )
{
err_t lwip_err = ERR_MEM;
err_t xReturn = ERR_MEM;
*mutex = xQueueCreateMutex();
*pxMutex = xQueueCreateMutex();
if( *mutex != NULL )
if( *pxMutex != NULL )
{
lwip_err = ERR_OK;
#if SYS_STATS
SYS_STATS_INC(mutex.used);
#endif
xReturn = ERR_OK;
#if SYS_STATS
{
SYS_STATS_INC( mutex.used );
}
#endif
}
else
{
#if SYS_STATS
SYS_STATS_INC(mutex.err);
#endif
#if SYS_STATS
{
SYS_STATS_INC( mutex.err );
}
#endif
}
return lwip_err;
return xReturn;
}
/** Lock a mutex
* @param mutex the mutex to lock */
void sys_mutex_lock(sys_mutex_t *mutex)
void sys_mutex_lock( sys_mutex_t *pxMutex )
{
while( xSemaphoreTake( *mutex, portMAX_DELAY ) != pdPASS );
while( xSemaphoreTake( *pxMutex, portMAX_DELAY ) != pdPASS );
}
/** Unlock a mutex
* @param mutex the mutex to unlock */
void sys_mutex_unlock(sys_mutex_t *mutex)
void sys_mutex_unlock(sys_mutex_t *pxMutex )
{
xSemaphoreGive(*mutex);
xSemaphoreGive( *pxMutex );
}
/** Delete a semaphore
* @param mutex the mutex to delete */
void sys_mutex_free(sys_mutex_t *mutex)
void sys_mutex_free( sys_mutex_t *pxMutex )
{
#if SYS_STATS
SYS_STATS_DEC(mutex.used);
#endif /* SYS_STATS */
vQueueDelete(*mutex);
#if SYS_STATS
{
SYS_STATS_DEC( mutex.used );
}
#endif /* SYS_STATS */
vQueueDelete( *pxMutex );
}
@ -441,10 +439,9 @@ void sys_mutex_free(sys_mutex_t *mutex)
* Inputs:
* sys_sem_t sem -- Semaphore to signal
*---------------------------------------------------------------------------*/
void sys_sem_signal(sys_sem_t * sem)
void sys_sem_signal( sys_sem_t *pxSemaphore )
{
//LWIP_ASSERT( "sys_sem_signal: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );
xSemaphoreGive(*sem);
xSemaphoreGive( *pxSemaphore );
}
/*---------------------------------------------------------------------------*
@ -455,15 +452,15 @@ void sys_sem_signal(sys_sem_t * sem)
* Inputs:
* sys_sem_t sem -- Semaphore to free
*---------------------------------------------------------------------------*/
void sys_sem_free(sys_sem_t * sem)
void sys_sem_free( sys_sem_t *pxSemaphore )
{
//LWIP_ASSERT( "sys_sem_free: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );
#if SYS_STATS
SYS_STATS_DEC(sem.used);
#endif /* SYS_STATS */
#if SYS_STATS
{
SYS_STATS_DEC(sem.used);
}
#endif
vQueueDelete(*sem);
vQueueDelete( *pxSemaphore );
}
/*---------------------------------------------------------------------------*
@ -474,20 +471,6 @@ void sys_sem_free(sys_sem_t * sem)
*---------------------------------------------------------------------------*/
void sys_init(void)
{
#if 0
int i;
// Initialize the the per-thread sys_timeouts structures
// make sure there are no valid pids in the list
for (i = 0; i < SYS_THREAD_MAX; i++)
{
s_timeoutlist[i].pid = SYS_THREAD_NULL;
// s_timeoutlist[i].timeouts.next = NULL;
}
// keep track of how many threads have been created
s_nextthread = 0;
#endif
}
u32_t sys_now(void)
@ -495,52 +478,6 @@ u32_t sys_now(void)
return xTaskGetTickCount();
}
#if 0
_RB_
u32_t sys_jiffies(void)
{
return UEZTickCounterGet();
}
#endif
/*---------------------------------------------------------------------------*
* Routine: sys_arch_timeouts
*---------------------------------------------------------------------------*
* Description:
* Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
* each thread has a list of timeouts which is represented as a linked
* list of sys_timeout structures. The sys_timeouts structure holds a
* pointer to a linked list of timeouts. This function is called by
* the lwIP timeout scheduler and must not return a NULL value.
*
* In a single threaded sys_arch implementation, this function will
* simply return a pointer to a global sys_timeouts variable stored in
* the sys_arch module.
* Outputs:
* sys_timeouts * -- Pointer to per-thread timeouts.
*---------------------------------------------------------------------------*/
#if 0
struct sys_timeouts *sys_arch_timeouts(void)
{
int i;
T_uezTask pid;
struct timeoutlist *tl;
pid = UEZTaskGetCurrent();
for (i = 0; i < s_nextthread; i++)
{
tl = &(s_timeoutlist[i]);
if (tl->pid == pid)
{
// return &(tl->timeouts);
}
}
// Error
return NULL;
}
#endif
/*---------------------------------------------------------------------------*
* Routine: sys_thread_new
*---------------------------------------------------------------------------*
@ -559,21 +496,24 @@ struct sys_timeouts *sys_arch_timeouts(void)
* Outputs:
* sys_thread_t -- Pointer to per-thread timeouts.
*---------------------------------------------------------------------------*/
sys_thread_t sys_thread_new(const char *name, void(* thread)(void *arg), void *arg, int stacksize, int prio)
sys_thread_t sys_thread_new( const char *pcName, void( *pxThread )( void *pvParameters ), void *pvArg, int iStackSize, int iPriority )
{
xTaskHandle CreatedTask;
int result;
xTaskHandle xCreatedTask;
portBASE_TYPE xResult;
sys_thread_t xReturn;
result = xTaskCreate( thread, ( signed portCHAR * ) name, stacksize, arg, prio, &CreatedTask );
xResult = xTaskCreate( pxThread, ( signed char * ) pcName, iStackSize, pvArg, iPriority, &xCreatedTask );
if(result == pdPASS)
if( xResult == pdPASS )
{
return CreatedTask;
xReturn = xCreatedTask;
}
else
{
return NULL;
xReturn = NULL;
}
return xReturn;
}
/*---------------------------------------------------------------------------*
@ -595,10 +535,10 @@ int result;
* Outputs:
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
sys_prot_t sys_arch_protect(void)
sys_prot_t sys_arch_protect( void )
{
taskENTER_CRITICAL();
return 1;
return ( sys_prot_t ) 1;
}
/*---------------------------------------------------------------------------*
@ -612,18 +552,18 @@ sys_prot_t sys_arch_protect(void)
* Inputs:
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
void sys_arch_unprotect(sys_prot_t pval)
void sys_arch_unprotect( sys_prot_t xValue )
{
(void) pval;
(void) xValue;
taskEXIT_CRITICAL();
}
/*
* Prints an assertion messages and aborts execution.
*/
void sys_assert(const char *msg)
void sys_assert( const char *pcMessage )
{
(void) msg;
(void) pcMessage;
for (;;)
{

Loading…
Cancel
Save