LWIP______

本文介绍了STM32F4使用LAN8720A和LWIP库进行以太网通讯的实例,并深入解析了LWIP内存管理的动态内存池初始化。通过分析内存池结构和数组偏移计算,展示了如何创建内存池。此外,还探讨了在UDP通信中遇到的限制及解决方案,包括自定义回调函数实现数据收发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 参考资料

STM32F4+LAN8720A+STM32CubeMX+Lwip 网络通讯(以太网通讯)小实例

2. LWIP内存管理

动态内存池初始化分析

在这里插入图片描述
在这里插入图片描述
NOTE: 注意箭头方向,要反过来看这个链表。

根据代码我们知道,初始化好的内存池都会被放到mem_pools中(注意那个逗号,精髓)
在这里插入图片描述
这里不得不提一下memp_t和MEMP_MAX的由来(👍)
在这里插入图片描述

理论分析完,看仿真情况:
在这里插入图片描述
这里就不一 一画线了

如下图所示,数组偏移时为什么是这样计算的?

在这里插入图片描述
那就要从数组的初始化源头说起,如下图所示:
在这里插入图片描述
那么通过这样一个过程,就会创建这样的结构体变量:

const struct memp_desc memp_UDP_PCB = {
	size,
	num,
	memp_memory_UDP_PCB_base, //u8_t *base
	&memp_tab_UDP_PCB //struct memp **tab
};
所以memp_memory_UDP_PCB_base可以理解为下面这张图:

在这里插入图片描述

NOTE: memp_memory_UDP_PCB_base总共131个字节
memp_memory_UDP_PCB_base看似是u8_t类型的数组但是放到并不是单个字节的数据,而是4个
struct udp_pcb var

通过仿真验证理论

在这里插入图片描述

3. udp_rev_callback()自定义函数测试

在这里插入图片描述

这个回调函数很简单,收到udp数据后回复一句"This is reply!",无论我发什么都只会回这一句,于是我改了一下,如下图所示:
在这里插入图片描述
将收到的数据再发回来,于是:

在这里插入图片描述
但是
在这里插入图片描述
这是因为q->payload在申请内存的时候只申请了16个字节,所以最多也只能发16个字节数据。那么这时候是要改 (1) 还是 (2) ?
在这里插入图片描述
如果只改(2)不改(1)且(2)> (1)那么就会出现内存溢出(我试过了,进错误中断),使用了申请之外的内存。
那么就得这么改:
在这里插入图片描述
于是:
在这里插入图片描述

`lwip_send` 是 Lightweight IP (LwIP) 协议栈中的一个关键函数,用于通过 TCP 或 UDP 协议发送数据。该函数的行为取决于所使用的传输层协议,其使用方法和实现细节在不同的上下文中可能有所不同。 在 TCP 协议中,`lwip_send` 会将数据排队等待发送,并尽可能立即尝试发送这些数据,但如果发送缓冲区已满或网络拥塞,数据可能会被延迟发送。该函数返回实际发送的字节数,若返回值小于请求发送的字节数,则可能表示需要稍后重试[^1]。 在 UDP 协议中,`lwip_send` 通常会直接发送数据报文,而不会建立连接或维护状态。由于 UDP 是无连接和不可靠的,因此必须确保数据报的大小不超过最大传输单元(MTU),否则可能会导致数据包丢失或分片[^1]。 ### 使用示例 以下是一个使用 `lwip_send` 的基本示例: ```c err_t lwip_send(int s, const void *data, size_t size, int flags); ``` - `s`:套接字描述符。 - `data`:指向要发送数据的指针。 - `size`:要发送的字节数。 - `flags`:发送标志(通常为 0)。 返回值为实际发送的字节数,若返回负值则表示发生错误。 ```c int sock; const char *message = "Hello, LwIP!"; err_t result = lwip_send(sock, message, strlen(message), 0); if (result < 0) { // 处理错误 } ``` ### 问题排查 当使用 `lwip_send` 遇到问题时,可以检查以下几个方面: 1. **套接字状态**:确保套接字已正确创建并连接(对于 TCP)。未连接的套接字在 TCP 中无法发送数据。 2. **缓冲区大小**:如果发送缓冲区已满,`lwip_send` 可能会返回部分成功或错误码。可以通过调整 LwIP 配置参数(如 `TCP_SND_BUF`)来增加缓冲区大小。 3. **网络连接状态**:确保网络连接正常且远端主机可达。TCP 连接可能会因网络中断而断开。 4. **错误码**:检查 `errno` 或返回值以获取更多错误信息。例如,`ERR_MEM` 表示内存不足,`ERR_CLSD` 表示连接已关闭。 5. **异步操作**:在非阻塞模式下,如果数据无法立即发送,应注册写事件并等待,直到可以继续发送。 ### 调试技巧 - 使用 LwIP 的日志功能(如 `LWIP_DEBUG`)来启用调试输出,查看内部状态和错误信息。 - 检查 LwIP 的统计信息(如 `lwip_stats`)以了解缓冲区使用情况和错误计数。 - 在发送操作失败后,尝试重新连接或重新初始化套接字。 ### 相关函数 - `lwip_sendto`:用于在 UDP 中指定目标地址发送数据。 - `lwip_write`:与 `lwip_send` 类似,但不支持 flags 参数。 - `lwip_sendmsg`:支持发送多个数据块,适用于高级用例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值