如今,TCP/IP協議的應用無處不在。隨着物聯網的火爆,嵌入式領域使用TCP/IP協議進行通信也愈來愈普遍。在咱們的相關產品中,也都有應用,因此咱們結合應用實際對相關應用做相應的總結。html
1、技術準備編程
咱們採用的開發平臺是STM32F407和LwIP協議棧。在開始以前,咱們須要作必要的準備工做。api
首先要得到LwIP的源碼,在網上有不少,不一樣版本及不一樣平臺的都有,不過咱們仍是建議直接從官方網站得到。其官方網站以下:網絡
http://savannah.nongnu.org/projects/lwip/多線程
其次,須要硬件平臺,咱們採用了STM32F407ZG+DM9161的網絡接口方式,這並非必須的,其餘硬件平臺也是同樣的。函數
最後,由於咱們後面要在操做系統下移植,採用的操做系統是FreeRTOS,因此還需下載FreeRTOS的源碼。一樣簡易從官網下載:性能
https://www.freertos.org/index.html測試
2、LwIP簡要說明優化
LwIP是一款免費的TCP/IP協議棧,但它的功能趨勢十分完備。LwIP 具備三種應用編程接口 (API):網站
對於以上三種接口,前一種只須要裸機便可調用,後兩種須要操做系統才能調用。因此據此LwIP存在兩種移植方式:一是,只移植內核,此時應用程序的編寫只能基於RAW/Callback API進行。二是,移植內核和上層API,此時應用程序編寫可使用3種API,即:RAW/Callback API、Sequential API和Socket API。
3、LwIP的無操做系統基本移植
在移植以前,咱們須要對源碼有一些瞭解,以及清楚API如何使用,才能進行很好的移植。在源碼的文件中有兩個文本文件:rawapi.txt和sys_arch.txt。在rawapi.txt文件中,做者說明了怎樣使用協議棧的Raw/Callback API進行編程。而在sys_arch.txt文件中,說明了如何移植,規定了移植者須要實現的函數宏定義等。接下來咱們就據此來實現移植。
其實,進行無操做系統的移植,所須要作的工做並很少,一是須要定義幾個協議在所須要的頭文件。二是須要編寫網卡的驅動程序,而寫驅動程序是主要工做所在。
首先咱們說須要定義的頭文件。根據sys_arch.txt文件中的要求,咱們須要實現cc.h、lwipopts.h和perf.h三個頭文件,線描述以下:
其次要實現網卡的驅動,事實上咱們採用STM32F407自帶的網卡,以及ST的開發庫時,驅動大部分都寫好了,咱們只須要完成硬件IO部分的配置以及一些必要的參數配置就能夠了。
接下來就是實現幾個必要的函數,按照LwIP做者給出的模板,須要實現5個函數以下:
以上這些函數都實現後,咱們須要使協議運轉起來,因此咱們還須要作兩件事,一是對協議及網卡初始化;二是實現對數據的輪詢,固然也可以使用中斷方式,不過在這裏咱們使用查詢方式。
初始化部分,除了初始化默認網絡接口的參數外,須要註冊2個函數,一是初始化網絡接口函數ethernetif_init;一是數據包接收函數ethernet_input。實現以下:
1 /* LwIP初始化配置 */ 2 void LWIP_Init_Configuration(void) 3 { 4 /* IP賦值 */ 5 IP_ADDRESS[0] = 192; 6 IP_ADDRESS[1] = 168; 7 IP_ADDRESS[2] = 2; 8 IP_ADDRESS[3] = 110; 9 NETMASK_ADDRESS[0] = 255; 10 NETMASK_ADDRESS[1] = 255; 11 NETMASK_ADDRESS[2] = 255; 12 NETMASK_ADDRESS[3] = 0; 13 GATEWAY_ADDRESS[0] = 192; 14 GATEWAY_ADDRESS[1] = 168; 15 GATEWAY_ADDRESS[2] = 2; 16 GATEWAY_ADDRESS[3] = 1; 17 18 /* 在無操做系統環境下初始化LwIP協議棧 */ 19 lwip_init(); 20 21 /* 固定IP地址初始化(IPv4) */ 22 IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]); 23 IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]); 24 IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]); 25 26 /* 添加無操做系統的網絡接口參數 */ 27 netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); 28 29 /* 註冊缺省的網絡接口 */ 30 netif_set_default(&gnetif); 31 32 if (netif_is_link_up(&gnetif)) 33 { 34 /* 鏈接正常時,啓用網絡接口 */ 35 netif_set_up(&gnetif); 36 } 37 else 38 { 39 /* 鏈接故障時,中止網絡接口 */ 40 netif_set_down(&gnetif); 41 } 42 43 } 44 初始化完成須要調用ethernetif_input接收數據才能實現通信,其實現很簡單。 45 /* 以太網輪循處理函數 */ 46 void EthernetProcess(void) 47 { 48 ethernetif_input(&gnetif); 49 50 /* 無操做系統超時檢測 */ 51 sys_check_timeouts(); 52 53 }
這樣每次查詢都會檢查是否有數據收到,並經過ethernet_input函數發送到協議棧進行處理。其實,可能你們會發現還有一個sys_check_timeouts()函數,它是一個超時檢測函數,要求調用一個名爲sys_now()的函數來返回系統時鐘,而sys_now()函數是咱們須要實現的,各個系統複雜程度不一樣,在這裏咱們使用了STM32的HAL庫,因此實現就很簡單了。
4、結論
前面已經完成了無操做系統LwIP的移植,那怎麼知道咱們的移植是否成功呢?接下來咱們對它進行必要的驗證。
首先咱們查看目標板在網絡上的配置是否正確。咱們打開命令行窗口,運行ipconfig命令,查看MAC地址和IP地址配置:
咱們配置的MAC地址00:08:E1:00:00:00和IP地址192.168.2.110顯示正常。接下來咱們採用ping命令測試網絡連接:
上圖顯示網絡鏈接正常,說明咱們的LwIP在無操做系統狀況下移植正常。
歡迎關注: