⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethernetif.c

📁 基于UC/OS 2+LWIP的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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> * *//* * This file is a skeleton for developing Ethernet network interface * drivers for lwIP. Add code to the low_level functions and do a * search-and-replace for the word "ethernetif" to replace it with * something that better describes your network interface. */#include "lwip/opt.h"#include "lwip/def.h"#include "lwip/mem.h"#include "lwip/pbuf.h"#include "lwip/sys.h"#include "lwip/stats.h"#include "netif/etharp.h"#include "AT91SAM7X256.h"#include "lib_AT91SAM7X256.h"#include <string.h>#include "Emac.h"#include "ethernetif.h"static void low_level_init(struct netif *netif){   	/* set MAC hardware address length */  	netif->hwaddr_len = 6;  	//xNetIf = NULL;  	ulNextRxBuffer = 0;  	  	/* set MAC hardware address */  	netif->hwaddr[0] = EMAC1;  	netif->hwaddr[1] = EMAC2;  	netif->hwaddr[2] = EMAC3;  	netif->hwaddr[3] = EMAC4;  	netif->hwaddr[4] = EMAC5;  	netif->hwaddr[5] = EMAC6;    	/* maximum transfer unit */  	netif->mtu = 1500;    	/* broadcast capability */  	netif->flags = NETIF_FLAG_BROADCAST;   	xNetIf = netif;  	/* Do whatever else is needed to initialize interface. */    	LanInitialize();  	AT91F_AIC_ConfigureIt (	AT91C_BASE_AIC,     						 	AT91C_ID_EMAC,     							AT91C_AIC_PRIOR_HIGHEST,     							AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,     							vEMACISR);    												    AT91C_BASE_EMAC->EMAC_IDR = 0x3fff;    AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_EMAC);     AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP | AT91C_EMAC_TXUBR;        OSTaskCreateExt(ethernetif_input,					(void *)1,					&INPOUTTaskStk[INPUTTASK_STK_SIZE - 1],					INPUT_TASK_PRIO,					INPUT_TASK_PRIO,					&INPOUTTaskStk[0],					INPUTTASK_STK_SIZE,					(void *)0,					OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);}/*-----------------------------------------------------------*//* See the header file for descriptions of public functions. */unsigned int ulEMACInputLength( void ){	register unsigned int ulIndex, ulLength = 0;	/* Skip any fragments.  We are looking for the first buffer that contains	data and has the SOF (start of frame) bit set. */	while( ( RxtdList[ ulNextRxBuffer ].addr & AT91C_OWNERSHIP_BIT ) && !( RxtdList[ ulNextRxBuffer ].U_Status.status & AT91C_SOF ) )	{		/* Ignoring this buffer.  Mark it as free again. */		RxtdList[ ulNextRxBuffer ].addr &= ~( AT91C_OWNERSHIP_BIT );				ulNextRxBuffer++;		if( ulNextRxBuffer >= NB_RX_BUFFERS )		{			ulNextRxBuffer = 0;		}	}	/* We are going to walk through the descriptors that make up this frame, 	but don't want to alter ulNextRxBuffer as this would prevent vEMACRead()	from finding the data.  Therefore use a copy of ulNextRxBuffer instead. */	ulIndex = ulNextRxBuffer;	/* Walk through the descriptors until we find the last buffer for this 	frame.  The last buffer will give us the length of the entire frame. */	while( ( RxtdList[ ulIndex ].addr & AT91C_OWNERSHIP_BIT ) && !ulLength )	{		ulLength = RxtdList[ ulIndex ].U_Status.status & AT91C_LENGTH_FRAME;		/* Increment to the next buffer, wrapping if necessary. */		ulIndex++;		if( ulIndex >= NB_RX_BUFFERS )		{			ulIndex = 0;		}	}	return ulLength;}/* * Function : SendPacket * Description : Send ethernet frame function * Input : frame data pointer, frame length * Output : transmit ok(1) or error(0) */int SendPacket( unsigned char* Data,int Size, int EndOfFrame){	unsigned int DataBuffered = 0, DataRemainingToSend, LengthToSend, LastBuffer;	int wait = 0;	int sndrtn = 0; //send return	char *pcBuffer;	INT8U err;		OSSemPend(lwip_output, 0, &err);	while(DataBuffered < Size){			// Is a buffer available? *		while(!(TxtdList[TxBuffIndex].U_Status.status & AT91C_TRANSMIT_OK)){				// There is no room to write the Tx data to the Tx buffer.  Wait a			//short while, then try again. 			wait++;			if(wait > Emac_MAX_WAIT){				// Give up. 				sndrtn = 1;				break;			}			else{				;			}		}		// lReturn will only be 0 if a buffer is available. 	if(sndrtn == 0){			//Get the address of the buffer from the descriptor, then copy 			//	the data into the buffer. 			pcBuffer = (char *) TxtdList[TxBuffIndex].addr;				// How much can we write to the buffer? 			DataRemainingToSend = Size - DataBuffered;			if(DataRemainingToSend <= ETH_TX_BUFFER_SIZE){				// We can write all the remaining bytes. 				LengthToSend = DataRemainingToSend;			}			else{				// We can not write more than ETH_TX_BUFFER_SIZE in one go. *				LengthToSend = ETH_TX_BUFFER_SIZE;			}				// Copy the data into the buffer. *				memcpy( ( void * ) pcBuffer, ( void * ) &( Data[ DataBuffered ] ), LengthToSend );				DataBuffered += LengthToSend;						// Is this the last data for the frame? *			if( EndOfFrame && ( DataBuffered >= Size ) ){				// No more data remains for this frame so we can start the 				//transmission. *				LastBuffer = AT91C_LAST_BUFFER;			}			else{				// More data to come for this frame. *				LastBuffer = 0;			}				// Fill out the necessary in the descriptor to get the data sent, 			//	then move to the next descriptor, wrapping if necessary. *			if( TxBuffIndex >= ( NB_TX_BUFFERS - 1 ) ){								TxtdList[ TxBuffIndex ].U_Status.status = 											( LengthToSend & ( unsigned int ) AT91C_LENGTH_FRAME )										| LastBuffer										| AT91C_TRANSMIT_WRAP;				TxBuffIndex = 0;				}			else{				TxtdList[ TxBuffIndex ].U_Status.status = 											( LengthToSend & ( unsigned int ) AT91C_LENGTH_FRAME )										| LastBuffer;				TxBuffIndex++;				}							// If this is the last buffer to be sent for this frame we can			//	start the transmission. *			if( LastBuffer ){				AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;			}							}		else{			break;		}											}		OSSemPost(lwip_output);		return sndrtn;}/* * low_level_output(): * * 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. * */static err_t low_level_output(struct netif *netif, struct pbuf *p){	struct pbuf *q;  	u8_t 			*pFrameData,*tmp ;	u32_t			FrameLength ;	  	pFrameData = mem_malloc(p->tot_len);	if (pFrameData == NULL)return ERR_MEM;	FrameLength = p->tot_len;	tmp = pFrameData;	#if ETH_PAD_SIZE  pbuf_header(p, -ETH_PAD_SIZE);			/* drop the padding word */#endif	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);  		SendPacket(q->payload, q->len, (q->next == NULL));  				     	}	mem_free(pFrameData);#if ETH_PAD_SIZE  	pbuf_header(p, ETH_PAD_SIZE);			/* reclaim the padding word */#endif  #if LINK_STATS  	lwip_stats.link.xmit++;#endif /* LINK_STATS */        	return ERR_OK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -