我使用的 LWIP 版本号是 LWIP 1.3.2 ,并且使用 UCOSII V2.89 系统。
在移植使用的过程中,使用 LWIP 只做客户端或服务端是没有问题的。后来客户端和服务端都集合使用的时
候,碰到了一个 BUG,for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) , 在这个地方进入死循环了,
即 pcb 块申请和释放的时候出错了, pcb->net 指向自己本身了。后来在网上查了一大堆资料,说是
LWIP1.3.2 版本就有这个问题,而 1.4.1 版本没有。为了解决这个问题就尝试去移植 LWIP1.4.1 这个版本,然
后却发现 1.4.1 与 1.3.2 版本的邮箱和信号量函数接口都不同了,在 UCOSII,V2.8.9 下已经不能满足了。相
当于之前移植的 sys_arch.c 已经不能适应了。LWIP1.4.1 在网上的 sys_arch.c 例子基本都是基于 UCOSIII-
V3.0.x 来实现。所有如果更换 LWIP1.4.1 的话,最好也要去替换 UCOSII。而又由于之前的工程中已有使用
UCOSII,再去替换工作量又相当大,所有想找到一种方式,直接在 LWIP1.3.2 版本下解决 LWIP 的 pcb->net
指向自己本身的问题。
后来发现这个问题是由于 LWIP 里面的 TCP 块在没有接连的情况下,不用 close 就会自动释放。如果 LWIP
自己释放过了,而你自己又操作 close 或 abort 释放一次,那么 TCP_PCB 内存块就出现问题了。那么问题既
然找到了,那就想办法解决。本人想到了一个修改最少最简便的方法来解决这个问题,仅需修改 2 个.c、1
个.h 文件即可解决这个问题。修改情况如下:
需改内容 解释
文件名称 添加内容(增加红色字体)
tcp.h /* the TCP protocol control block */
struct tcp_pcb {
/** common PCB members */
IP_PCB;
/** protocol specific PCB members */
TCP_PCB_COMMON(struct tcp_pcb);
..............................省略......................................
/* KEEPALIVE counter */
u8_t keep_cnt_sent;
u8_t pcb_used;
};
在 struct tcp_pcb 结 构 体 中 增 加 一 个 字
段,pcb_used。这个字段值 = 0 或 = 1。
0 代表这个 TCP_PCB 块没有在使用,已经
释放。
1 代表这个 TCP_PCB 块正在使用,占用内
存。
memp.c void
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_used == 0){
return;
}
pcb->pcb_used = 0;
}
SYS_ARCH_DECL_PROTECT(old_level);
在 释 放 TCP_PCB 块 的 时 候 , 如 果
pcb_used==0,那么这个 TCP_PCB 块已经
释放过了,可能是没连接的块系统自己释
放, 也 能是 自己 误 操作 , 多次 释放 。总
之,不管什么原因,已经释放过的不能再
释放了,所有这边直接 return 退出。没有释
放的正常释放,只是字段 pcb_used 置 0。
评论0