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

📄 ethernetif.c

📁 基于UC/OS 2+LWIP的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
}void vEMACRead( char *pcTo, unsigned long ulSectionLength, unsigned long ulTotalFrameLength ){	static unsigned long ulSectionBytesReadSoFar = 0, ulBufferPosition = 0, ulFameBytesReadSoFar = 0;	static char *pcSource;	register unsigned long ulBytesRemainingInBuffer, ulRemainingSectionBytes;	/* vEMACRead is called with pcTo set to NULL to indicate that we are about	to read a new frame.  Any fragments remaining in the frame we were 	processing during the last call should be dropped. */	if( pcTo == NULL )	{		/* How many bytes are indicated as being in this buffer?  If none then		the buffer is completely full and the frame is contained within more		than one buffer. */		/* Reset our state variables ready for the next read from this buffer. */        pcSource = ( char * )( RxtdList[ ulNextRxBuffer ].addr & emacADDRESS_MASK );        ulFameBytesReadSoFar = ( unsigned long ) 0;		ulBufferPosition = ( unsigned long ) 0;	}	else	{		/* Loop until we have obtained the required amount of data. */        ulSectionBytesReadSoFar = 0;		while( ulSectionBytesReadSoFar < ulSectionLength )		{			/* We may have already read some data from this buffer.  How much			data remains in the buffer? */			ulBytesRemainingInBuffer = ( ETH_RX_BUFFER_SIZE - ulBufferPosition );			/* How many more bytes do we need to read before we have the 			required amount of data? */            ulRemainingSectionBytes = ulSectionLength - ulSectionBytesReadSoFar;			/* Do we want more data than remains in the buffer? */			if( ulRemainingSectionBytes > ulBytesRemainingInBuffer )			{				/* We want more data than remains in the buffer so we can 				write the remains of the buffer to the destination, then move				onto the next buffer to get the rest. */				memcpy( &( pcTo[ ulSectionBytesReadSoFar ] ), &( pcSource[ ulBufferPosition ] ), ulBytesRemainingInBuffer );				ulSectionBytesReadSoFar += ulBytesRemainingInBuffer;                ulFameBytesReadSoFar += ulBytesRemainingInBuffer;				/* Mark the buffer as free again. */				RxtdList[ ulNextRxBuffer ].addr &= ~( AT91C_OWNERSHIP_BIT );				/* Move onto the next buffer. */				ulNextRxBuffer++;				if( ulNextRxBuffer >= NB_RX_BUFFERS )				{					ulNextRxBuffer = ( unsigned long ) 0;				}				/* Reset the variables for the new buffer. */				pcSource = ( char * )( RxtdList[ ulNextRxBuffer ].addr & emacADDRESS_MASK );				ulBufferPosition = ( unsigned long ) 0;			}			else			{				/* We have enough data in this buffer to send back.  Read out				enough data and remember how far we read up to. */				memcpy( &( pcTo[ ulSectionBytesReadSoFar ] ), &( pcSource[ ulBufferPosition ] ), ulRemainingSectionBytes );				/* There may be more data in this buffer yet.  Increment our 				position in this buffer past the data we have just read. */				ulBufferPosition += ulRemainingSectionBytes;				ulSectionBytesReadSoFar += ulRemainingSectionBytes;                ulFameBytesReadSoFar += ulRemainingSectionBytes;				/* Have we now finished with this buffer? */				if( ( ulBufferPosition >= ETH_RX_BUFFER_SIZE ) || ( ulFameBytesReadSoFar >= ulTotalFrameLength ) )				{					/* Mark the buffer as free again. */					RxtdList[ ulNextRxBuffer ].addr &= ~( AT91C_OWNERSHIP_BIT );					/* Move onto the next buffer. */					ulNextRxBuffer++;					if( ulNextRxBuffer >= NB_RX_BUFFERS )					{						ulNextRxBuffer = 0;					}						pcSource = ( char * )( RxtdList[ ulNextRxBuffer ].addr & emacADDRESS_MASK );					ulBufferPosition = 0;				}			}		}	}}/* * low_level_input(): * * Should allocate a pbuf and transfer the bytes of the incoming * packet from the interface into the pbuf. * */static struct pbuf *low_level_input( struct netif *netif ){  	struct pbuf *p, *q;	u16_t len;  	INT8U err;      	OSSemPend(next, 0, &err); #if ETH_PAD_SIZE  	len += ETH_PAD_SIZE;						/* allow room for Ethernet padding */#endif  			/* Obtain the size of the packet and put it into the "len"	variable. */	len = ulEMACInputLength();	if(len){		/* 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			/* Let the driver know we are going to read a new packet. */			vEMACRead( NULL, 0, len );								/* 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. */				vEMACRead( q->payload, q->len, len );			}#if ETH_PAD_SIZE    		pbuf_header(p, ETH_PAD_SIZE);			/* reclaim the padding word */#endif#if LINK_STATS    		lwip_stats.link.recv++;#endif /* LINK_STATS */        		}   		else {//    drop packet();#if LINK_STATS    		lwip_stats.link.memerr++;    		lwip_stats.link.drop++;#endif /* LINK_STATS */        		}	}		OSSemPost(next);	  	return p;  }/* * ethernetif_output(): * * This function is called by the TCP/IP stack when an IP packet * should be sent. It calls the function called low_level_output() to * do the actual transmission of the packet. * */static err_t ethernetif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr){	/* resolve hardware address, then send (or queue) packet */	return etharp_output(netif, ipaddr, p);}/* * ethernetif_input(): * * 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. * */void ethernetif_input(void *p_arg){	struct ethernetif *ethernetif;  	struct eth_hdr *ethhdr;  	struct pbuf *p;	INT8U err;  	    	for(;;){		OSSemPend(lwip_input, 0, &err);  		ethernetif = netif_default->state;				p = NULL;		  		p = low_level_input(netif_default);  		/* no packet could be read, silently ignore this */  		if (p != NULL) { 		  			/* points to packet payload, which starts with an Ethernet header */  			ethhdr = p->payload;#if LINK_STATS  			lwip_stats.link.recv++;#endif /* LINK_STATS */  			ethhdr = p->payload;  			switch (htons(ethhdr->type)) {  				/* IP packet? */  				case ETHTYPE_IP:  	    				/* update ARP table */    				etharp_ip_input(netif_default, p);				    				/* skip Ethernet header */    				pbuf_header(p, -sizeof(struct eth_hdr));    				//pbuf_header(p, -14);				    				/* pass to network layer */    				netif_default->input(p, netif_default);				    			break;          			case ETHTYPE_ARP:    	      				/* pass p to ARP module  */      				etharp_arp_input(netif_default, ethernetif->ethaddr, p);				    			break;    			default:		      				pbuf_free(p);      				//p = NULL;    			break;  			}  		}	}}static void arp_timer(void *arg){	etharp_tmr();	sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);}/* * ethernetif_init(): * * 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. * */err_t ethernetif_init(struct netif *netif){	struct ethernetif *ethernetif;    	ethernetif = mem_malloc(sizeof(struct ethernetif));    	if (ethernetif == NULL)  	{  		LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));  		return ERR_MEM;  	}    	netif->state = ethernetif;  	netif->name[0] = IFNAME0;  	netif->name[1] = IFNAME1;    	netif->output = ethernetif_output;  	netif->linkoutput = low_level_output;    	ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);    	low_level_init(netif);  	etharp_init();  	sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);  	return ERR_OK;}

⌨️ 快捷键说明

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