1. 程式人生 > >【原創】LWIP 之 ethernetif.c檔案移植

【原創】LWIP 之 ethernetif.c檔案移植

/*
 * 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 <

[email protected]>
 *
 */

/*
 * 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
地點:大連

注:本文屬小盒子原創,轉載請註明出處,謝謝合作!

相關推薦

原創LWIP ethernetif.c檔案移植

/* * Copyright (c) 2001-2004 Swedish Institute of Computer Science. * All rights reserved.  *  * Redistribution and use in source and binary forms, with or

原創讀後感格列佛遊記

生物 人類 順序 整體 其實在 徹底 知識 社會 分用 書名:《格列佛遊記》 作者:【英國】喬納森·斯威夫特 概要: 在這本著名的英國諷刺小說中,作者以格列佛先生的名義,借以遊記的形式,講述了主人公先後遊歷了小人國、巨人國、飛島國和“慧骃”國的故事,雖然不曾直

原創分散式elk日誌架構的演進

引言 好久沒寫分散式系列的文章了,最近剛好有個朋友給我留言,想看這方面的知識。其實這方面的知識,網上各種技術峰會的資料一抓一大把。博主也是湊合著寫寫。感覺自己也寫不出什麼新意,大家也湊合看看。 日誌系統的必要性? 我15年實習的時候那會,給某國企做開發。不怕大家笑話,生產上就兩臺機器。那

原創Android應用程式的組成部分

        Android架構裡定義了4種應用程式構件,使用者的Android應用程式都是由這4種構件組成,他們分別是Activity(活動)、Service(服務)、BroadcastReceiver(廣播接收器)和ContentProvider(內容提供器)。下面我們分別來看看他們都是做什麼的。 1

SpringBootSpringBoot入門配置檔案

介紹:example02 相信很多人選擇Spring Boot主要是考慮到它既能兼顧Spring的強大功能,還能實現快速開發的便捷。我們在Spring Boot使用過程中,最直觀的感受就是沒有了原來自己整合Spring應用時繁多的XML配置內容,替代它的是在p

原創Android 引用第三方庫檔案大全

不知不覺,使用Android Studio開發App已有一段時間了,接觸到了各式各樣的第三方庫檔案的引入,也是時候總結一波了。 使用android Studio開發Android應用時,避免不了需要藉助Gradle引入各式各樣的第三方庫檔案,幫助我們更好的開發App,常

原創大資料基礎Spark(7)spark讀取檔案split過程(即RDD分割槽數量)

spark 2.1.1 spark初始化rdd的時候,需要讀取檔案,通常是hdfs檔案,在讀檔案的時候可以指定最小partition數量,這裡只是建議的數量,實際可能比這個要大(比如檔案特別多或者特別大時),也可能比這個要小(比如檔案只有一個而且很小時),如果沒有指定最小partition數量,初始化完成的

原創python倒排索引查詢包含某主題或單詞的檔案

什麼是倒排索引? 倒排索引(英語:Inverted index),也常被稱為反向索引、置入檔案或反向檔案,是一種索引方法,被用來儲存在全文搜尋下某個單詞在一個文件或者一組文件中的儲存位置的對映。它是文件檢索系統中最常用的資料結構。通過倒排索引,可以根據單詞快速獲取包含這個單詞的文件列表。倒排索引主要由兩個部分

原創Zend Framework 2框架MVC

spa lov gef rst 當前 mage 匿名函數 skeleton 一個 ZendFramework 2框架之MVC作者:sys(360電商技術組)1.前言Zend Framework 2是zend官方推出的php開源框架,基於php5.3。他全然採用面向對象的代

原創小程序開發教程2、小程序域名配置申請支持SSL(https)

證書頒發 分享圖片 tro get 操作方法 alt 賽門鐵克 似的 http 要把一個網站對接進小程序,一、網站的域名必須通過備案(ICP備案)。在買域名的時候,各個域名服務商都有提供相應的備案平臺,可以方便的提交備案。工信部官網:http://www.miitbeian

原創分布式redis復習精講

復雜 雙緩存 緩存 方便 參數 過期策略 內心 線程 註意 引言 為什麽寫這篇文章? 博主的《分布式之消息隊列復習精講》得到了大家的好評,內心誠惶誠恐,想著再出一篇關於復習精講的文章。但是還是要說明一下,復習精講的文章偏面試準備,真正在開發過程中,還是腳踏實地,一步一個腳印

區塊鏈TOP1重入漏洞自我理解原創

bubuko ont 國內 編程語言 credit 導致 被攻擊 復合 我們 最近在研究區塊鏈方面的漏洞,智能合約top 1重入漏洞。在網上找了很多相關的文章,發現大部分都是通過代碼進行分析。話說,我們不了解平臺,只是熟悉代碼,只知其原理不知其過程,不便於我們的漏洞理解。

原創C# API 未能創建 SSL/TLS 安全通道 問題解決

分享圖片 proto 執行 manager ima com 添加 poi ssl 在調用執行API之前添加以下代碼就行了 System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls1

原創Redis高階功能 慢查詢

一、何為慢查詢? 慢查詢功能可以有效地幫助我們找到 Redis 可能存在的瓶頸 要想理解慢查詢的定義是什麼,我們可以參見下圖。當我們在客戶端傳送命令給 Redis之後,Redis 需要對這些查詢進行排隊處理。如果這條查詢命令在內部執行的時間超過了已經配置好的時限,那麼這條命令(查詢)

原創Irp佔坑保護檔案不被刪除

Irp操作出自125096的部落格 http://blog.csdn.net/qq125096885/article/details/53033896 這裡提下 博主的例子中使用irpclose檔案物件,這可能會造成藍屏。 見連結:https://bbs.pediy.com/thr

筆記window下 使用c++遍歷資料夾及其子資料夾和檔案,並列印檔案路徑及各檔案內容

這兩天一直在學習如何使用c++遍歷資料夾、讀取檔案內容和寫入檔案。 話不多說,直接上程式碼 /** 檔案功能:遞迴遍歷資料夾,遍歷資料夾及其子資料夾和檔案.列印資料夾名稱、檔名稱和檔案數目*** 參考:https://www.cnblogs.com/collectionne/p/679230

tftp下載檔案為中文名原創

author :張繼飛 在專案中通過tftp下載檔案時會有中文名稱的問題,上位機發送下來IP地址與檔名,本地程式將檔名以字串的形式拼起來,結果呼叫tftp 時,去server下載提示檔案不存在,後來經過仔細驗證,發現上位機發下來的是utf8編碼的檔名,但通過手動tftp 去下載檔案,抓包發現一個

原創利用“程序注入”實現無檔案不死webshell

引子   上週末,一個好兄弟找我說一個很重要的目標shell丟了,這個shell之前是通過一個S2程式碼執行的漏洞拿到的,現在漏洞還在,不過web目錄全部不可寫,問我有沒有辦法搞個webshell繼續做內網。正好我之前一直有個通過“程序注入”來實現記憶體webshell的想法,於是就趁這個機會以Java為例做

原創C#的定時器使用詳解

定時器是程式開發中必不可少的一員,無論是微控制器/ARM,還是上位機,理清不同的定時器之間的差異可以避免進坑~ 那麼我們就來分析分析C#中常見的三種定時器: Windows.Form.Timer 首先我們使用這個系統定時器,間隔設定為200ms。 Th

原創需求評審實戰演練

一 我在面試時,經常會出一道簡易計算器需求的程式設計題,完了之後再讓寫一下這個需求的用例,題目看起來很簡單,但是幾乎可以把我想了解到的基礎測試理論全部都涵蓋了。 今天我還拿這個例子來實操下在《測試人員參與需求評審的價值是什麼?》中提到的需求評審關注點。 比如我現