Appearance
移植
[lwIP - A Lightweight TCP/IP stack - Summary Savannah] (nongnu.org)
从这一个网页里面下载contrib包(移植文件以及示例)和lwIP源码(协议栈的核心文件)
文件
contrib包, 主要使用的是app文件夹, examples文件夹, ports文件夹
core文件:
ipv4文件夹, jpv6文件夹: 相关的源码(DHCP, ARP, ICMP, IGMP)
altcp.c, altcp_alloc.c, altcp_tcp.c: 应用的抽象层, 用于TCP连接的API
def.c: lwIP基础类函数定义, 主机序列和网络序列转换, 字符串查找比较, 整数转字符串
dns.c: 域名解析
inet_chksum.c : 计算校验和功能(计算TCP, IP, UDP协议的校验和)
init.c: 检测宏定义和配置的错误和提示
ip.c: IP协议相关的函数(和文件夹里面的文件相关)
mem.c: 动态内存池管理
memp.c: 静态内存堆管理
netif.c: lwIP网卡的操作, 注册删除, 使能禁用, 设置IP等
pbuf.c: 网络数据包的操作
raw.c: 传输协议框架
stats.c: lwIP里面的内核统计系统
sys.c: sys模块
tcp.c, tcp_in.c, tcp_out.c: tcp相关的操作, TCP连接, 数据包的输入输出, 定时器等
timeouts.c: lwIP内核的超时处理
udp.c: UDP的操作, 连接以及数据包操作
移植
LwIP应用开发笔记之一:LwIP无操作系统基本移植 - Moonan - 博客园 (cnblogs.com)
首先我们说需要定义的头文件。根据sys_arch.txt文件中的要求,我们需要实现cc.h、lwipopts.h和perf.h三个头文件,线描述如下:
- cc.h文件主要完成协议栈内部使用的数据类型的定义,以保证平台无关性。
- lwipopts.h文件包含了用户对协议栈内核参数进行的配置。
- perf.h文件是实现与系统统计和测量相关的功能。
其次要实现网卡的驱动,事实上我们采用STM32F407自带的网卡,以及ST的开发库时,驱动大部分都写好了,我们只需要完成硬件IO部分的配置以及一些必要的参数配置就可以了。
接下来就是实现几个必要的函数,按照LwIP作者给出的模板,需要实现5个函数如下:
- low_level_init 调用以太网驱动函数,初始化 STM32F4xx 和 STM32F2x7xx 以太网外设
- low_level_output 调用以太网驱动函数以发送以太网包
- low_level_input 调用以太网驱动函数以接收以太网包
- ethernetif_init 初始化网络接口结构 (netif, 主要是记录函数句柄)并调用low_level_init以初始化以太网外设
- ethernetif_input 调用low_level_input接收包,然后将其提供给LwIP栈
- sys_now 提供lwIp的时基
以上这些函数都实现后,我们需要使协议运转起来,所以我们还需要做两件事,一是对协议及网卡初始化;二是实现对数据的轮询,当然也可使用中断方式,不过在这里我们使用查询方式。
初始化部分,除了初始化默认网络接口的参数外,需要注册2个函数,一是初始化网络接口函数ethernetif_init;一是数据包接收函数ethernet_input。
这两个函数在netif_add函数里面进行注册
ethernet.c和ethernet.h两个文件包含了以太网驱动初始化和MAC的驱动程序,这里需要用户自己根据自己的以太网芯片进行设置,通过设置以太网句柄ETH_HandleTypeDef进行设置。
添加系统
移植freertos
lwip添加sys_arch.c/h文件
之后需要更改文件
- lwipopts.h文件里面的配置, 实际是使用stm32的配置文件, 之后把里面的LWIP_PROVIDE_ERRNO选项改为1,FW_F4V1.26.0\Projects\STM32469I_EVAL\Applications\LwIP\LwIP_HTTP_Server_Netconn_RTOS\Inc\lwipopts.h文件进行替换
- cc.h文件里面有一个重复的变量, 把里面的
typedef int sys_prot_t;
进行注销, 重复定了 - lwip_comm.c/h 把里面的lwip_periodic_handle函数删除(这是一个轮询函数)和修改lwip_comm_init函数, 把开启DHCP处理放在启动任务里面(之前是在main函数里面)
- ethernetif.h/c文件改为使用操作系统的网卡驱动, 主要是low_level_init函数以及ethernetif_input函数, 添加信号量
- ethrnet.c中断优先级, 使得FreeRTOS里面的函数可以在中断里面使用
实际使用时候把low_level_init函数注册为一个任务, 中断里面释放信号量