注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

小盒子的小盒

知道的越多不知道的就越多

 
 
 

日志

 
 

【原创】LWIP 之 ethernetif.c文件移植  

2012-04-24 10:45:25|  分类: LwIP |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

/*
 * 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 "HYT_api.h"//add by smallbox at 07.03.27
//#include "MAC/inc/libemac.h"//add by smallbox at 07.03.27
//#include "LD_Eth.h"//add by smallbox at 07.09.30
#include "dm9000x.h"

/* Define those to better describe your network interface. */
#define IFNAME0 'h'
#define IFNAME1 'e'

//add by heyunhunn at 07.03.27
#define MTU   1500
//end add

struct ethernetif {
  struct eth_addr *ethaddr;
  /* Add whatever per-interface state that is needed here. */
};

static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};

/* Forward declarations. */


static void  ethernetif_input(struct netif *netif);
static err_t ethernetif_output(struct netif *netif, struct pbuf *p,
             struct ip_addr *ipaddr);

 

/*
*******************************************************************************
*        low_level_init
*
*Description: 对网卡进行初始化设置
*
*Arguments : netif指向netif结构的指针,该结构储存着网卡的一些基本信息
*    
*
*Returns : 无
*
*Note  : MAC地址需要与RTL8019的MAC地址保持一致
*
*    V1.0 by smallbox at 2007.04.03
*    V1.1 Modify by smallbox at 2007.10.08 for Mac addr
*
*******************************************************************************
*/

static void low_level_init(struct netif *netif)
{
  struct ethernetif *ethernetif;
  
  ethernetif = netif->state;
  netif->hwaddr_len = NETIF_MAX_HWADDR_LEN;

  //设置MAC地址
  netif->hwaddr[0] = MAC_ADDR_0;
  netif->hwaddr[1] = MAC_ADDR_1;
  netif->hwaddr[2] = MAC_ADDR_2;
  netif->hwaddr[3] = MAC_ADDR_3;
  netif->hwaddr[4] = MAC_ADDR_4;
  netif->hwaddr[5] = MAC_ADDR_5;
 
  netif->mtu = MTU;
  netif->flags = NETIF_FLAG_BROADCAST;
 
  HYT_DM9000X_init();

}


/*
*******************************************************************************
*        low_level_output
*
*Description: TCP/IP协议包的发送
*
*Arguments : netif 指向netif结构的指针
*    *p  指向的发送的数据包
*
*Returns : 无
*
*Note  : 返回指向pbuf结构的指针
*
*    V1.0 by smallbox at 2007.04.04
*
*******************************************************************************
*/

static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
  struct ethernetif *ethernetif;
  struct pbuf *q;
 
  ethernetif= netif->state;
 
#if ETH_PAD_SIZE
  pbuf_header(p, -ETH_PAD_SIZE);
#endif

  for(q = p; q != NULL; q = q->next) {
     HYT_DM9000X_SendPacket(q->payload,q->len);
  }

#if ETH_PAD_SIZE
  pbuf_header(p, ETH_PAD_SIZE);
#endif
 
#if LINK_STATS
  lwip_stats.link.xmit++;
#endif /* LINK_STATS */     

  return ERR_OK;
}


/*
*******************************************************************************
*        low_level_input
*
*Description: 完成实际的信息包接收
*
*Arguments : netif指向netif结构的指针
*    
*
*Returns : 无
*
*Note  : 返回指向pbuf结构的指针
*
*    V1.0 by smallbox at 2007.04.04
*    V1.1 Modify by smallbox at 2007.10.16
*     优化了改函数,速度上得到一定的改善
*
*******************************************************************************
*/

static struct pbuf * low_level_input(struct netif *netif)
{
 struct ethernetif *ethernetif;
   struct pbuf *p = NULL, *q;
   u16_t len;
   
   int flag;
   
   unsigned int i;
 unsigned char buffer[4096];
 unsigned char *des;
 unsigned char *data;
 
 data =  buffer;
    
   ethernetif = netif->state;
   
