- 简述
- 下载两个文件:lwip-1.4.1 ,contrib-1.4.1
- 文件下载地址:http://download-mirror.savannah.gnu.org/releases/lwip/
- 没有用MQTT等例程,暂时参照原子教程移植,后续如果用到应用方面再移植lwip2.1.2版本
- 说明
- LWIP内核中有许多的周期性定时器,如TCP定时器、ARP定时器、DHCP定时器
- 将上述定时器封装在一个函数里面,然后周期性调用这个函数
- LWIP协议栈要求每250ms处理一次TCP定时器,5S处理一次ARP定时器,500ms处理一次DHCP精细处理,60处理一次DHCP的粗糙处理
- 根据上述要求编写lwip_periodic_handle()函数,可以完成对lwip内核的定时处理函数的周期性调用
- LWIP的时基由定时器产生,10ms
- 移植步骤
- 添加网卡驱动stm32f7xx_hal_eth.c
- 添加LAN8720驱动:复制原子工程目录里面的lan8720.c和lan8720.h文件
- 添加LWIP源文件
- 添加中间文件:cc.h、cpu.h、perf.h、sys_arch.h、sys_arch.c、ethernetif.c,这几个文件在contrib目录下,此处直接复制例程中的arch文件夹
- 添加LWIP通用文件:lwip_comm.c、lwip_comm.h、lwipopts.h,用于lwip网卡/内核初始化,申请/释放内存、设定IP地址等等,最后一个依据应用裁剪和配置LWIP文件
- 复制例程下的ethernetif.h文件到lwip/src/include/netif目录
- LWIP源码修改
- 替换lwip/lwip1.4.1/src/netif目录下的ethernetif.c文件
- 修改mem.c文件
- 注释掉ram_heap数组
- 定义为指向u8_t的指针
- 修改memp.c文件
- 注释掉memp_memory数组
- 定义为指向u8_t的指针
- 添加如下源码
//得到memp_memory数组大小 u32_t memp_get_memorysize(void) { u32_t length=0; length=( MEM_ALIGNMENT-1 //全局型数组 为所有POOL分配的内存空间 //MEMP_SIZE表示需要在每个POOL头部预留的空间 MEMP_SIZE = 0 #define LWIP_MEMPOOL(name,num,size,desc)+((num)*(MEMP_SIZE+MEMP_ALIGN_SIZE(size))) #include "lwip/memp_std.h" ); return length; }
- lwip动态内存管理技术,有一个内存堆ram_heap和内存池memp_memory,lwip的内存来源
- lwip裁剪与配置
- 协议栈自带的opt.h文件(内部是条件编译)
- 自建一个配置文件lwipopts.h
- lan8720.c文件详解:
- u8 LAN8720_Init(void); PHY芯片初始化
- HAL_ETH_MspInit(); 以太网底层驱动、时钟、引脚配置
- u32 LAN8720_ReadPHY(u16 reg); 读取LAN8720指令寄存器
- void LAN8720_WritePHY(u16 reg,u16 value); 向LAN8720指令寄存器写入指定值
- u8 LAN8720_Get_Speed(void); 获取当前连接速度和双工状态
- u8 ETH_MACDMA_Config(void); 以太网DMA接收中断服务函数
- u8 ETH_Mem_Malloc(void); 获取接收到的帧长度
- void ETH_Mem_Free(void); 申请内存:Rx_Buff、Tx_Buff、DMARxDscrTab、DMATxDscrTab
- u32 ETH_GetRxPktSize(ETH_DMADescTypeDef *DMARxDesc); 释放内存 -----------------------------
- ethernetif.c文件详解
- low_level_init();
- 网卡的复位、协议栈网络接口管理结构体netif中相关字段的初始化、发送和接收DMA描述符链表的初始化,硬件帧校验的开启并且打开以太网
- low_level_output();
- 发送数据,将lwip协议栈准备好的数据通过网卡发送出去
- low_level_input();
- 从网卡中提取数据,并将数据封装在pbuf结构体供lwip使用
- ethernetif_input();
- 主要是对low_level_input()函数做封装,然后将接收到的数据送入指定的网卡结构中
- ethernetif_init();
- 为low_level_init(); 函数的简单封装,并且初始化了netif的相关字段
- low_level_init();
- 软件流程
- 外设初始化
- LWIP内核初始化
- DHCP获取IP地址
- 显示在LCD上
- 主循环中调用lwip_periodic_handle()函数
- 不管DHCP是否完成,都要周期性调用lwip_periodic_handle()函数,
- 这个函数是周期性调用协议栈内核的一些定时函数以满足LWIP内核要求
- 主函数例程
-
/************************************************** * 函数名:main() * 描述 :主函数入口 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **************************************************/ int main(void) { u16 i=0; Cache_Enable(); //打开L1-Cache HAL_Init(); //初始化HAL库 Stm32_Clock_Init(432,25,2,9); //设置时钟,216Mhz delay_init(216); //延时初始化 uart_init(115200); //串口初始化 BSP_LED_Init(); //初始化LED BSP_KEY_Init(); //初始化按键 BSP_SDRAM_Init(); //初始化SDRAM BSP_LCD_Init(); //初始化LCD PCF8574_Init(); //初始化PCF8574 my_mem_init(SRAMIN); //初始化内部内存池 // my_mem_init(SRAMEX); //初始化外部内存池 my_mem_init(SRAMDTCM); //初始化DTCM内存池 POINT_COLOR = RED; BSP_LCD_ShowString(30,30,200,16,16,"Dreamer STM32F4/F7"); BSP_LCD_ShowString(30,50,200,16,16,"Ethernet lwIP est"); BSP_LCD_ShowString(30,70,200,16,16,"Dreamer Catcher"); BSP_LCD_ShowString(30,90,200,16,16,"2020/05/14"); TIM3_Init(1000-1,1080-1); //定时器3初始化,定时器时钟为108M,分频系数为1080-1, //所以定时器3的频率为108M/1080=100K,自动重装载为1000-1,那么定时器周期就是10ms while(lwip_comm_init()) //lwip初始化 { BSP_LCD_ShowString(30,110,200,20,16,"LWIP Init Falied! "); delay_ms(500); BSP_LCD_ShowString(30,110,200,16,16,"Retrying... "); delay_ms(500); } BSP_LCD_ShowString(30,110,200,20,16,"LWIP Init Success!"); BSP_LCD_ShowString(30,130,200,16,16,"DHCP IP configing..."); //等待DHCP获取 #if LWIP_DHCP //使用DHCP while((lwipdev.dhcpstatus!=2)&&(lwipdev.dhcpstatus!=0XFF))//等待DHCP获取成功/超时溢出 { lwip_periodic_handle(); //LWIP内核需要定时处理的函数 } #endif show_address(lwipdev.dhcpstatus); //显示地址信息 while(1) { lwip_periodic_handle(); //LWIP内核需要定时处理的函数 delay_us(200); i++; if(i==2000) { i=0; LED0_Toggle; } } }
-
- 下载验证
- 总结
- 注意, 和 DMARxDscrTab, DMATxDscrTab 一样, 如果使用 F7 芯片的话 Rx_Buff 和 Tx_Buff的内存也一定要放到 DTCM 中,否则的网络也会出问题的。
- 深入学习可参考《嵌入式网络那些事:LwIP协议深度剖析与实战演练》
- 参考资料:
- 正点原子《STM32F767开发指南(HAL库版)》
- 正点原子《STM32F767 LWIP手册》
- 野火《STM32 HAL库开发实战指南》
- 野火《LWIP应用开发实战指南》
- 官方源码
- 硬件平台:
- 正点原子阿波罗F767
- 软件平台:
- MDK5.2.5
- 库版本:
- TM32Cube_FW_F7_V1.4.0
- LWIP版本
- lwip-1.4.1
- contrib-1.4.1
【2】嵌入式TCP/IP协议——————LWIP无系统移植
最新推荐文章于 2024-09-26 16:05:01 发布