河北水利局项目

This commit is contained in:
2025-12-15 16:07:49 +08:00
commit f11a7c2b95
1146 changed files with 452892 additions and 0 deletions

View File

@@ -0,0 +1,888 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* Standard library includes. */
#include <stdio.h>
#include <string.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
TaskHandle_t xEthIntTask;
/* lwIP includes. */
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "netif/etharp.h"
/* Hardware includes. */
#include "fec.h"
/* Delay to wait for a DMA buffer to become available if one is not already
available. */
#define netifBUFFER_WAIT_ATTEMPTS 10
#define netifBUFFER_WAIT_DELAY (10 / portTICK_PERIOD_MS)
/* Delay between polling the PHY to see if a link has been established. */
#define netifLINK_DELAY ( 500 / portTICK_PERIOD_MS )
/* Delay between looking for incoming packets. In ideal world this would be
infinite. */
#define netifBLOCK_TIME_WAITING_FOR_INPUT netifLINK_DELAY
/* Name for the netif. */
#define IFNAME0 'e'
#define IFNAME1 'n'
/* Hardware specific. */
#define netifFIRST_FEC_VECTOR 23
/*-----------------------------------------------------------*/
/* The DMA descriptors. This is a char array to allow us to align it correctly. */
static unsigned char xFECTxDescriptors_unaligned[ ( configNUM_FEC_TX_BUFFERS * sizeof( FECBD ) ) + 16 ];
static unsigned char xFECRxDescriptors_unaligned[ ( configNUM_FEC_RX_BUFFERS * sizeof( FECBD ) ) + 16 ];
static FECBD *xFECTxDescriptors;
static FECBD *xFECRxDescriptors;
/* The DMA buffers. These are char arrays to allow them to be alligned correctly. */
static unsigned char ucFECTxBuffers[ ( configNUM_FEC_TX_BUFFERS * configFEC_BUFFER_SIZE ) + 16 ];
static unsigned char ucFECRxBuffers[ ( configNUM_FEC_RX_BUFFERS * configFEC_BUFFER_SIZE ) + 16 ];
static unsigned portBASE_TYPE uxNextRxBuffer = 0, uxNextTxBuffer = 0;
/* Semaphore used by the FEC interrupt handler to wake the handler task. */
static SemaphoreHandle_t xFecSemaphore;
#pragma options align= packed
struct ethernetif
{
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
};
/*-----------------------------------------------------------*/
/* Standard lwIP netif handlers. */
static void prvInitialiseFECBuffers( void );
static void low_level_init( struct netif *netif );
static err_t low_level_output(struct netif *netif, struct pbuf *p);
static struct pbuf *low_level_input(struct netif *netif);
static void ethernetif_input( void *pParams );
/* Functions adapted from Freescale provided code. */
static int fec_mii_write( int phy_addr, int reg_addr, int data );
static int fec_mii_read( int phy_addr, int reg_addr, uint16* data );
static uint8 fec_hash_address( const uint8* addr );
static void fec_set_address( const uint8 *pa );
static void fec_irq_enable( void );
/*-----------------------------------------------------------*/
/********************************************************************/
/*
* Write a value to a PHY's MII register.
*
* Parameters:
* ch FEC channel
* phy_addr Address of the PHY.
* reg_addr Address of the register in the PHY.
* data Data to be written to the PHY register.
*
* Return Values:
* 0 on failure
* 1 on success.
*
* Please refer to your PHY manual for registers and their meanings.
* mii_write() polls for the FEC's MII interrupt event and clears it.
* If after a suitable amount of time the event isn't triggered, a
* value of 0 is returned.
*/
static int fec_mii_write( int phy_addr, int reg_addr, int data )
{
int timeout;
uint32 eimr;
/* Clear the MII interrupt bit */
MCF_FEC_EIR = MCF_FEC_EIR_MII;
/* Mask the MII interrupt */
eimr = MCF_FEC_EIMR;
MCF_FEC_EIMR &= ~MCF_FEC_EIMR_MII;
/* Write to the MII Management Frame Register to kick-off the MII write */
MCF_FEC_MMFR = MCF_FEC_MMFR_ST_01 | MCF_FEC_MMFR_OP_WRITE | MCF_FEC_MMFR_PA(phy_addr) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10 | MCF_FEC_MMFR_DATA( data );
/* Poll for the MII interrupt (interrupt should be masked) */
for (timeout = 0; timeout < MII_TIMEOUT; timeout++)
{
if (MCF_FEC_EIR & MCF_FEC_EIR_MII)
{
break;
}
}
if( timeout == MII_TIMEOUT )
{
return 0;
}
/* Clear the MII interrupt bit */
MCF_FEC_EIR = MCF_FEC_EIR_MII;
/* Restore the EIMR */
MCF_FEC_EIMR = eimr;
return 1;
}
/********************************************************************/
/*
* Read a value from a PHY's MII register.
*
* Parameters:
* ch FEC channel
* phy_addr Address of the PHY.
* reg_addr Address of the register in the PHY.
* data Pointer to storage for the Data to be read
* from the PHY register (passed by reference)
*
* Return Values:
* 0 on failure
* 1 on success.
*
* Please refer to your PHY manual for registers and their meanings.
* mii_read() polls for the FEC's MII interrupt event and clears it.
* If after a suitable amount of time the event isn't triggered, a
* value of 0 is returned.
*/
static int fec_mii_read( int phy_addr, int reg_addr, uint16* data )
{
int timeout;
uint32 eimr;
/* Clear the MII interrupt bit */
MCF_FEC_EIR = MCF_FEC_EIR_MII;
/* Mask the MII interrupt */
eimr = MCF_FEC_EIMR;
MCF_FEC_EIMR &= ~MCF_FEC_EIMR_MII;
/* Write to the MII Management Frame Register to kick-off the MII read */
MCF_FEC_MMFR = MCF_FEC_MMFR_ST_01 | MCF_FEC_MMFR_OP_READ | MCF_FEC_MMFR_PA(phy_addr) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10;
/* Poll for the MII interrupt (interrupt should be masked) */
for (timeout = 0; timeout < MII_TIMEOUT; timeout++)
{
if (MCF_FEC_EIR & MCF_FEC_EIR_MII)
{
break;
}
}
if(timeout == MII_TIMEOUT)
{
return 0;
}
/* Clear the MII interrupt bit */
MCF_FEC_EIR = MCF_FEC_EIR_MII;
/* Restore the EIMR */
MCF_FEC_EIMR = eimr;
*data = (uint16)(MCF_FEC_MMFR & 0x0000FFFF);
return 1;
}
/********************************************************************/
/*
* Generate the hash table settings for the given address
*
* Parameters:
* addr 48-bit (6 byte) Address to generate the hash for
*
* Return Value:
* The 6 most significant bits of the 32-bit CRC result
*/
static uint8 fec_hash_address( const uint8* addr )
{
uint32 crc;
uint8 byte;
int i, j;
crc = 0xFFFFFFFF;
for(i=0; i<6; ++i)
{
byte = addr[i];
for(j=0; j<8; ++j)
{
if((byte & 0x01)^(crc & 0x01))
{
crc >>= 1;
crc = crc ^ 0xEDB88320;
}
else
{
crc >>= 1;
}
byte >>= 1;
}
}
return (uint8)(crc >> 26);
}
/********************************************************************/
/*
* Set the Physical (Hardware) Address and the Individual Address
* Hash in the selected FEC
*
* Parameters:
* ch FEC channel
* pa Physical (Hardware) Address for the selected FEC
*/
static void fec_set_address( const uint8 *pa )
{
uint8 crc;
/*
* Set the Physical Address
*/
MCF_FEC_PALR = (uint32)((pa[0]<<24) | (pa[1]<<16) | (pa[2]<<8) | pa[3]);
MCF_FEC_PAUR = (uint32)((pa[4]<<24) | (pa[5]<<16));
/*
* Calculate and set the hash for given Physical Address
* in the Individual Address Hash registers
*/
crc = fec_hash_address(pa);
if(crc >= 32)
{
MCF_FEC_IAUR |= (uint32)(1 << (crc - 32));
}
else
{
MCF_FEC_IALR |= (uint32)(1 << crc);
}
}
/********************************************************************/
/*
* Enable interrupts on the selected FEC
*
*/
static void fec_irq_enable( void )
{
int fec_vbase;
#if INTC_LVL_FEC > configMAX_SYSCALL_INTERRUPT_PRIORITY
#error INTC_LVL_FEC must be less than or equal to configMAX_SYSCALL_INTERRUPT_PRIORITY
#endif
fec_vbase = 64 + netifFIRST_FEC_VECTOR;
/* Enable FEC interrupts to the ColdFire core
* Setup each ICR with a unique interrupt level combination */
fec_vbase -= 64;
/* FEC Rx Frame */
MCF_INTC0_ICR(fec_vbase+4) = MCF_INTC_ICR_IL(INTC_LVL_FEC);
/* FEC Rx Buffer */
MCF_INTC0_ICR(fec_vbase+5) = MCF_INTC_ICR_IL(INTC_LVL_FEC);
/* FEC FIFO Underrun */
MCF_INTC0_ICR(fec_vbase+2) = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);
/* FEC Collision Retry Limit */
MCF_INTC0_ICR(fec_vbase+3) = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);
/* FEC Late Collision */
MCF_INTC0_ICR(fec_vbase+7) = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);
/* FEC Heartbeat Error */
MCF_INTC0_ICR(fec_vbase+8) = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);
/* FEC Bus Error */
MCF_INTC0_ICR(fec_vbase+10) = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);
/* FEC Babbling Transmit */
MCF_INTC0_ICR(fec_vbase+11) = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);
/* FEC Babbling Receive */
MCF_INTC0_ICR(fec_vbase+12) = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);
/* Enable the FEC interrupts in the mask register */
MCF_INTC0_IMRH &= ~( MCF_INTC_IMRH_INT_MASK33 | MCF_INTC_IMRH_INT_MASK34 | MCF_INTC_IMRH_INT_MASK35 );
MCF_INTC0_IMRL &= ~( MCF_INTC_IMRL_INT_MASK25 | MCF_INTC_IMRL_INT_MASK26 | MCF_INTC_IMRL_INT_MASK27 | MCF_INTC_IMRL_INT_MASK28 | MCF_INTC_IMRL_INT_MASK29 | MCF_INTC_IMRL_INT_MASK30 | MCF_INTC_IMRL_INT_MASK31 | MCF_INTC_IMRL_MASKALL );
/* Clear any pending FEC interrupt events */
MCF_FEC_EIR = MCF_FEC_EIR_CLEAR_ALL;
/* Unmask all FEC interrupts */
MCF_FEC_EIMR = MCF_FEC_EIMR_UNMASK_ALL;
}
/**
* In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param netif the already initialized lwip network interface structure
* for this ethernetif
*/
static void low_level_init( struct netif *netif )
{
unsigned short usData;
const unsigned char ucMACAddress[6] =
{
configMAC_0, configMAC_1,configMAC_2,configMAC_3,configMAC_4,configMAC_5
};
prvInitialiseFECBuffers();
vSemaphoreCreateBinary( xFecSemaphore );
for( usData = 0; usData < 6; usData++ )
{
netif->hwaddr[ usData ] = ucMACAddress[ usData ];
}
/* Set the Reset bit and clear the Enable bit */
MCF_FEC_ECR = MCF_FEC_ECR_RESET;
/* Wait at least 8 clock cycles */
for( usData = 0; usData < 10; usData++ )
{
asm( "NOP" );
}
/* Set MII speed to 2.5MHz. */
MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED( ( ( configCPU_CLOCK_HZ / 1000000 ) / 5 ) + 1 );
/*
* Make sure the external interface signals are enabled
*/
MCF_GPIO_PNQPAR = MCF_GPIO_PNQPAR_IRQ3_FEC_MDIO | MCF_GPIO_PNQPAR_IRQ5_FEC_MDC;
MCF_GPIO_PTIPAR = MCF_GPIO_PTIPAR_FEC_COL_FEC_COL
| MCF_GPIO_PTIPAR_FEC_CRS_FEC_CRS
| MCF_GPIO_PTIPAR_FEC_RXCLK_FEC_RXCLK
| MCF_GPIO_PTIPAR_FEC_RXD0_FEC_RXD0
| MCF_GPIO_PTIPAR_FEC_RXD1_FEC_RXD1
| MCF_GPIO_PTIPAR_FEC_RXD2_FEC_RXD2
| MCF_GPIO_PTIPAR_FEC_RXD3_FEC_RXD3
| MCF_GPIO_PTIPAR_FEC_RXDV_FEC_RXDV;
MCF_GPIO_PTJPAR = MCF_GPIO_PTJPAR_FEC_RXER_FEC_RXER
| MCF_GPIO_PTJPAR_FEC_TXCLK_FEC_TXCLK
| MCF_GPIO_PTJPAR_FEC_TXD0_FEC_TXD0
| MCF_GPIO_PTJPAR_FEC_TXD1_FEC_TXD1
| MCF_GPIO_PTJPAR_FEC_TXD2_FEC_TXD2
| MCF_GPIO_PTJPAR_FEC_TXD3_FEC_TXD3
| MCF_GPIO_PTJPAR_FEC_TXEN_FEC_TXEN
| MCF_GPIO_PTJPAR_FEC_TXER_FEC_TXER;
/* Can we talk to the PHY? */
do
{
vTaskDelay( netifLINK_DELAY );
usData = 0;
fec_mii_read( configPHY_ADDRESS, PHY_PHYIDR1, &usData );
} while( ( usData == 0xffff ) || ( usData == 0 ) );
/* Start auto negotiate. */
fec_mii_write( configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) );
/* Wait for auto negotiate to complete. */
do
{
vTaskDelay( netifLINK_DELAY );
fec_mii_read( configPHY_ADDRESS, PHY_BMSR, &usData );
} while( !( usData & PHY_BMSR_AN_COMPLETE ) );
/* When we get here we have a link - find out what has been negotiated. */
fec_mii_read( configPHY_ADDRESS, PHY_ANLPAR, &usData );
if( ( usData & PHY_ANLPAR_100BTX_FDX ) || ( usData & PHY_ANLPAR_100BTX ) )
{
/* Speed is 100. */
}
else
{
/* Speed is 10. */
}
if( ( usData & PHY_ANLPAR_100BTX_FDX ) || ( usData & PHY_ANLPAR_10BTX_FDX ) )
{
/* Full duplex. */
MCF_FEC_RCR &= (uint32)~MCF_FEC_RCR_DRT;
MCF_FEC_TCR |= MCF_FEC_TCR_FDEN;
}
else
{
MCF_FEC_RCR |= MCF_FEC_RCR_DRT;
MCF_FEC_TCR &= (uint32)~MCF_FEC_TCR_FDEN;
}
/* Clear the Individual and Group Address Hash registers */
MCF_FEC_IALR = 0;
MCF_FEC_IAUR = 0;
MCF_FEC_GALR = 0;
MCF_FEC_GAUR = 0;
/* Set the Physical Address for the selected FEC */
fec_set_address( ucMACAddress );
/* Set Rx Buffer Size */
MCF_FEC_EMRBR = (uint16)configFEC_BUFFER_SIZE;
/* Point to the start of the circular Rx buffer descriptor queue */
MCF_FEC_ERDSR = ( volatile unsigned long ) &( xFECRxDescriptors[ 0 ] );
/* Point to the start of the circular Tx buffer descriptor queue */
MCF_FEC_ETSDR = ( volatile unsigned long ) &( xFECTxDescriptors[ 0 ] );
/* Mask all FEC interrupts */
MCF_FEC_EIMR = MCF_FEC_EIMR_MASK_ALL;
/* Clear all FEC interrupt events */
MCF_FEC_EIR = MCF_FEC_EIR_CLEAR_ALL;
/* Initialize the Receive Control Register */
MCF_FEC_RCR = MCF_FEC_RCR_MAX_FL(ETH_MAX_FRM) | MCF_FEC_RCR_FCE;
MCF_FEC_RCR |= MCF_FEC_RCR_MII_MODE;
#if( configUSE_PROMISCUOUS_MODE == 1 )
{
MCF_FEC_RCR |= MCF_FEC_RCR_PROM;
}
#endif
/* Create the task that handles the EMAC. */
xTaskCreate( ethernetif_input, "ETH_INT", configETHERNET_INPUT_TASK_STACK_SIZE, (void *)netif, configETHERNET_INPUT_TASK_PRIORITY, &xEthIntTask );
fec_irq_enable();
MCF_FEC_ECR = MCF_FEC_ECR_ETHER_EN;
MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
}
/**
* This function should do the actual transmission of the packet. The packet is
* 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 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
*
* @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).
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
u32_t l = 0;
unsigned char *pcTxData = NULL;
portBASE_TYPE i;
( void ) netif;
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
/* Get a DMA buffer into which we can write the data to send. */
for( i = 0; i < netifBUFFER_WAIT_ATTEMPTS; i++ )
{
if( xFECTxDescriptors[ uxNextTxBuffer ].status & TX_BD_R )
{
/* Wait for the buffer to become available. */
vTaskDelay( netifBUFFER_WAIT_DELAY );
}
else
{
pcTxData = xFECTxDescriptors[ uxNextTxBuffer ].data;
break;
}
}
if( pcTxData == NULL )
{
/* For break point only. */
portNOP();
return ERR_BUF;
}
else
{
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. */
memcpy( &pcTxData[l], (u8_t*)q->payload, q->len );
l += q->len;
}
}
/* Setup the buffer descriptor for transmission */
xFECTxDescriptors[ uxNextTxBuffer ].length = l;//nbuf->length + ETH_HDR_LEN;
xFECTxDescriptors[ uxNextTxBuffer ].status |= (TX_BD_R | TX_BD_L);
/* Continue the Tx DMA task (in case it was waiting for a new TxBD) */
MCF_FEC_TDAR = MCF_FEC_TDAR_X_DES_ACTIVE;
uxNextTxBuffer++;
if( uxNextTxBuffer >= configNUM_FEC_TX_BUFFERS )
{
uxNextTxBuffer = 0;
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.xmit);
return ERR_OK;
}
/**
* 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
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf *low_level_input(struct netif *netif)
{
struct pbuf *p, *q;
u16_t len, l;
( void ) netif;
l = 0;
p = NULL;
/* Obtain the size of the packet and put it into the "len" variable. */
len = xFECRxDescriptors[ uxNextRxBuffer ].length;
if( ( len != 0 ) && ( ( xFECRxDescriptors[ uxNextRxBuffer ].status & RX_BD_E ) == 0 ) )
{
#if ETH_PAD_SIZE
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p != NULL)
{
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
/* We iterate over the pbuf chain until we have read the entire
* packet into the pbuf. */
for(q = p; q != NULL; q = q->next)
{
/* Read enough bytes to fill this pbuf in the chain. The
* available data in the pbuf is given by the q->len
* variable. */
memcpy((u8_t*)q->payload, &(xFECRxDescriptors[ uxNextRxBuffer ].data[l]), q->len);
l = l + q->len;
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.recv);
}
else
{
LINK_STATS_INC(link.memerr);
LINK_STATS_INC(link.drop);
} /* End else */
/* Free the descriptor. */
xFECRxDescriptors[ uxNextRxBuffer ].status |= RX_BD_E;
MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
uxNextRxBuffer++;
if( uxNextRxBuffer >= configNUM_FEC_RX_BUFFERS )
{
uxNextRxBuffer = 0;
}
} /* End if */
return p;
}
/**
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() 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
*/
static void ethernetif_input( void *pParams )
{
struct netif *netif;
struct ethernetif *ethernetif;
struct eth_hdr *ethhdr;
struct pbuf *p;
netif = (struct netif*) pParams;
ethernetif = netif->state;
for( ;; )
{
do
{
/* move received packet into a new pbuf */
p = low_level_input( netif );
if( p == NULL )
{
/* No packet could be read. Wait a for an interrupt to tell us
there is more data available. */
xSemaphoreTake( xFecSemaphore, netifBLOCK_TIME_WAITING_FOR_INPUT );
}
} while( p == NULL );
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
switch (htons(ethhdr->type)) {
/* IP or ARP packet? */
case ETHTYPE_IP:
pbuf_header( p, (s16_t)-sizeof(struct eth_hdr) );
/* full packet send to tcpip_thread to process */
if (netif->input(p, netif) != ERR_OK)
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
p = NULL;
}
break;
case ETHTYPE_ARP:
#if ETHARP_TRUST_IP_MAC
etharp_ip_input(netif, p);
#endif
etharp_arp_input(netif, ethernetif->ethaddr, p);
break;
default:
pbuf_free(p);
p = NULL;
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
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t ethernetif_init(struct netif *netif)
{
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 */
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100);
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->linkoutput = low_level_output;
ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
low_level_init(netif);
return ERR_OK;
}
/*-----------------------------------------------------------*/
static void prvInitialiseFECBuffers( void )
{
unsigned portBASE_TYPE ux;
unsigned char *pcBufPointer;
pcBufPointer = &( xFECTxDescriptors_unaligned[ 0 ] );
while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 )
{
pcBufPointer++;
}
xFECTxDescriptors = ( FECBD * ) pcBufPointer;
pcBufPointer = &( xFECRxDescriptors_unaligned[ 0 ] );
while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 )
{
pcBufPointer++;
}
xFECRxDescriptors = ( FECBD * ) pcBufPointer;
/* Setup the buffers and descriptors. */
pcBufPointer = &( ucFECTxBuffers[ 0 ] );
while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 )
{
pcBufPointer++;
}
for( ux = 0; ux < configNUM_FEC_TX_BUFFERS; ux++ )
{
xFECTxDescriptors[ ux ].status = TX_BD_TC;
xFECTxDescriptors[ ux ].data = pcBufPointer;
pcBufPointer += configFEC_BUFFER_SIZE;
xFECTxDescriptors[ ux ].length = 0;
}
pcBufPointer = &( ucFECRxBuffers[ 0 ] );
while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 )
{
pcBufPointer++;
}
for( ux = 0; ux < configNUM_FEC_RX_BUFFERS; ux++ )
{
xFECRxDescriptors[ ux ].status = RX_BD_E;
xFECRxDescriptors[ ux ].length = configFEC_BUFFER_SIZE;
xFECRxDescriptors[ ux ].data = pcBufPointer;
pcBufPointer += configFEC_BUFFER_SIZE;
}
/* Set the wrap bit in the last descriptors to form a ring. */
xFECTxDescriptors[ configNUM_FEC_TX_BUFFERS - 1 ].status |= TX_BD_W;
xFECRxDescriptors[ configNUM_FEC_RX_BUFFERS - 1 ].status |= RX_BD_W;
uxNextRxBuffer = 0;
uxNextTxBuffer = 0;
}
/*-----------------------------------------------------------*/
__declspec(interrupt:0) void vFECISRHandler( void )
{
unsigned long ulEvent;
portBASE_TYPE xHighPriorityTaskWoken = pdFALSE;
ulEvent = MCF_FEC_EIR & MCF_FEC_EIMR;
MCF_FEC_EIR = ulEvent;
if( ( ulEvent & MCF_FEC_EIR_RXB ) || ( ulEvent & MCF_FEC_EIR_RXF ) )
{
/* A packet has been received. Wake the handler task. */
xSemaphoreGiveFromISR( xFecSemaphore, &xHighPriorityTaskWoken );
}
if (ulEvent & ( MCF_FEC_EIR_UN | MCF_FEC_EIR_RL | MCF_FEC_EIR_LC | MCF_FEC_EIR_EBERR | MCF_FEC_EIR_BABT | MCF_FEC_EIR_BABR | MCF_FEC_EIR_HBERR ) )
{
/* Sledge hammer error handling. */
prvInitialiseFECBuffers();
MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
}
portEND_SWITCHING_ISR( xHighPriorityTaskWoken );
}