 flag = HYT_DM9000X_RevPacket(data,&len);
 
#if 0 
 if(flag == 1) {
  des = data;
  LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));   
  for(i=0; i<len; i++) {
   LWIP_DEBUGF(RTL8019_DEBUG, ("0x%02X ",*des++));
  }
  LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
  LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
  LWIP_DEBUGF(RTL8019_DEBUG, ("the receive data length is %d\r\n",len));
  LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
  
 }
#endif 

 if(flag == 1) { 
  #if ETH_PAD_SIZE
   len += ETH_PAD_SIZE;
  #endif

    //p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
    //Modify by smallbox at 07.10.16
    if(p == NULL) {
     p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
    }
  
    if (p != NULL) {

   #if ETH_PAD_SIZE
       pbuf_header(p, -ETH_PAD_SIZE);
   #endif

      for(q = p; q != NULL; q = q->next) {
    memcpy(q->payload,(unsigned char *)data, q->len);
         data += q->len;
      }

   #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   
    }
 }

  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);
 
}


/*
*******************************************************************************
*        LD_Ethernet_Rev
*
*Description: 创建以太网RTL8019接收任务
*
*Arguments : netif 网卡的基本信息[此时为NULL]
*    
*
*Returns : 无
*
*Note  : 该任务采用查询方式接收
*
*    V1.0 by smallbox at 2007.10.09
*
*******************************************************************************
*/

void LD_Ethernet_Rev(void)
{
 int prio;
 prio = sys_thread_new(ethernetif_input,(struct netif *)netif_default, 7);

 LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
 LWIP_DEBUGF(RTL8019_DEBUG, ("Current ethernetif_input Priority is %d\r\n",prio));
 LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
 
}


/*
*******************************************************************************
*        ethernetif_input
*
*Description: 以太网卡信息包接收任务,
*    它通过调用low_level_input()函数来完成实际的信息包接收
*
*Arguments : netif 网卡的基本信息[此时为NULL]
*    
*
*Returns : 无
*
*Note  : 
*
*    V1.0 by smallbox at 2007.04.02
*
*******************************************************************************
*/

void ethernetif_input(struct netif *netif)
{
  struct ethernetif *ethernetif;
  struct eth_hdr *ethhdr;
  struct pbuf *p;
 
  while(1)
  {
   ethernetif = netif->state;
   do{
    p = low_level_input(netif);
    if (p == NULL)
     OSTimeDlyHMSM(0,0,0,100);
   }while(p == NULL);

 #if LINK_STATS
   lwip_stats.link.recv++;
 #endif

   ethhdr = p->payload;
    
   switch (htons(ethhdr->type)) {

    case ETHTYPE_IP:
 #if 1 
      etharp_ip_input(netif, p); //更新ARP表
 #endif
   //跳过以太网头部字段
      pbuf_header(p, -sizeof(struct eth_hdr));
      //传递到网络层
      netif->input(p, netif);
      break;
      
     case ETHTYPE_ARP:
        //将netif传递到ARP模块
        p = etharp_arp_input(netif, ethernetif->ethaddr, p);
        if(p != NULL) {
         low_level_output(netif, p);
         pbuf_free(p);
        p = NULL;
       }        
        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
*
*Description: 通过调用low_level_init()函数完成网卡初始设置工作。
*    该函数应该在操作系统启动后设置LwIP时调用,这个系统
*    就是在SetupLwIP_Ethernet()函数中通过调用netif_add()
*    函数调用该函数完成网卡初始设置工作。
*
*Arguments : netif指向netif结构的指针,该结构储存着网卡的一些基本信息
*    
*
*Returns : 如果无法申请下内存则返回ERR_MEM,成功则返回ERR_OK
*
*Note  : 
*
*    V1.0 by smallbox at 2007.04.03
*
*******************************************************************************
*/

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\r\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;
}


/*$PAGE$*/

 

作者:小盒子
时间:2012.04.24
地点:大连

注:本文属小盒子原创,转载请注明出处,谢谢合作!
  评论这张
 
阅读(2148)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017