本人使用的LWIP版本號(hào)是LWIP 1.3.2 ,并且使用UCOSII V2.89系統(tǒng)。
在移植使用的過(guò)程中,使用LWIP只做客戶端或服務(wù)端是沒(méi)有問(wèn)題的。
后來(lái)客戶端和服務(wù)端都集合使用的時(shí)候,碰到了一個(gè)BUG, for(pcb =tcp_active_pcbs; pcb != NULL; pcb = pcb->next) , 在這個(gè)地方進(jìn)入死循環(huán)了, 即pcb 塊申請(qǐng)和釋放的時(shí)候出錯(cuò)了,pcb->net指向自己本身了。后來(lái)在網(wǎng)上查了一大堆資料, 說(shuō)是LWIP1.3.2版本就有這個(gè)問(wèn)題,而1.4.1版本沒(méi)有。
為了解決這個(gè)問(wèn)題就嘗試去移植LWIP1.4.1這個(gè)版本,然后卻發(fā)現(xiàn)1.4.1與1.3.2版本的郵箱和信號(hào) 量函數(shù)接口都不同了,在UCOSII,V2.8.9下已經(jīng)不能滿足了。相當(dāng)于之前移植的sys_arch.c已經(jīng) 不能適應(yīng)了。LWIP1.4.1在網(wǎng)上的sys_arch.c例子基本都是基于UCOSIII-V3.0.x 來(lái)實(shí)現(xiàn)。所有如果 更換LWIP1.4.1的話,最好也要去替換UCOSII。而又由于之前的工程中已有使用UCOSII,再去替 換工作量又相當(dāng)大,所有想找到一種方式,直接在LWIP1.3.2版本下解決LWIP的pcb->net指向自己 本身的問(wèn)題。
后來(lái)發(fā)現(xiàn)這個(gè)問(wèn)題是由于LWIP里面的TCP塊在沒(méi)有接連的情況下,不用close就會(huì)自動(dòng)釋放。如果LWIP 自己釋放過(guò)了,而你自己又操作close或abort釋放一次,那么TCP_PCB內(nèi)存塊就出現(xiàn)問(wèn)題了。那么問(wèn)題 既然找到了,那就想辦法解決。本人想到了一個(gè)修改最少最簡(jiǎn)便的方法來(lái)解決這個(gè)問(wèn)題,僅需修改 2個(gè).c、1個(gè).h文件即可解決這個(gè)問(wèn)題。修改情況如下:
需改內(nèi)容 | | | | | /* 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 結(jié)構(gòu)體中增加一個(gè)字段,pcb_used。這個(gè)字段值 = 0 或 = 1。 0代表這個(gè)TCP_PCB塊沒(méi)有在使用,已經(jīng)釋放。 1代表這個(gè)TCP_PCB塊正在使用,占用內(nèi)存。 | | 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); ..............................省略...................................... SYS_ARCH_UNPROTECT(old_level); } | 在釋放TCP_PCB塊的時(shí)候,如果pcb_used==0,那么這個(gè)TCP_PCB塊已經(jīng)釋放過(guò)了,可能是沒(méi)連接的塊系統(tǒng)自己釋放,也能是自己誤操作,多次釋放?傊还苁裁丛,已經(jīng)釋放過(guò)的不能再釋放了,所有這邊直接return退出。沒(méi)有釋放的正常釋放,只是字段pcb_used置0。 | | struct tcp_pcb * tcp_alloc(u8_t prio) { struct tcp_pcb *pcb; u32_t iss; pcb = memp_malloc(MEMP_TCP_PCB); if (pcb == NULL) { ..............................省略...................................... } if (pcb != NULL) { memset(pcb, 0, sizeof(struct tcp_pcb)); ..............................省略...................................... pcb->keep_cnt_sent = 0; pcb->pcb_used = 1; } return pcb; } | 在申請(qǐng)TCP_PCB塊的時(shí)候,把pcb_used置1,標(biāo)記這個(gè)塊目前正在使用,占用內(nèi)存。 |
現(xiàn)在只需要在,structtcp_pcb中添加一個(gè)字段,再加上幾行代碼,就可以解決這個(gè)問(wèn)題了。
|