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

📄 ethernetif.c

📁 基于AT91SAM7x256的硬件平台的WEB服务器源码(A&shy DS版本, ucOS_II+LWIP+自己编写的DNS查询工具)
💻 C
字号:
//*------------------------------------------------------------------------------------------------//* 文件名				: ethernetif.c//* 功能描述			: 网卡的驱动函数库文件//* 作者    			: 焦海波//* 版本				: 0.1//* 建立日期、时间		: 2006/06/07 14:05//* 最近修改日期、时间	: //* 修改原因			: //*------------------------------------------------------------------------------------------------//*------------------------------------------ 头文件 -----------------------------------------------#include	"/uCOS_II/includes.h"#include 	"/LwIP/include/lwip/opt.h"#include 	"/LwIP/include/lwip/def.h"#include 	"/LwIP/include/lwip/mem.h"#include 	"/LwIP/include/lwip/pbuf.h"#include 	"/LwIP/include/lwip/sys.h"#include 	"/LwIP/include/lwip/stats.h"#include 	"/LwIP/include/netif/etharp.h"#include	"/at91sam7x256/periph/emac/lib_emac.h"#include 	"/task.h"	//*------------------------------------- 常量、变量、宏 --------------------------------------------#define 	IFNAME0 	'e'#define 	IFNAME1 	'n'#define		MTU			1500static const st_eth_addr __stEthBroadcastAddr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};static st_netif *__pstNetif = NULL;HANDLER hEthernetInput;OS_STK T_ETHERNETIF_INPUT_STK[T_ETHERNETIF_INPUT_STKSIZE];//*--------------------------------------- 结构体定义 ----------------------------------------------//* 以太网卡结构体typedef struct ethernetif {  st_eth_addr *pstEthaddr;}st_ethernetif;//*-------------------------------------- 函数原型声明 ---------------------------------------------err_t ethernetif_init(st_netif *pstNetif);static err_t __ethernetif_output(st_netif *pstNetif, st_pbuf *pstPbuf, st_ip_addr *pstIPAddr);static err_t __low_level_output(st_netif *pstNetif, st_pbuf *pstPbuf);static st_pbuf *__low_level_input(st_netif *pstNetif);static void __T_EthernetifInput(void *pReserved);static void __low_level_init(st_netif *pstNetif);static void __arp_timer(void *pReserved);//*================================================================================================//*											函	数	区//*================================================================================================//*------------------------------------------------------------------------------------------------//* 函数名称 : ethernetif_init//* 功能描述 : 通过调用low_level_init()函数完成网卡初始设置工作。该函数应该在操作系统启动后设置LwIP//*			 : 时调用,这个系统就是在SetupLwIP()函数中通过调用netif_add()函数调用该函数完成网卡初始//*          : 设置工作。//* 入口参数 : <pstNetif>[in] 指向st_netif结构的指针,该结构储存着网卡的一些基本信息//* 出口参数 : 如果无法申请下内存则返回ERR_MEM,成功则返回ERR_OK//*------------------------------------------------------------------------------------------------err_t ethernetif_init(st_netif *pstNetif){	st_ethernetif   *__pstEthernetif;	__pstEthernetif = mem_malloc(sizeof(st_ethernetif));		if(__pstEthernetif == NULL)		return ERR_MEM;	pstNetif->state = __pstEthernetif;	pstNetif->name[0] = IFNAME0;	pstNetif->name[1] = IFNAME1;	pstNetif->output = __ethernetif_output;	pstNetif->linkoutput = __low_level_output;	__pstEthernetif->pstEthaddr = (st_eth_addr*)&(pstNetif->hwaddr[0]);	__low_level_init(pstNetif);	etharp_init();	sys_timeout(ARP_TMR_INTERVAL, __arp_timer, NULL);	return ERR_OK;}//*------------------------------------------------------------------------------------------------//* 函数名称 : __ethernetif_output//* 功能描述 : 当要发送一个IP信息包时,该函数由TCP/IP协议栈调用。该函数通过调用__low_level_output()//*			 : 函数来完成实际的信息包发送。//* 入口参数 :  <pstNetif>[in] 指向st_netif结构的指针,其指定IP信息包将被发送的哪一个网卡接口上//*			 :   <pstPbuf>[in] 指向st_pbuf结构的指针,其保存着将要发送的IP信息包//*			 : <pstIPAddr>[in] 指向st_ip_addr结构的指针,其指定IP信息包的目的IP地址//* 出口参数 : - ERR_RTE:不能路由到目的地址(没有外网网关)//*			 : - ERR_BUF:无法为以太网头腾出空间//*			 : - etharp_query()函数或netif->linkoutput()函数的返回值//*------------------------------------------------------------------------------------------------static err_t __ethernetif_output(st_netif *pstNetif, st_pbuf *pstPbuf, st_ip_addr *pstIPAddr){    //* 解析硬件地址,然后发送或排队信息包    return etharp_output(pstNetif, pstIPAddr, pstPbuf);}//*------------------------------------------------------------------------------------------------//* 函数名称 : __low_level_output//* 功能描述 : 完成实际的信息包发送//* 入口参数 :  <pstNetif>[in] 指向st_netif结构的指针,其指定IP信息包将被发送的哪一个网卡接口上//*			 :   <pstPbuf>[in] 指向st_pbuf结构的指针,其保存着将要发送的IP信息包//* 出口参数 : -  0: 发送成功//*			 : - -1: 发送失败//*------------------------------------------------------------------------------------------------static err_t __low_level_output(st_netif *pstNetif, st_pbuf *pstPbuf){		st_pbuf *__pstSendPbuf = pstPbuf;	static HANDLER __hBlockOutput = NULL;	err_t __errReturn = ERR_OK;	if(__hBlockOutput == NULL)		__hBlockOutput = OSAPIBlockNew(PIP_LOW_LEVEL_OUTPUT);	#if ETH_PAD_SIZE		pbuf_header(pstPbuf, -ETH_PAD_SIZE);	#endif	//* 阻塞对EMAC的访问,以避免不同的任务同时访问EMAC造成访问冲突的问题,最长等待时间是2秒	if(OS_NO_ERR == OSAPIBlockEnter(__hBlockOutput, 2000))	{		for(; __pstSendPbuf!=NULL; __pstSendPbuf=__pstSendPbuf->next)		{			//* 发送pbuf中的数据,每次一个pbuf,如果__pstSendPbuf->next指针为空则表明已经到达pbuf链表的末尾			if(!EMACSendPacket(__pstSendPbuf->payload, __pstSendPbuf->len, (__pstSendPbuf->next == NULL)))			{				__errReturn = ~ERR_OK;			}		}        OSAPIBlockExit(__hBlockOutput);	}		#if ETH_PAD_SIZE		pbuf_header(pstPbuf, ETH_PAD_SIZE);	#endif	#if LINK_STATS		lwip_stats.link.xmit++;	#endif    return __errReturn;}//*------------------------------------------------------------------------------------------------//* 函数名称 : __low_level_input//* 功能描述 : 完成实际的信息包接收//* 入口参数 :  <pstNetif>[in] 指向st_netif结构的指针//* 出口参数 : 返回指向st_pbuf结构的指针//*------------------------------------------------------------------------------------------------static st_pbuf *__low_level_input(st_netif *pstNetif){	st_pbuf         *__pstPbuf = NULL, *__pstCurPbuf;	UWORD			__uwLen;	static HANDLER __hBlockInput = NULL;		if(__hBlockInput == NULL)		__hBlockInput = OSAPIBlockNew(PIP_LOW_LEVEL_INPUT);		//* 阻塞对EMAC的访问,以避免不同的任务同时访问EMAC造成访问冲突的问题,最长等待时间是1秒	if(OS_NO_ERR == OSAPIBlockEnter(__hBlockInput, 1000))	{		//* 获取收到的信息包的长度		__uwLen = GetInputPacketLen();		if(__uwLen)		{			#if ETH_PAD_SIZE				__uwLen += ETH_PAD_SIZE; 			#endif						//* 从pbuf pool中获取一个pbuf链			__pstPbuf = pbuf_alloc(PBUF_RAW, __uwLen, PBUF_POOL);			if(__pstPbuf != NULL)			{				#if ETH_PAD_SIZE					pbuf_header(__pstPbuf, -ETH_PAD_SIZE);				#endif								//* 复制数据				for(__pstCurPbuf=__pstPbuf; __pstCurPbuf!=NULL; __pstCurPbuf=__pstCurPbuf->next)					EMACReadPacket(__pstCurPbuf->payload, __pstCurPbuf->len, (__pstCurPbuf->next == NULL));									#if ETH_PAD_SIZE					pbuf_header( p, ETH_PAD_SIZE );				#endif				#if LINK_STATS					lwip_stats.link.recv++;				#endif			}			else			{				#if LINK_STATS					lwip_stats.link.memerr++;					lwip_stats.link.drop++;				#endif			}		}				OSAPIBlockExit(__hBlockInput);	}		return __pstPbuf;}//*------------------------------------------------------------------------------------------------//* 函数名称 : __T_EthernetifInput//* 功能描述 : 以太网卡信息包接收任务,它通过调用__low_level_output()函数来完成实际的信息包接收。//* 入口参数 : <pReserved>[in] 保留//* 出口参数 : 无//*------------------------------------------------------------------------------------------------static void __T_EthernetifInput(void *pReserved){	st_ethernetif		*pstEthernetif;	st_pbuf				*__pstPbuf;	st_eth_hdr			*__pstEthhdr;	while(TRUE)	{		pstEthernetif = (st_ethernetif*)__pstNetif->state;				//* 从EMAC循环读取数据		do{			__pstPbuf = __low_level_input(__pstNetif);			if(__pstPbuf == NULL)				OSAPISemWait(hEthernetInput, 100);		}while(__pstPbuf == NULL);					__pstEthhdr = __pstPbuf->payload;				#if LINK_STATS			lwip_stats.link.recv++;		#endif				__pstEthhdr = __pstPbuf->payload;				switch(htons(__pstEthhdr->type))		{			case ETHTYPE_IP:				//* 更新ARP表				etharp_ip_input(__pstNetif, __pstPbuf);				//* 跳过以太网头部字段				pbuf_header(__pstPbuf, -sizeof(st_eth_hdr) );				 													//* 传递到网络层				__pstNetif->input(__pstPbuf, __pstNetif);								break;					case ETHTYPE_ARP:				//* 将__pstPbuf传递到ARP模块				etharp_arp_input(__pstNetif, pstEthernetif->pstEthaddr, __pstPbuf);				break;					default:				pbuf_free(__pstPbuf);				__pstPbuf = NULL;				break;		}		}}//*------------------------------------------------------------------------------------------------//* 函数名称 : __low_level_init//* 功能描述 : 对网卡进行初始化设置//* 入口参数 : <pstNetif>[in] 指向st_netif结构的指针,该结构储存着网卡的一些基本信息//* 出口参数 : 无//*------------------------------------------------------------------------------------------------static void __low_level_init(st_netif *pstNetif){	UBYTE		__ubOldPrio;	UBYTE		__ubErr;	pstNetif->hwaddr_len = NETIF_MAX_HWADDR_LEN;	//* 设置MAC地址	pstNetif->hwaddr[0] = MAC_ADDR_0;	pstNetif->hwaddr[1] = MAC_ADDR_1;	pstNetif->hwaddr[2] = MAC_ADDR_2;	pstNetif->hwaddr[3] = MAC_ADDR_3;	pstNetif->hwaddr[4] = MAC_ADDR_4;	pstNetif->hwaddr[5] = MAC_ADDR_5;		pstNetif->mtu = MTU;	pstNetif->flags = NETIF_FLAG_BROADCAST;	__pstNetif = pstNetif;	//* 初始化EMAC。EMACInit()函数包含查询状态位代码,并且这些查询代码并没有使用OSTimeDly()等函数主动释放	//* CPU使用权。如果网线在当时并没有接触良好,则这个过程需要相当长的时间。为了避免阻塞其它低优先级任务的	//* 正常运行,我们使用了uCOS提供的任务管理函数,先将其所在任务的优先级降低,等初始化完成之后再恢复其优	//* 先级。	__ubOldPrio = OSTCBCur->OSTCBPrio;	__ubErr = OSTaskChangePrio(OS_PRIO_SELF, OS_IDLE_PRIO - 1);	EMACInit();	if(__ubErr == OS_NO_ERR)		OSTaskChangePrio(OS_PRIO_SELF, __ubOldPrio);		OSTaskCreate(__T_EthernetifInput, (void*)NULL, &T_ETHERNETIF_INPUT_STK[T_ETHERNETIF_INPUT_STKSIZE-1], T_ETHERNETIF_INPUT_PRIOR);}//*------------------------------------------------------------------------------------------------//* 函数名称 : __arp_timer//* 功能描述 : ARP表定时更新处理函数//* 入口参数 : <pReserved>[in/out] 保留 //* 出口参数 : 无//*------------------------------------------------------------------------------------------------static void __arp_timer(void *pReserved){    etharp_tmr();    sys_timeout(ARP_TMR_INTERVAL, __arp_timer, NULL);}

⌨️ 快捷键说明

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