lwip学习日志
lwip学习日志
打算基于正点原子的教程学习lwIP,开发板用的正点原子stm32f407zgt6最小系统板加LAN8720A来实现网络通信
开发IDE使用的是CLion,用的开源的嵌入式编译器:arm-gnu-toolchain-15.3.rel1-mingw-w64-i686-arm-none-eabi
参考书籍:《lwIP开发指南_V1.7.pdf》
网络数据的数据流通

结合这张图,数据从单片机连接的网线到单片机内部去处理,整体逻辑是这样的:
数据以差分信号的形式在网线中传递,直到传递到RJ45网口(外部PHY),然后LAN8720A将其转换成01二进制数据,通过它的RMII接口传递给stm32的mac内核,mac有发送和接收的缓冲区,各一个,每个2KB,(IEEE规定每个帧最大1520B左右,2kB完全够用了),mac内核获取一帧数据后,告诉单片机的DMA,将该帧转移到指定的内存区域,这样的内存区域有多个,每个内存区域由一个DMA描述符(结构体)来控制访问。
- PHY是啥
计算机网络中的物理层,负责光电模拟信号 与 数字信号互转
常用的 PHY 芯片有两种,分别是 LAN8720A 和 YT8512C。
- RMII 是啥
RMII 就是 STM32 内部 MAC 和外部 PHY 之间的“精简版高速数据通道”
- mac又是什么
MAC(介质访问控制) 就是 STM32 内部专门负责“以太网数据打包/拆包”的硬件控制器。
在数据链路层,用于保证通过一个网线连接的两个主机正常通信,通过mac地址来确定目标主机,也有拆分数据报,差错检测,CSMA/CD等功能
具体可看计算机网络的数据链路层
以太网DMA描述符
这个所谓的描述符就是用于控制上面说的内存区域的DMA结构体
分为初级和高级,初级只用前4个,每个成员32位字节,被拆分使用
通过最后的DESC3知道下一个描述符在哪,知道描述符就知道要把数据放到那个内存区域,最后一个描述符的DESC3是第一个描述符的地址,这样形成一个环,可以源源不断的从mac拉去数据到内存
这个描述符的作用相当于是个工具人,那么谁来使用这个工具呢,参考这个结构体
如果把配置以太网比作开一家快递站,ETH_DMADescTypeDef(描述符)是“快递单”,那么 ETH_InitTypeDef 就是“快递站的开业配置清单”。它告诉 STM32 的以太网外设:“你的地址是什么、用什么接口、快递单放在哪里、快递柜多大”。
- uint8_t *MACAddr;
指向一个包含 6 个字节的数组,用来设置开发板的物理地址(MAC 地址)。
- ETH_MediaInterfaceTypeDef MediaInterfac
选择 MAC 和 PHY 之间的硬件接口类型。一般是ETH_MEDIA_INTERFACE_RMII
- ETH_DMADescTypeDef *TxDesc;
就是刚才说的工具人,让它来指定将数据传输到哪块内存区域里
- ETH_DMADescTypeDef *RxDesc;
同上
- uint32_t RxBuffLen;
设置接收缓冲区的大小(通常设为 1524 或 1536 字节,略大于以太网最大帧 1518 字节)。
这里可以看到关于这些描述符的定义,以及赋值等


lwIP移植
虽然lwIP可以通过cubemx极速移植,但是我还是想手动移植体验一下,感觉可以加深印象
lwIP源码网址

添加网卡驱动程序
算了,还是太麻烦,还是略吧,有缘再写
lwIP内存管理
lwIP 提供了两种简单而高效的内存管理机制:动态内存池管理和动态内存堆管理。
- 动态内存堆(Heap):像标准 C 的 malloc/free,能分配任意大小的内存块,灵活但容易产生碎片。
- 动态内存池(Pool):预先切好一堆固定大小的块,分配释放极快,没有碎片,但只适合固定大小的数据结构。
lwIP 也支持使用 malloc 和 free 进行内存分配。然而, lwIP 并不建议使用 C 标准库的内存分配策略。