如今,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在无操做系统状况下移植正常。
欢迎关注: