LWIP_簡記(6.走一遍初始化)

LWIP一句話記住就行:
一項工程,兩份配置,三種內存分配,四套操作API,五步初始化,六個"數據流",七個數據結構
-------------------------------------------

前面在第一節乃至後面每一篇我都在強調五步初始化,第三節也實操了一下.
今天呢就詳細的再來講一下這五步初始化的具體操作.

1.xxx_init(網絡驅動,一般由具體廠商弄,比如BCM,RTL,AW...) 
2.tcpip_init(lwip的初始化流程了) 
3.lwip_init(就是一些通用協議,內存,網卡的初始化調用) 
4.netif_init(網卡的初始化,同上步還有很多同級的初始化操作) 
5.ethernetif_init(底層硬件初始化,上面的netif可以理解爲抽象的網卡)

1.xxx_init()

這裏我們還是借鑑博通的ap6203來看:

static int bcm_cmd_wifi_init(rt_uint32_t argc, char** argv)                                                                             
{                                                                                                                                       
    rt_kprintf("argc=%d\n", argc);                                                                                                      
    if (argc > 1)                                                                                                                       
    {                                                                                                                                   
        ++argv;                                                                                                                         
        --argc;                                                                                                                         
    }                                                                                                                                   
                                                                                                                                        
    tcpip_init(NULL, NULL);                                                                                                             
                                                                                                                                        
#ifdef USE_POLLING_MODE                                                                                                                 
        mhd_config_polling(1);                                                                                                          
        mhd_config_polling_interval(50);                                                                                                
#endif                                                                                                                                  
    bcm_wifi_start();                                                                                                                   
    return 0;                                                                                                                           
}                                                                                                                                       
MSH_CMD_EXPORT_ALIAS(bcm_cmd_wifi_init, bcm_init, Broadcom WiFi Init commands);

這裏我們可以主要分兩個部分:
1.tcpip_inti()進行協議棧的初始化,也就是後面會提到的lwip_init().
2.mhd_xxx()以及bcm_xxx()這些都是博通網卡的初始化,你可以理解爲硬件操作,當然啦這都是不開源的,所以我也沒辦法幫大家分析了.
但你們知道的我總會給大家帶來點特別的東西.於是翻山越嶺,終於在<嵌入式網絡那些事LWIP協議>一書中找到了一個RTL8019的網卡初始化:

/************************************
**函數名:board_init
**輸入參數:無
**輸出參數:無
**功能描述:網卡復位與初始化函數
**************************************/
void board_int(void)
{
NE_RESET = 0x11;
Delay(500);
NE_CR = ENCR_PAGE0 + ENCR_NODMA;
NE_DCR = NEDCRVAL;
NE_TPSR = TX_START_PG;
NE_PSTART = RX_START_PG;
NE_STOP = RX_STOP_PG;
NE_BNRY = RX_START_PG;
...

本來想着把代碼全部粘貼上來,仔細一看就不要佔用我的版面了.因爲看不懂,所以我就簡單的告訴大家,這就是廠商自己整出來操作一下寄存器.如果你恰好在博通,聯發科,正基...這些公司,那就更不需要我說了,但是如果不是,哈哈就直接忽略吧.記住有這麼一個過程就好.
值得一提的是:
MSH_CMD_EXPORT_ALIAS(bcm_cmd_wifi_init, bcm_init, Broadcom WiFi Init commands);
可以看到集成了一條命令,bcm_init.那麼我們可以猜想一下,肯定還有聯網,斷開,掃描...命令,類似wifimanager.

2.tcpip_init()

好了我們接着來看重點:lwip/src/api/tcpip.c

/**
 * @ingroup lwip_os
 * Initialize this module:
 * - initialize all sub modules
 * - start the tcpip_thread
 *
 * @param initfunc a function to call when tcpip_thread is running and finished initializing
 * @param arg argument to pass to initfunc
 */
void
tcpip_init(tcpip_init_done_fn initfunc, void *arg)
{
  lwip_init();
                                                                                                                                                                       
  tcpip_init_done = initfunc;
  tcpip_init_done_arg = arg;
  if (sys_mbox_new(&tcpip_mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
    LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
  }
#if LWIP_TCPIP_CORE_LOCKING
  if (sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
    LWIP_ASSERT("failed to create lock_tcpip_core", 0);
  }
#endif /* LWIP_TCPIP_CORE_LOCKING */
 
  sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, RT_THREAD_PRIORITY_MAX-1);
}

1.調用lwip_init()初始化sub modules.
2.利用sys_mbox_new()創建一個郵箱.
3.利用sys_mutex_new()創建一個鎖.
4.利用sys_thread_new()創建一個tcpip_thread線程.

/**
 * The main lwIP thread. This thread has exclusive access to lwIP core functions
 * (unless access to them is not locked). Other threads communicate with this
 * thread using message boxes.
 *                                                                                                                                                                     
 * It also starts all the timers to make sure they are running in the right
 * thread context.
 *
 * @param arg unused argument
 */
static void
tcpip_thread(void *arg)
{
  struct tcpip_msg *msg;
  LWIP_UNUSED_ARG(arg);
 
  LWIP_MARK_TCPIP_THREAD();
 
  LOCK_TCPIP_CORE();
  if (tcpip_init_done != NULL) {
    tcpip_init_done(tcpip_init_done_arg);
  }
 
  while (1) {                          /* MAIN Loop */
    LWIP_TCPIP_THREAD_ALIVE();
    /* wait for a message, timeouts are processed while waiting */
    TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg);
    if (msg == NULL) {
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));
      LWIP_ASSERT("tcpip_thread: invalid message", 0);
      continue;
    }
    tcpip_thread_handle_msg(msg);
  }
}

這裏我也只把代碼先貼出來,後面也會單獨來分析.總之tcpip_init()大家先記住上面這四步就行了,重要的兩步後面會詳細分析.

3.lwip_init()

一些子系統的初始化操作,包括sys,mem,memp,pbuf,tcp,udp,arp…
如果詳細的展開講,那麼篇幅就很長很長了,不過呢我之前在百度腦圖整了個流程分析.
這裏貼上連接,方便大家去跟一下.
https://naotu.baidu.com/file/9a8cb83b68a7ac578aa833079e2f3b83
這裏需要重點提出來的就是netif_init(),緊接着下一節我就會單獨來分析.

4.netif_init()

其實這也只是lwip_init()中調用的而已,只是個人覺得很重要就拿出來了.等下一節具體分析吧.

5.ethernetif_init()

在這裏插入圖片描述
在這裏插入圖片描述
其實這篇博文呢也只是給初始化開個頭,因爲接下來都會一直停留在初始化階段,會結合代碼詳細的分析.大家拭目以待吧.

-------------------------------------------
這期就到這裏了,LWIP想怎麼玩就怎麼玩,我們下期再見.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章