lwIP TCP/IP 協議棧筆記之八: 無操作系統移植

目錄

1. lwIP添加到工程

2. 添加頭文件

3. 修改網卡驅動

4. lwIP 時基

5. 協議棧初始化

6. 獲取數據包

6.1 查詢方式

6.2 中斷方式

7. ping 命令和ipconfig命令


1. lwIP添加到工程

如上圖,把源碼中src 添加到工程,並添加LwIP 頭文件路徑。比較簡單,不做贅述

2. 添加頭文件

lwipopts.h、cc.h、pref.h,並放入 新建的/arch 目錄。

在之前有說明相關的配置,這裏直接從“contrib-2.1.0 官方例程中拷貝,並修改。

3. 修改網卡驅動

參考contrib-2.1.0\examples\ethernetif 修改。

4. lwIP 時基

實現sys_now()函數來獲取系統的時鐘,以毫秒爲單位,LwIP 通過兩次獲取的時間就能判斷是否有超時,從而讓內核去處理對應的事件。一般用滴答定時器產生1ms的基準,並關聯該函數。

5. 協議棧初始化

使用LwIP,那就必須先將協議棧初始化,我們就創建一個函數,在函數中初始化協議棧,註冊網卡,設置主機的IP 地址、子網掩碼、網關地址等。

掛載網卡的函數netif_add()。注意器

void LwIP_Init(void)
{
  /* IP addresses initialization */
  /* USER CODE BEGIN 0 */
#ifdef USE_DHCP
  ip_addr_set_zero_ip4(&ipaddr);
  ip_addr_set_zero_ip4(&netmask);
  ip_addr_set_zero_ip4(&gw);
#else
  IP4_ADDR(&ipaddr,IP_ADDR0,IP_ADDR1,IP_ADDR2,IP_ADDR3);
  IP4_ADDR(&netmask,NETMASK_ADDR0,NETMASK_ADDR1,NETMASK_ADDR2,NETMASK_ADDR3);
  IP4_ADDR(&gw,GW_ADDR0,GW_ADDR1,GW_ADDR2,GW_ADDR3);
#endif /* USE_DHCP */
  /* USER CODE END 0 */
    
  /* Initilialize the LwIP stack without RTOS */
  lwip_init();
  
  /* add the network interface (IPv4/IPv6) without RTOS */
  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input);

  /* Registers the default network interface */
  netif_set_default(&gnetif);

  if (netif_is_link_up(&gnetif))
  {
    /* When the netif is fully configured this function must be called */
    netif_set_up(&gnetif);
  }
  else
  {
    /* When the netif link is down this function must be called */
    netif_set_down(&gnetif);
  }

/* USER CODE BEGIN 3 */

/* USER CODE END 3 */
}

  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input);   -->  ethernet_input()

 

6. 獲取數據包

獲取數據包的方式有兩種,一種是查詢方式,另一種是中斷方式。查詢方式通過主函數的while 循環進行週期性處理,去獲取網卡中是否接收到數據包,然後遞交給上層協議去處理,而中斷方式則不一樣,在網卡接收到一個數據包的時候,就觸發中斷,通知CPU 去處理,這樣子效率就會高很多,特別是在操作系統環境下,我們都採用中斷方式去獲取數據包。

方式需底層驅動配置支持,在初始化的時候,如果網卡接收模式被配置爲ETH_RXINTERRUPT_MODE,則表示使用
中斷方式獲取數據包,而如果網卡接收模式被配置爲ETH_RXPOLLING_MODE 則表明用查詢方式獲取數據包。

6.1 查詢方式

使用查詢方式獲取數據包的時候,我們只需要在程序中週期性調用網卡接收函數即可


int main(void)
{
  //板級外設初始化
  BSP_Init();
  
  //LwIP協議棧初始化
  LwIP_Init();  
  
  while (1)
  {
    //調用網卡接收函數
    ethernetif_input(&gnetif);
  
    //處理LwIP中定時事件
    sys_check_timeouts();
  }
}

6.2 中斷方式

中斷方式來接收數據,當接收完成的時候,就通知CPU 來處理即可,效率會比較高

int flag = 0;
int main(void)
{
  //板級外設初始化
  BSP_Init();
  
  //LwIP協議棧初始化
  LwIP_Init();  
  
  while (1)
  {
    if(flag)
    {
      flag = 0;
      //調用網卡接收函數
      ethernetif_input(&gnetif);
    }
    //處理LwIP中定時事件
    sys_check_timeouts();
  }
}
void ETH_IRQHandler(void)
{

  HAL_ETH_IRQHandler(&heth);
  
}

/**
  * @brief  Ethernet Rx Transfer completed callback
  * @param  heth: ETH handle
  * @retval None
  */
extern int flag ;

void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{
  flag = 1;
//  LWIP_Process();
}

7. ping 命令和ipconfig命令

https://blog.csdn.net/XieWinter/article/details/99962809

執行“arp -a”命令,可以看到電腦主機的ARP 表,我們開發板的IP地址與MAC 地址都正確出現在ARP 表。

 

總結:無操作系統移植相對比較簡單,需要主要該方式只能使用lwIP raw API接口

     例程:https://download.csdn.net/download/xiewinter/11588610

 

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