View File

@@ -0,0 +1,571 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Modifications Copyright (c) 2006 Christian Walter <wolti@sil.at>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
* Modifcations: Christian Walter <wolti@sil.at>
*
* $Id: sys_arch.c,v 1.1 2008/08/05 00:10:49 b06862 Exp $
*/
/* ------------------------ System includes ------------------------------- */
#include "stdlib.h"
/* ------------------------ FreeRTOS includes ----------------------------- */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* ------------------------ lwIP includes --------------------------------- */
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/sio.h"
#include "lwip/stats.h"
/* ------------------------ Project includes ------------------------------ */
/* ------------------------ Defines --------------------------------------- */
/* This is the number of threads that can be started with sys_thead_new() */
#define SYS_MBOX_SIZE ( 16 )
#define MS_TO_TICKS( ms ) \
( TickType_t )( ( TickType_t ) ( ms ) / portTICK_PERIOD_MS )
#define TICKS_TO_MS( ticks ) \
( unsigned long )( ( TickType_t ) ( ticks ) * portTICK_PERIOD_MS )
#define THREAD_STACK_SIZE ( 256 /*FSL:1024*/ )
#define THREAD_NAME "lwIP"
#define THREAD_INIT( tcb ) \
do { \
tcb->next = NULL; \
tcb->pid = ( TaskHandle_t )0; \
tcb->timeouts.next = NULL; \
} while( 0 )
/* ------------------------ Type definitions ------------------------------ */
typedef struct sys_tcb
{
struct sys_tcb *next;
struct sys_timeouts timeouts;
TaskHandle_t pid;
} sys_tcb_t;
/* ------------------------ Prototypes ------------------------------------ */
/* ------------------------ Static functions ------------------------------ */
sys_tcb_t *sys_thread_current( void );
/* ------------------------ Static variables ------------------------------ */
static sys_tcb_t *tasks = NULL;
/* ------------------------ Start implementation -------------------------- */
void
sys_init( void )
{
LWIP_ASSERT( "sys_init: not called first", tasks == NULL );
tasks = NULL;
}
/*
* This optional function does a "fast" critical region protection and returns
* the previous protection level. This function is only called during very short
* critical regions. An embedded system which supports ISR-based drivers might
* want to implement this function by disabling interrupts. Task-based systems
* might want to implement this by using a mutex or disabling tasking. This
* function should support recursive calls from the same task or interrupt. In
* other words, sys_arch_protect() could be called while already protected. In
* that case the return value indicates that it is already protected.
*
* sys_arch_protect() is only required if your port is supporting an operating
* system.
*/
sys_prot_t
sys_arch_protect( void )
{
vPortEnterCritical( );
return 1;
}
/*
* This optional function does a "fast" set of critical region protection to the
* value specified by pval. See the documentation for sys_arch_protect() for
* more information. This function is only required if your port is supporting
* an operating system.
*/
void
sys_arch_unprotect( sys_prot_t pval )
{
( void )pval;
vPortExitCritical( );
}
/*
* Prints an assertion messages and aborts execution.
*/
void
sys_assert( const char *msg )
{
/*FSL:only needed for debugging
printf(msg);
printf("\n\r");
*/
vPortEnterCritical( );
for(;;)
;
}
void
sys_debug( const char *const fmt, ... )
{
/*FSL: same implementation as printf*/
/*FSL: removed due to lack of space*/
//printf(fmt);
}
/* ------------------------ Start implementation ( Threads ) -------------- */
/*
* Starts a new thread with priority "prio" that will begin its execution in the
* function "thread()". The "arg" argument will be passed as an argument to the
* thread() function. The argument "ssize" is the requested stack size for the
* new thread. The id of the new thread is returned. Both the id and the
* priority are system dependent.
*/
sys_thread_t
sys_thread_new(char *name, void ( *thread ) ( void *arg ), void *arg, int /*size_t*/ stacksize, int prio )
{
sys_thread_t thread_hdl = SYS_THREAD_NULL;
int i;
sys_tcb_t *p;
/* We disable the FreeRTOS scheduler because it might be the case that the new
* tasks gets scheduled inside the xTaskCreate function. To prevent this we
* disable the scheduling. Note that this can happen although we have interrupts
* disabled because xTaskCreate contains a call to taskYIELD( ).
*/
vPortEnterCritical( );
p = tasks;
i = 0;
/* We are called the first time. Initialize it. */
if( p == NULL )
{
p = (sys_tcb_t *)pvPortMalloc( sizeof( sys_tcb_t ) );
if( p != NULL )
{
tasks = p;
}
}
else
{
/* First task already counter. */
i++;
/* Cycle to the end of the list. */
while( p->next != NULL )
{
i++;
p = p->next;
}
p->next = (sys_tcb_t *)pvPortMalloc( sizeof( sys_tcb_t ) );
p = p->next;
}
if( p != NULL )
{
/* Memory allocated. Initialize the data structure. */
THREAD_INIT( p );
/* Now q points to a free element in the list. */
if( xTaskCreate( thread, name, stacksize, arg, prio, &p->pid ) == pdPASS )
{
thread_hdl = p;
}
else
{
vPortFree( p );
}
}
vPortExitCritical( );
return thread_hdl;
}
void
sys_arch_thread_remove( sys_thread_t hdl )
{
sys_tcb_t *current = tasks, *prev;
sys_tcb_t *toremove = hdl;
TaskHandle_t pid = ( TaskHandle_t ) 0;
LWIP_ASSERT( "sys_arch_thread_remove: assertion hdl != NULL failed!", hdl != NULL );
/* If we have to remove the first task we must update the global "tasks"
* variable. */
vPortEnterCritical( );
if( hdl != NULL )
{
prev = NULL;
while( ( current != NULL ) && ( current != toremove ) )
{
prev = current;
current = current->next;
}
/* Found it. */
if( current == toremove )
{
/* Not the first entry in the list. */
if( prev != NULL )
{
prev->next = toremove->next;
}
else
{
tasks = toremove->next;
}
LWIP_ASSERT( "sys_arch_thread_remove: can't remove thread with timeouts!",
toremove->timeouts.next == NULL );
pid = toremove->pid;
THREAD_INIT( toremove );
vPortFree( toremove );
}
}
/* We are done with accessing the shared datastructure. Release the
* resources.
*/
vPortExitCritical( );
if( pid != ( TaskHandle_t ) 0 )
{
vTaskDelete( pid );
/* not reached. */
}
}
/*
* Returns the thread control block for the currently active task. In case
* of an error the functions returns NULL.
*/
sys_thread_t
sys_arch_thread_current( void )
{
sys_tcb_t *p = tasks;
TaskHandle_t pid = xTaskGetCurrentTaskHandle( );
vPortEnterCritical( );
while( ( p != NULL ) && ( p->pid != pid ) )
{
p = p->next;
}
vPortExitCritical( );
return p;
}
/*
* 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.
*/
struct sys_timeouts *
sys_arch_timeouts( void )
{
sys_tcb_t *ptask;
ptask = sys_arch_thread_current( );
LWIP_ASSERT( "sys_arch_timeouts: ptask != NULL", ptask != NULL );
return ptask != NULL ? &( ptask->timeouts ) : NULL;
}
/* ------------------------ Start implementation ( Semaphores ) ----------- */
/* Creates and returns a new semaphore. The "count" argument specifies
* the initial state of the semaphore.
*/
sys_sem_t
sys_sem_new( u8_t count )
{
SemaphoreHandle_t xSemaphore;
vSemaphoreCreateBinary( xSemaphore );
if( xSemaphore != SYS_SEM_NULL )
{
if( count == 0 )
{
xSemaphoreTake( xSemaphore, 1 );
}
#if SYS_STATS == 1
vPortEnterCritical( );
lwip_stats.sys.sem.used++;
if( lwip_stats.sys.sem.used > lwip_stats.sys.sem.max )
{
lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
}
vPortExitCritical( );
#endif
}
else
{
LWIP_ASSERT( "sys_sem_new: xSemaphore == SYS_SEM_NULL", xSemaphore != SYS_SEM_NULL );
}
return xSemaphore;
}
/* Deallocates a semaphore */
void
sys_sem_free( sys_sem_t sem )
{
LWIP_ASSERT( "sys_sem_free: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );
if( sem != SYS_SEM_NULL )
{
#if SYS_STATS == 1
vPortEnterCritical( );
lwip_stats.sys.sem.used--;
vPortExitCritical( );
#endif
vQueueDelete( sem );
}
}
/* Signals a semaphore */
void
sys_sem_signal( sys_sem_t sem )
{
LWIP_ASSERT( "sys_sem_signal: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );
xSemaphoreGive( sem );
}
/*
* Blocks the thread while waiting for the semaphore to be
* signaled. If the "timeout" argument is non-zero, the thread should
* only be blocked for the specified time (measured in
* milliseconds).
*
* If the timeout argument is non-zero, the return value is the number of
* milliseconds spent waiting for the semaphore to be signaled. If the
* semaphore wasn't signaled within the specified time, the return value is
* SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
* (i.e., it was already signaled), the function may return zero.
*
* Notice that lwIP implements a function with a similar name,
* sys_sem_wait(), that uses the sys_arch_sem_wait() function.
*/
u32_t
sys_arch_sem_wait( sys_sem_t sem, u32_t timeout )
{
portBASE_TYPE xStatus;
TickType_t xTicksStart, xTicksEnd, xTicksElapsed;
u32_t timespent;
LWIP_ASSERT( "sys_arch_sem_wait: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );
xTicksStart = xTaskGetTickCount( );
if( timeout == 0 )
{
do
{
xStatus = xSemaphoreTake( sem, MS_TO_TICKS( 100 ) );
}
while( xStatus != pdTRUE );
}
else
{
xStatus = xSemaphoreTake( sem, MS_TO_TICKS( timeout ) );
}
/* Semaphore was signaled. */
if( xStatus == pdTRUE )
{
xTicksEnd = xTaskGetTickCount( );
xTicksElapsed = xTicksEnd - xTicksStart;
timespent = TICKS_TO_MS( xTicksElapsed );
}
else
{
timespent = SYS_ARCH_TIMEOUT;
}
return timespent;
}
/* ------------------------ Start implementation ( Mailboxes ) ------------ */
/* Creates an empty mailbox. */
sys_mbox_t
sys_mbox_new( /*paolo:void*/int size )
{
QueueHandle_t mbox;
mbox = xQueueCreate( SYS_MBOX_SIZE/*size*/, sizeof( void * ) );
if( mbox != SYS_MBOX_NULL )
{
#if SYS_STATS == 1
vPortEnterCritical( );
lwip_stats.sys.mbox.used++;
if( lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max )
{
lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
}
vPortExitCritical( );
#endif
}
return mbox;
}
/*
Deallocates a mailbox. If there are messages still present in the
mailbox when the mailbox is deallocated, it is an indication of a
programming error in lwIP and the developer should be notified.
*/
void
sys_mbox_free( sys_mbox_t mbox )
{
void *msg;
LWIP_ASSERT( "sys_mbox_free: mbox != SYS_MBOX_NULL", mbox != SYS_MBOX_NULL );
if( mbox != SYS_MBOX_NULL )
{
while( uxQueueMessagesWaiting( mbox ) != 0 )
{
if( sys_arch_mbox_fetch( mbox, &msg, 1 ) != SYS_ARCH_TIMEOUT )
{
LWIP_ASSERT( "sys_mbox_free: memory leak (msg != NULL)", msg == NULL );
}
}
vQueueDelete( mbox );
#if SYS_STATS == 1
vPortEnterCritical( );
lwip_stats.sys.mbox.used--;
vPortExitCritical( );
#endif
}
}
/*
* This function sends a message to a mailbox. It is unusual in that no error
* return is made. This is because the caller is responsible for ensuring that
* the mailbox queue will not fail. The caller does this by limiting the number
* of msg structures which exist for a given mailbox.
*/
void
sys_mbox_post( sys_mbox_t mbox, void *data )
{
portBASE_TYPE xQueueSent;
/* Queue must not be full - Otherwise it is an error. */
xQueueSent = xQueueSend( mbox, &data, 0 );
LWIP_ASSERT( "sys_mbox_post: xQueueSent == pdPASS", xQueueSent == pdPASS );
}
/*FSL*/
/*
*Try to post the "msg" to the mailbox. Returns ERR_MEM if this one
*is full, else, ERR_OK if the "msg" is posted.
*/
err_t
sys_mbox_trypost( sys_mbox_t mbox, void *data )
{
/* Queue must not be full - Otherwise it is an error. */
if(xQueueSend( mbox, &data, 0 ) == pdPASS)
{
return ERR_OK;
}
else
{
return ERR_MEM;
}
}
/*
* Blocks the thread until a message arrives in the mailbox, but does
* not block the thread longer than "timeout" milliseconds (similar to
* the sys_arch_sem_wait() function). The "msg" argument is a result
* parameter that is set by the function (i.e., by doing "*msg =
* ptr"). The "msg" parameter maybe NULL to indicate that the message
* should be dropped.
*
* Note that a function with a similar name, sys_mbox_fetch(), is
* implemented by lwIP.
*/
u32_t
sys_arch_mbox_fetch( sys_mbox_t mbox, void **msg, u32_t timeout )
{
void *ret_msg;
portBASE_TYPE xStatus;
TickType_t xTicksStart, xTicksEnd, xTicksElapsed;
u32_t timespent;
LWIP_ASSERT( "sys_arch_mbox_fetch: mbox != SYS_MBOX_NULL", mbox != SYS_MBOX_NULL );
xTicksStart = xTaskGetTickCount( );
if( timeout == 0 )
{
do
{
xStatus = xQueueReceive( mbox, &ret_msg, MS_TO_TICKS( 100 ) );
}
while( xStatus != pdTRUE );
}
else
{
xStatus = xQueueReceive( mbox, &ret_msg, MS_TO_TICKS( timeout ) );
}
if( xStatus == pdTRUE )
{
if( msg )
{
*msg = ret_msg;
}
xTicksEnd = xTaskGetTickCount( );
xTicksElapsed = xTicksEnd - xTicksStart;
timespent = TICKS_TO_MS( xTicksElapsed );
}
else
{
if( msg )
{
*msg = NULL;
}
timespent = SYS_ARCH_TIMEOUT;
}
return timespent;
}
u32_t
sys_jiffies( void )
{
TickType_t xTicks = xTaskGetTickCount( );
return ( u32_t )TICKS_TO_MS( xTicks );
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
* Modifcations: Christian Walter <wolti@sil.at>
*/
#ifndef __CC_H__
#define __CC_H__
/* ------------------------ System includes ------------------------------- */
/* ------------------------ Project includes ------------------------------ */
#include "cpu.h"
#include "sys_arch.h"
/* ------------------------ Defines --------------------------------------- */
//#pragma options align= packed
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT //non CW compatible: __attribute__ ((__packed__))
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD( x ) x
/*FSL: non used on code:
#define ALIGN_STRUCT_8_BEGIN
#define ALIGN_STRUCT_8 //non CW compatible: __attribute__ ((aligned (8)))
#define ALIGN_STRUCT_8_END
*/
#define LWIP_PLATFORM_ASSERT( x ) sys_assert( x )
#define LWIP_PLATFORM_DIAG( x, ... ) do{ sys_debug x; } while( 0 );
/* Define (sn)printf formatters for these lwIP types */
#define U16_F "hu"
#define S16_F "hd"
#define X16_F "hx"
#define U32_F "lu"
#define S32_F "ld"
#define X32_F "lx"
/* ------------------------ Type definitions (lwIP) ----------------------- */
typedef unsigned char u8_t;
typedef signed char s8_t;
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned long u32_t;
typedef signed long s32_t;
typedef u32_t mem_ptr_t;
typedef int sys_prot_t;
/* ------------------------ Prototypes ------------------------------------ */
#endif

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CPU_H__
#define __CPU_H__
/* ------------------------ Defines --------------------------------------- */
#define BYTE_ORDER BIG_ENDIAN
#endif

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PERF_H__
#define __PERF_H__
/* ------------------------ Defines --------------------------------------- */
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __SYS_RTXC_H__
#define __SYS_RTXC_H__
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#define SYS_MBOX_NULL (QueueHandle_t)0
#define SYS_SEM_NULL (SemaphoreHandle_t)0
typedef SemaphoreHandle_t sys_sem_t;
typedef QueueHandle_t sys_mbox_t;
typedef TaskHandle_t sys_thread_t;
/* Message queue constants. */
#define archMESG_QUEUE_LENGTH ( 6 )
#define archPOST_BLOCK_TIME_MS ( ( unsigned long ) 10000 )
#endif

View File

@@ -0,0 +1,55 @@
/*!
* \file eth.h
* \brief Definitinos for Ethernet Frames
* \version $Revision: 1.2 $
* \author Michael Norman
*/
#ifndef _ETH_H
#define _ETH_H
/*******************************************************************/
/* Ethernet standard lengths in bytes*/
#define ETH_ADDR_LEN (6)
#define ETH_TYPE_LEN (2)
#define ETH_CRC_LEN (4)
#define ETH_MAX_DATA (1500)
#define ETH_MIN_DATA (46)
#define ETH_HDR_LEN (ETH_ADDR_LEN * 2 + ETH_TYPE_LEN)
/* Defined Ethernet Frame Types */
#define ETH_FRM_IP (0x0800)
#define ETH_FRM_ARP (0x0806)
#define ETH_FRM_RARP (0x8035)
#define ETH_FRM_TEST (0xA5A5)
/* Maximum and Minimum Ethernet Frame Sizes */
#define ETH_MAX_FRM (ETH_HDR_LEN + ETH_MAX_DATA + ETH_CRC_LEN)
#define ETH_MIN_FRM (ETH_HDR_LEN + ETH_MIN_DATA + ETH_CRC_LEN)
#define ETH_MTU (ETH_HDR_LEN + ETH_MAX_DATA)
/* Ethernet Addresses */
typedef uint8 ETH_ADDR[ETH_ADDR_LEN];
/* 16-bit Ethernet Frame Type, ie. Protocol */
typedef uint16 ETH_FRM_TYPE;
/* Ethernet Frame Header definition */
typedef struct
{
ETH_ADDR dest;
ETH_ADDR src;
ETH_FRM_TYPE type;
} ETH_HDR;
/* Ethernet Frame definition */
typedef struct
{
ETH_HDR head;
uint8* data;
} ETH_FRAME;
/*******************************************************************/
#endif /* _ETH_H */

View File

@@ -0,0 +1,87 @@
/*!
* \file eth.h
* \brief Definitions for Ethernet Physical Layer Interface
* \version $Revision: 1.3 $
* \author Michael Norman
*/
#ifndef _ETH_PHY_H
#define _ETH_PHY_H
/*******************************************************************/
int
eth_phy_autoneg(int phy_addr, MII_SPEED speed, MII_DUPLEX duplex);
int
eth_phy_manual(int phy_addr, MII_SPEED speed, MII_DUPLEX duplex, int loop);
int
eth_phy_get_speed(int, int*);
int
eth_phy_get_duplex(int, int*);
int
eth_phy_reg_dump(int);
/*******************************************************************/
/* MII Register Addresses */
#define PHY_BMCR (0x00)
#define PHY_BMSR (0x01)
#define PHY_PHYIDR1 (0x02)
#define PHY_PHYIDR2 (0x03)
#define PHY_ANAR (0x04)
#define PHY_ANLPAR (0x05)
/* Bit definitions and macros for PHY_CTRL */
#define PHY_BMCR_RESET (0x8000)
#define PHY_BMCR_LOOP (0x4000)
#define PHY_BMCR_SPEED (0x2000)
#define PHY_BMCR_AN_ENABLE (0x1000)
#define PHY_BMCR_POWERDOWN (0x0800)
#define PHY_BMCR_ISOLATE (0x0400)
#define PHY_BMCR_AN_RESTART (0x0200)
#define PHY_BMCR_FDX (0x0100)
#define PHY_BMCR_COL_TEST (0x0080)
/* Bit definitions and macros for PHY_STAT */
#define PHY_BMSR_100BT4 (0x8000)
#define PHY_BMSR_100BTX_FDX (0x4000)
#define PHY_BMSR_100BTX (0x2000)
#define PHY_BMSR_10BT_FDX (0x1000)
#define PHY_BMSR_10BT (0x0800)
#define PHY_BMSR_NO_PREAMBLE (0x0040)
#define PHY_BMSR_AN_COMPLETE (0x0020)
#define PHY_BMSR_REMOTE_FAULT (0x0010)
#define PHY_BMSR_AN_ABILITY (0x0008)
#define PHY_BMSR_LINK (0x0004)
#define PHY_BMSR_JABBER (0x0002)
#define PHY_BMSR_EXTENDED (0x0001)
/* Bit definitions and macros for PHY_AN_ADV */
#define PHY_ANAR_NEXT_PAGE (0x8001)
#define PHY_ANAR_REM_FAULT (0x2001)
#define PHY_ANAR_PAUSE (0x0401)
#define PHY_ANAR_100BT4 (0x0201)
#define PHY_ANAR_100BTX_FDX (0x0101)
#define PHY_ANAR_100BTX (0x0081)
#define PHY_ANAR_10BT_FDX (0x0041)
#define PHY_ANAR_10BT (0x0021)
#define PHY_ANAR_802_3 (0x0001)
/* Bit definitions and macros for PHY_AN_LINK_PAR */
#define PHY_ANLPAR_NEXT_PAGE (0x8000)
#define PHY_ANLPAR_ACK (0x4000)
#define PHY_ANLPAR_REM_FAULT (0x2000)
#define PHY_ANLPAR_PAUSE (0x0400)
#define PHY_ANLPAR_100BT4 (0x0200)
#define PHY_ANLPAR_100BTX_FDX (0x0100)
#define PHY_ANLPAR_100BTX (0x0080)
#define PHY_ANLPAR_10BTX_FDX (0x0040)
#define PHY_ANLPAR_10BT (0x0020)
/*******************************************************************/
#endif /* _ETH_PHY_H */

View File

@@ -0,0 +1,166 @@
/*
* File: fec.h
* Purpose: Driver for the Fast Ethernet Controller (FEC)
*
* Notes:
*/
#ifndef _FEC_H_
#define _FEC_H_
#include "eth.h"
#include "fecbd.h"
#include "mii.h"
#include "eth_phy.h"
/********************************************************************/
/* External Interface Modes */
#define FEC_MODE_7WIRE 0 /* Old 7-wire (AMD) mode */
#define FEC_MODE_MII 1 /* Media Independent Interface */
#define FEC_MODE_RMII 2 /* Reduced MII */
#define FEC_MODE_LOOPBACK 3 /* Internal Loopback */
#define INTC_LVL_FEC 3
/*
* FEC Configuration Parameters
*/
typedef struct
{
uint8 ch; /* FEC channel */
uint8 mode; /* Transceiver mode */
MII_SPEED speed; /* Ethernet Speed */
MII_DUPLEX duplex; /* Ethernet Duplex */
uint8 prom; /* Promiscuous Mode? */
uint8 mac[6]; /* Ethernet Address */
uint8 phyaddr; /* PHY address */
uint8 initphy; /* Init PHY? */
int nrxbd; /* Number of RxBDs */
int ntxbd; /* Number of TxBDs */
} FEC_CONFIG;
#define YES 1
#define NO 0
/*
* FEC Event Log
*/
typedef struct {
int errors; /* total count of errors */
int hberr; /* heartbeat error */
int babr; /* babbling receiver */
int babt; /* babbling transmitter */
int gra; /* graceful stop complete */
int txf; /* transmit frame */
int txb; /* transmit buffer */
int rxf; /* receive frame */
int rxb; /* received buffer */
int mii; /* MII */
int eberr; /* FEC/DMA fatal bus error */
int lc; /* late collision */
int rl; /* collision retry limit */
int un; /* Tx FIFO underflow */
int rfsw_inv; /* Invalid bit in RFSW */
int rfsw_l; /* RFSW Last in Frame */
int rfsw_m; /* RFSW Miss */
int rfsw_bc; /* RFSW Broadcast */
int rfsw_mc; /* RFSW Multicast */
int rfsw_lg; /* RFSW Length Violation */
int rfsw_no; /* RFSW Non-octet */
int rfsw_cr; /* RFSW Bad CRC */
int rfsw_ov; /* RFSW Overflow */
int rfsw_tr; /* RFSW Truncated */
} FEC_EVENT_LOG;
#if 0
int
fec_mii_write( int, int, int);
int
fec_mii_read(int, int, uint16*);
void
fec_mii_init(int, int);
void
fec_mib_init(void);
void
fec_mib_dump(void);
void
fec_log_init(int);
void
fec_log_dump(int);
void
fec_reg_dump(int);
void
fec_duplex (int, MII_DUPLEX);
void
fec_rmii_speed (int, MII_SPEED);
uint8
fec_hash_address(const uint8*);
void
fec_set_address (const uint8*);
void
fec_reset ( void );
void
fec_init (int, const uint8*);
void
fec_rx_start(int, uint8*, int);
void
fec_rx_continue( void );
void
fec_rx_handler(void);
void
fec0_rx_handler(void);
void
fec1_rx_handler(void);
void
fec_tx_continue( void );
void
fec_tx_stop (int);
void
fec_tx_handler(NIF*, int);
int
fec_send (uint8*, uint8*, uint16 , NBUF*);
int
fec0_send(uint8*, uint8*, uint16 , NBUF*);
int
fec1_send(uint8*, uint8*, uint16 , NBUF*);
void
fec_irq_enable( void );
void
fec_irq_disable(int);
int
fec_eth_start(FEC_CONFIG*, int);
void
fec_eth_stop(int);
#endif
/********************************************************************/
#endif /* _FEC_H_ */

View File

@@ -0,0 +1,101 @@
/*
* File: fecbd.h
* Purpose:
*
* Purpose: Provide a simple buffer management driver
*/
#ifndef _FECBD_H_
#define _FECBD_H_
/********************************************************************/
#define Rx 1
#define Tx 0
/*
* Buffer sizes in bytes
*/
#ifndef RX_BUF_SZ
#define RX_BUF_SZ 1520 //2048
#endif
#ifndef TX_BUF_SZ
#define TX_BUF_SZ 1520
#endif
/*
* Buffer Descriptor Format
*/
#pragma options align= packed
typedef struct
{
uint16 status; /* control and status */
uint16 length; /* transfer length */
uint8 *data; /* buffer address */
} FECBD;
/*
* Bit level definitions for status field of buffer descriptors
*/
#define TX_BD_R 0x8000
#define TX_BD_TO1 0x4000
#define TX_BD_W 0x2000
#define TX_BD_TO2 0x1000
#define TX_BD_INTERRUPT 0x1000 /* MCF547x/8x Only */
#define TX_BD_L 0x0800
#define TX_BD_TC 0x0400
#define TX_BD_DEF 0x0200 /* MCF5272 Only */
#define TX_BD_ABC 0x0200
#define TX_BD_HB 0x0100 /* MCF5272 Only */
#define TX_BD_LC 0x0080 /* MCF5272 Only */
#define TX_BD_RL 0x0040 /* MCF5272 Only */
#define TX_BD_UN 0x0002 /* MCF5272 Only */
#define TX_BD_CSL 0x0001 /* MCF5272 Only */
#define RX_BD_E 0x8000
#define RX_BD_R01 0x4000
#define RX_BD_W 0x2000
#define RX_BD_R02 0x1000
#define RX_BD_INTERRUPT 0x1000 /* MCF547x/8x Only */
#define RX_BD_L 0x0800
#define RX_BD_M 0x0100
#define RX_BD_BC 0x0080
#define RX_BD_MC 0x0040
#define RX_BD_LG 0x0020
#define RX_BD_NO 0x0010
#define RX_BD_CR 0x0004
#define RX_BD_OV 0x0002
#define RX_BD_TR 0x0001
#define RX_BD_ERROR (RX_BD_NO | RX_BD_CR | RX_BD_OV | RX_BD_TR)
/*
* The following defines are provided by the MCF547x/8x
* DMA API. These are shown here to show their correlation
* to the other FEC buffer descriptor status bits
*
* #define MCD_FEC_BUF_READY 0x8000
* #define MCD_FEC_WRAP 0x2000
* #define MCD_FEC_INTERRUPT 0x1000
* #define MCD_FEC_END_FRAME 0x0800
*/
/*
* Functions provided in fec_bd.c
*/
int fecbd_init(int, int, int);
void fecbd_flush(int);
void fecbd_dump( void );
uint32 fecbd_get_start(int, int);
FECBD* fecbd_rx_alloc(int);
FECBD* fecbd_tx_alloc(int);
FECBD* fecbd_tx_free(int);
/*
* Error codes
*/
#define ERR_MALLOC (-1)
#define ERR_NBUFALLOC (-2)
/*******************************************************************/
#endif /* _FECBD_H_ */

View File

@@ -0,0 +1,43 @@
/*!
* \file mii.h
* \brief Media Independent Interface (MII) driver
* \version $Revision: 1.3 $
* \author Michael Norman
*
* \warning This driver assumes that FEC0 is used for all MII management
* communications. For dual PHYs, etc., insure that FEC0_MDC and
* FEC0_MDIO are connected to the PHY's MDC and MDIO.
*/
#ifndef _MII_H_
#define _MII_H_
/*******************************************************************/
int
mii_write(int, int, uint16);
int
mii_read(int, int, uint16*);
void
mii_init(int);
/* MII Speed Settings */
typedef enum {
MII_10BASE_T, /*!< 10Base-T operation */
MII_100BASE_TX /*!< 100Base-TX operation */
} MII_SPEED;
/* MII Duplex Settings */
typedef enum {
MII_HDX, /*!< half-duplex */
MII_FDX /*!< full-duplex */
} MII_DUPLEX;
#define MII_TIMEOUT 0x10000
#define MII_LINK_TIMEOUT 0x10000
/*******************************************************************/
#endif /* _MII_H_ */

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CC_H__
#define __CC_H__
#include <stdio.h>
#include <stdlib.h>
#include "cpu.h"
typedef unsigned char u8_t;
typedef signed char s8_t;
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned long u32_t;
typedef signed long s32_t;
typedef u32_t mem_ptr_t;
typedef int sys_prot_t;
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#define LWIP_PLATFORM_DIAG(x)
#define LWIP_PLATFORM_ASSERT(x)
#endif /* __CC_H__ */

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CPU_H__
#define __CPU_H__
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* __CPU_H__ */

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __ARCH_INIT_H__
#define __ARCH_INIT_H__
#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg)
void tcpip_init_done(void *);
int wait_for_tcpip_init(void);
#endif /* __ARCH_INIT_H__ */

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LIB_H__
#define __LIB_H__
#include <string.h>
#endif /* __LIB_H__ */

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PERF_H__
#define __PERF_H__
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif /* __PERF_H__ */

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __SYS_RTXC_H__
#define __SYS_RTXC_H__
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#define SYS_MBOX_NULL (QueueHandle_t)0
#define SYS_SEM_NULL (SemaphoreHandle_t)0
typedef SemaphoreHandle_t sys_sem_t;
typedef QueueHandle_t sys_mbox_t;
typedef TaskHandle_t sys_thread_t;
/* Message queue constants. */
#define archMESG_QUEUE_LENGTH ( 6 )
#define archPOST_BLOCK_TIME_MS ( ( unsigned long ) 10000 )
#endif /* __SYS_RTXC_H__ */

View File

@@ -0,0 +1,440 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* lwIP includes. */
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/stats.h"
struct timeoutlist
{
struct sys_timeouts timeouts;
TaskHandle_t pid;
};
/* This is the number of threads that can be started with sys_thread_new() */
#define SYS_THREAD_MAX 4
static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX];
static u16_t s_nextthread = 0;
/*-----------------------------------------------------------------------------------*/
// Creates an empty mailbox.
sys_mbox_t sys_mbox_new(int size)
{
QueueHandle_t mbox;
( void ) size;
mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) );
#if SYS_STATS
++lwip_stats.sys.mbox.used;
if (lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) {
lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
}
#endif /* SYS_STATS */
return mbox;
}
/*-----------------------------------------------------------------------------------*/
/*
Deallocates a mailbox. If there are messages still present in the
mailbox when the mailbox is deallocated, it is an indication of a
programming error in lwIP and the developer should be notified.
*/
void sys_mbox_free(sys_mbox_t mbox)
{
if( uxQueueMessagesWaiting( mbox ) )
{
/* Line for breakpoint. Should never break here! */
portNOP();
#if SYS_STATS
lwip_stats.sys.mbox.err++;
#endif /* SYS_STATS */
// TODO notify the user of failure.
}
vQueueDelete( mbox );
#if SYS_STATS
--lwip_stats.sys.mbox.used;
#endif /* SYS_STATS */
}
/*-----------------------------------------------------------------------------------*/
// Posts the "msg" to the mailbox.
void sys_mbox_post(sys_mbox_t mbox, void *data)
{
while ( xQueueSendToBack(mbox, &data, portMAX_DELAY ) != pdTRUE ){}
}
/*-----------------------------------------------------------------------------------*/
// Try to post the "msg" to the mailbox.
err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg)
{
err_t result;
if ( xQueueSend( mbox, &msg, 0 ) == pdPASS )
{
result = ERR_OK;
}
else {
// could not post, queue must be full
result = ERR_MEM;
#if SYS_STATS
lwip_stats.sys.mbox.err++;
#endif /* SYS_STATS */
}
return result;
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread until a message arrives in the mailbox, but does
not block the thread longer than "timeout" milliseconds (similar to
the sys_arch_sem_wait() function). The "msg" argument is a result
parameter that is set by the function (i.e., by doing "*msg =
ptr"). The "msg" parameter maybe NULL to indicate that the message
should be dropped.
The return values are the same as for the sys_arch_sem_wait() function:
Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
timeout.
Note that a function with a similar name, sys_mbox_fetch(), is
implemented by lwIP.
*/
u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
{
void *dummyptr;
TickType_t StartTime, EndTime, Elapsed;
StartTime = xTaskGetTickCount();
if ( msg == NULL )
{
msg = &dummyptr;
}
if ( timeout != 0 )
{
if ( pdTRUE == xQueueReceive( mbox, &(*msg), timeout / portTICK_PERIOD_MS ) )
{
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS;
return ( Elapsed );
}
else // timed out blocking for message
{
*msg = NULL;
return SYS_ARCH_TIMEOUT;
}
}
else // block forever for a message.
{
while( pdTRUE != xQueueReceive( mbox, &(*msg), portMAX_DELAY ) ){} // time is arbitrary
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS;
return ( Elapsed ); // return time blocked TODO test
}
}
/*-----------------------------------------------------------------------------------*/
/*
Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll
return with SYS_MBOX_EMPTY. On success, 0 is returned.
*/
u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg)
{
void *dummyptr;
if ( msg == NULL )
{
msg = &dummyptr;
}
if ( pdTRUE == xQueueReceive( mbox, &(*msg), 0 ) )
{
return ERR_OK;
}
else
{
return SYS_MBOX_EMPTY;
}
}
/*-----------------------------------------------------------------------------------*/
// Creates and returns a new semaphore. The "count" argument specifies
// the initial state of the semaphore.
sys_sem_t sys_sem_new(u8_t count)
{
SemaphoreHandle_t xSemaphore;
vSemaphoreCreateBinary( xSemaphore );
if( xSemaphore == NULL )
{
#if SYS_STATS
++lwip_stats.sys.sem.err;
#endif /* SYS_STATS */
return SYS_SEM_NULL; // TODO need assert
}
if(count == 0) // Means it can't be taken
{
xSemaphoreTake(xSemaphore,1);
}
#if SYS_STATS
++lwip_stats.sys.sem.used;
if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) {
lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
}
#endif /* SYS_STATS */
return xSemaphore;
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread while waiting for the semaphore to be
signaled. If the "timeout" argument is non-zero, the thread should
only be blocked for the specified time (measured in
milliseconds).
If the timeout argument is non-zero, the return value is the number of
milliseconds spent waiting for the semaphore to be signaled. If the
semaphore wasn't signaled within the specified time, the return value is
SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
(i.e., it was already signaled), the function may return zero.
Notice that lwIP implements a function with a similar name,
sys_sem_wait(), that uses the sys_arch_sem_wait() function.
*/
u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
{
TickType_t StartTime, EndTime, Elapsed;
StartTime = xTaskGetTickCount();
if( timeout != 0)
{
if( xSemaphoreTake( sem, timeout / portTICK_PERIOD_MS ) == pdTRUE )
{
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS;
return (Elapsed); // return time blocked TODO test
}
else
{
return SYS_ARCH_TIMEOUT;
}
}
else // must block without a timeout
{
while( xSemaphoreTake( sem, portMAX_DELAY ) != pdTRUE ){}
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS;
return ( Elapsed ); // return time blocked
}
}
/*-----------------------------------------------------------------------------------*/
// Signals a semaphore
void sys_sem_signal(sys_sem_t sem)
{
xSemaphoreGive( sem );
}
/*-----------------------------------------------------------------------------------*/
// Deallocates a semaphore
void sys_sem_free(sys_sem_t sem)
{
#if SYS_STATS
--lwip_stats.sys.sem.used;
#endif /* SYS_STATS */
vQueueDelete( sem );
}
/*-----------------------------------------------------------------------------------*/
// Initialize sys arch
void sys_init(void)
{
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 = 0;
s_timeoutlist[i].timeouts.next = NULL;
}
// keep track of how many threads have been created
s_nextthread = 0;
}
/*-----------------------------------------------------------------------------------*/
/*
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.
*/
struct sys_timeouts *sys_arch_timeouts(void)
{
int i;
TaskHandle_t pid;
struct timeoutlist *tl;
pid = xTaskGetCurrentTaskHandle( );
for(i = 0; i < s_nextthread; i++)
{
tl = &(s_timeoutlist[i]);
if(tl->pid == pid)
{
return &(tl->timeouts);
}
}
// Error
return NULL;
}
/*-----------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/
// TODO
/*-----------------------------------------------------------------------------------*/
/*
Starts a new thread with priority "prio" that will begin its execution in the
function "thread()". The "arg" argument will be passed as an argument to the
thread() function. The id of the new thread is returned. Both the id and
the priority are system dependent.
*/
sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio)
{
TaskHandle_t CreatedTask;
int result;
if ( s_nextthread < SYS_THREAD_MAX )
{
result = xTaskCreate( thread, name, stacksize, arg, prio, &CreatedTask );
// For each task created, store the task handle (pid) in the timers array.
// This scheme doesn't allow for threads to be deleted
s_timeoutlist[s_nextthread++].pid = CreatedTask;
if(result == pdPASS)
{
return CreatedTask;
}
else
{
return NULL;
}
}
else
{
return NULL;
}
}
/*
This optional function does a "fast" critical region protection and returns
the previous protection level. This function is only called during very short
critical regions. An embedded system which supports ISR-based drivers might
want to implement this function by disabling interrupts. Task-based systems
might want to implement this by using a mutex or disabling tasking. This
function should support recursive calls from the same task or interrupt. In
other words, sys_arch_protect() could be called while already protected. In
that case the return value indicates that it is already protected.
sys_arch_protect() is only required if your port is supporting an operating
system.
*/
sys_prot_t sys_arch_protect(void)
{
vPortEnterCritical();
return 1;
}
/*
This optional function does a "fast" set of critical region protection to the
value specified by pval. See the documentation for sys_arch_protect() for
more information. This function is only required if your port is supporting
an operating system.
*/
void sys_arch_unprotect(sys_prot_t pval)
{
( void ) pval;
vPortExitCritical();
}
/*
* Prints an assertion messages and aborts execution.
*/
void sys_assert( const char *msg )
{
( void ) msg;
/*FSL:only needed for debugging
printf(msg);
printf("\n\r");
*/
vPortEnterCritical( );
for(;;)
;
}