1 硬件方案
1.1 ENC28J60
1.1.1 基于ENC28J60的LwIP方案移植
- ENC28J60初始化
- netif_add()函数来完成网卡的注册
- ethernetif.c
low_level_init 函数主要完成网卡的复位、协议栈网络接口管理结构体netif中相关字段的初始化low_level_output函数用于发送数据,将 LWIP 协议栈准备好的数据通过网卡发送出去,先将 pbuf 结构的数据放到buffer中,然后调用函数ENC28J60_Packet_Send()发送数据low_level_input函数是从网卡中提取数据,并将数据封装在 pbuf 结构体中供 LWIP 使用,函数 low_level_input()首先调用函数ENC28J60_Packet_Receive()接收网络数据,然后将数据打包成 pbuf 结构,然后将这个 pbuf 返回,low_level_input 函数就是完成这个功能的- 从网络缓冲区中读取接收到的数据包并将其发送给LWIP处理
- LWIP 内核中有许多的周期性的定时器,相对应的定时处理函数也需要被周期性调用的,因为没有使用操作系统,所有需要我们自己使用定时器来实现。比如:使用 STM32F103 定时器3提供这个系统时钟,定时器 3 定时周期为 10ms,定时器 3 的中断服务函数如下,lwip_localtime 是一个全局变量,在 lwip_comm.c 文件中有定义
- lwip初始化
1.2 W5500
- 移植类似,参考ENC28J60
2 轻量化嵌入式协议栈LwIP
2.1 LwIP主要特点
- LwIP 全名:Light weight IP,意思是
轻量化的 TCP/IP 协议,是瑞典计算机科学院 (SICS)的 Adam Dunkels 开发的一个小型开源的 TCP/IP 协议栈。 - LwIP 的设计初衷是:用少量的资源消耗实现一个较为完整的 TCP/IP 协议栈,其中“完整”主要指的是 TCP 协议的完整性,实现的重点是在保持 TCP 协议主要功能的基础上减少对 RAM 的占用。此外 LwIP既可以移植到操作系统上运行,也可以在无操作系统的情况下独立运行。
2.2 LwIP在嵌入式中使用优点
-
- 资源开销低,即轻量化。LwIP 内核有自己的内存管理策略和数据包管理策略,使得内核处理数据包的效率很高。另外,LwIP 高度可剪裁,一切不需要的功能都可以通过宏编译选项去掉。
LwIP 的流畅运行需要 40KB 的代码 ROM 和几十KB的RAM,这让它非常适合用在内存资源受限的嵌入式设备中。
- 资源开销低,即轻量化。LwIP 内核有自己的内存管理策略和数据包管理策略,使得内核处理数据包的效率很高。另外,LwIP 高度可剪裁,一切不需要的功能都可以通过宏编译选项去掉。
-
- 支持的协议较为完整。几乎支持 TCP/IP 中所有常见的协议,这在嵌入式设备中早已够用。
-
- 实现了一些常见的应用程序:DHCP 客户端、DNS客户端、HTTP 服务器、MQTT 客户端、TFTP 服务器、SNTP 客户端等等。
-
- 同时提供了
三种编程接口:RAW API、NETCONN API(注:NETCONN API即为 Sequential API,为了统一,下文均采用 NETCONN API)和Socket API。这三种 API的执行效率、易用性、可移植性以及时空间的开销各不相同,用户可以根据实际需要,平衡利弊,选择合适的 API进行网络应用程序的开发。
- 同时提供了
-
高度可移植。其源代码全部用 C实现,用户可以很方便地实现跨处理器、跨编译器的移植。另外,它对内核中会使用到操作系统功能的地方进行了抽象,使用了一套自定义的 API,用户可以通过自己实现这些 API,从而实现跨操作系统的移植工作。
-
开源、免费,用户可以不用承担任何商业风险地使用它。
-
- 相比于嵌入式领域其它的 TCP/IP 协议栈,比如 uC-TCP/IP、FreeRTOS-TCP 等,LwIP 的发展历史要更悠久一些,得到了更多的验证和测试。LwIP 被广泛用在嵌入式网络设备中,国内一些物联网公司推出的物联网操作系统,其 TCP/IP 核心就是 LwIP;物联网知名的WiFi模块 ESP8266,其 TCP/IP 固件,使用的就是 LwIP。
3 提高 LwIP 网络传输的速度
- 如果按照 LwIP 默认的配置,是远不可能达到我们实验所显示的速度的,因为还没优化,那肯定也是不稳定的,下面我们来看看优化的参数,首先,网速必然受限于硬件,只有硬件是很好的,那么软件才能优化的更好,网卡肯定要选择好一点的网卡,然后在工程中的
stm32f4xx_hal_config.h 文件中配置以太网发送和接收的缓冲区大小,默认是 4,我们可以稍微改大一点 - 对 LwIP
管理的内存肯定要分配的大一些, - 而对于发送数据是存储在 ROM 或者静态存储区的时候,还要将
MEMP_NUM_PBUF宏定义改的大一点,当然发送缓冲区大小和发送缓冲区队列长度决定了发送速度的大小,根据不同需求进行配置,并且需要不断调试, - 而对于接收数据的配置,应该配置 TCP 缓冲队列中的报文段数量与 TCP 接收窗口大小,特别是接收窗口的大小,这直接可以影响数据的接收速度。
- 想要整个 LwIP 能高速平稳运行,只配置这些是不够的,比如我们应该
使用中断的方式接收数据,这就省去了 CPU查询数据,而且,我们应该将内核邮箱的容量增大,这样子在接收到数据之后,投递给内核就不会因为无法投递而阻塞,同时内核线程的优先级应该设置得更高一点,这样子就能及时去处理这些数据,