阿韬出品,必属诚品!
背景介绍:
本人用的 raw 在 F407 上使用 LWIP1.32,用的 raw(裸跑)。版本不一定受限与 1.32,可以自己先试试
本人碰到的问题是,stm32 作为客户端,创建多个客户端访问不同的服务端。在频率很高的访问下,容易出
现死机,其实是落入一个死循环里面了。在 tcp.c 中的 tcp_slowtmr()内,然后发现一个程序死在一个 while
循环,应该在 while (pcb != NULL)这一行。是因为每次有 pcb = pcb->next;,然而看 pcb 的地址和 pcb->next
地址一样,所以就一直在里面了。真正的原因是,开启一条到服务器的链接, 但在等待确定链接已经保持的
过程中, 意外被服务器关闭了, 而由于时间太短, 这时候, 应用程序认为 服务器并没有连接上, 然后把这个 tcp
的控制块 abort 掉。而 abort 的时候调用 free 内存的函数, 却不知道这块内存其实已经是 free 掉的了, 再 free
一次, 就会出现 memp_tab 中 元素的 ->next 指回自身.
而这时候再 malloc 一个新内存空间的时候, 由于 next 永远是指回同一块内存区域, 所以导致下次再分配的时
候, 还是分配同一块空间给应用层。
但应用层不知道分配的是同一块空间, 而继续使用, 然后就导致两条链接共用同一个内存区域.. 但 lwip 自己
并不知道.
当两条链接最终注册入同一个 pcbs 链表去管理的时候, 就会导致自己指回自己, 因为本来就是同一块内存,..
最后就 pcb 死循环了
本文档是解决方案,真正遇到这个问题看这个文档比直接用代码效果更好:
在 tcp.h 中,找到 struct tcp_pcb 的一个结构体。在最后
/* KEEPALIVE counter */
u8_t keep_cnt_sent;
u8_t pcb_occupied;
添 加 红 字 , 这 里 只 是 一 个 标 志 位 , TCP_PCB 块 在 使 用 , pcb_occupied = 1 。 TCP_PCB 块 不 使 用 ,
pcb_occupied = 0;
在 memp.c 中,找到 memp_free(memp_t type, void *mem)这个函数,添加红色内容
struct memp *memp;
struct tcp_pcb *pcb;
if(type == MEMP_TCP_PCB ){
pcb = (struct tcp_pcb *)mem;
if(pcb->pcb_occupied == 0){
return;
}
pcb->pcb_occupied = 0;
}
SYS_ARCH_DECL_PROTECT(old_level);
在 tcp.c 中,在 struct tcp_pcb * tcp_alloc(u8_t prio) 函数里面,添加红色内容
pcb->keep_cnt_sent = 0;
pcb->pcb_occupied = 1;
}
评论2