#include "config.h" #include "type.h" #include "lwipopts.h" #include "string.h" #include "opt.h" extern struct tcp_pcb *usr_tcp_pcb_addr[MEMP_NUM_TCP_PCB]; extern struct memp *usr_seg_addr[MEMP_NUM_TCP_SEG]; extern struct pbuf *usr_pbuf_pool_addr[PBUF_POOL_SIZE]; static uint32 g_port; #if USE_RESET_TCP #include "lwip/netif.h" #include "stm32f4xx_hal_eth.h" extern struct netif gnetif; /* network interface structure */ extern ETH_HandleTypeDef heth; void usr_close_network(void) { HAL_ETH_Stop(&heth); netif_set_down(&gnetif); } void usr_open_network(void) { netif_set_up(&gnetif); HAL_ETH_Start(&heth); } /* 0.检测tcp_seg的内存是否已经用尽; 1.定位到占用相应tcp_seg的内存对应的tcp_pcb; 2.将tcp_pcb从tcp_pcb_lists中清除; 3.释放相应的tcp_pcb; */ extern struct stats_ lwip_stats; extern struct tcp_pcb *tcp_bound_pcbs; extern union tcp_listen_pcbs_t tcp_listen_pcbs; extern struct tcp_pcb *tcp_active_pcbs; extern struct tcp_pcb *tcp_tw_pcbs; #include "tcp.h" extern void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); static uint16 occupyed_num=0; static uint16 rels_lis_num=0; static uint16 rels_bod_num=0; static uint16 rels_act_num=0; static uint16 rels_tw_num=0; static uint16 checked_times=0; static uint16 reset_pbuf_pool_cnt=0; uint16 get_tcp_seg_errnum(void) { return lwip_stats.memp[4]->err; } uint16 get_tcp_seg_occupy(void) { return (uint16)lwip_stats.memp[4]->used*100/lwip_stats.memp[4]->avail; } uint8 check_pcb_buf_err(void) { if(((lwip_stats.memp[4]->used >= lwip_stats.memp[4]->avail) && (lwip_stats.memp[4]->err >= 50))//tcp_seg ||((lwip_stats.memp[4]->used >= lwip_stats.memp[4]->avail*3/4) && (lwip_stats.memp[4]->err >= 50))){ return 1; } else if((lwip_stats.memp[14]->used >= lwip_stats.memp[14]->avail*3/4) && (lwip_stats.memp[14]->err >= 50)){//pbuf_pool return 2; } else{ return 0; } } void check_and_release_pbuf_pool(void) { struct pbuf *p; uint16 i; for (i=0; ierr=0; reset_pbuf_pool_cnt++; if(reset_pbuf_pool_cnt>=2000)reset_pbuf_pool_cnt=10; } void check_and_release_pcb(void) { struct tcp_pcb *pcb_occupy[MEMP_NUM_TCP_PCB]={NULL}; struct tcp_pcb *poccupy; struct tcp_pcb *pcb; // static uint16 check_cnt=0; uint16 occupy_index=0; uint16 rels_lis_cnt=0; uint16 rels_bod_cnt=0; uint16 rels_act_cnt=0; uint16 rels_tw_cnt=0; uint16 i,j; //定位 for(i=0;iunsent == (struct tcp_seg *)((uint8*)usr_seg_addr[j]+MEMP_SIZE)) ||(usr_tcp_pcb_addr[i]->unacked == (struct tcp_seg *)((uint8*)usr_seg_addr[j]+MEMP_SIZE)) ||(usr_tcp_pcb_addr[i]->ooseq == (struct tcp_seg *)((uint8*)usr_seg_addr[j]+MEMP_SIZE)) ) { pcb_occupy[occupy_index] = usr_tcp_pcb_addr[i]; printf("pcb_occupy:0x%8x\n",pcb_occupy[occupy_index]); occupy_index++; } } } //释放 for(poccupy = pcb_occupy[0],i=0;poccupy!=NULL&&i<50;poccupy=pcb_occupy[i]) { for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { if(pcb==poccupy){//刚好就是被占用的pcb tcp_pcb_remove(&tcp_active_pcbs, pcb); printf("checked and remove tcp form tcp_active_pcb 0x%8x\n",pcb); rels_act_cnt++; break; } } for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { if(pcb==poccupy){//刚好就是被占用的pcb tcp_pcb_remove(&tcp_tw_pcbs, pcb); printf("checked and remove tcp form tcp_tw_pcbs 0x%8x\n",pcb); rels_tw_cnt++; break; } } for (pcb = tcp_bound_pcbs; pcb != NULL; pcb = pcb->next) { if(pcb==poccupy){//刚好就是被占用的pcb tcp_pcb_remove(&tcp_bound_pcbs, pcb); printf("checked and remove tcp form tcp_bound_pcbs 0x%8x\n",pcb); rels_bod_cnt++; break; } } i++; /*for (pcb = (struct tcp_pcb *)tcp_listen_pcbs->pcbs; pcb != NULL; pcb = pcb->next) { if(pcb==poccupy){//刚好就是被占用的pcb //tcp_pcb_remove(&tcp_listen_pcbs, pcb); printf("checked tcp form tcp_listen_pcbs 0x%8x\n",pcb); rels_lis_cnt++; break; } }*/ } lwip_stats.memp[4]->err=0; occupyed_num = occupy_index; checked_times++; rels_lis_num = rels_lis_cnt; rels_bod_num = rels_bod_cnt; rels_act_num = rels_act_cnt; rels_tw_num = rels_tw_cnt; } #endif//USE_RESET_TCP #if USE_UART_CMD_PRINT_LWIP //------------------------------ static char strBuf[100]; extern void uart_send_string(uint32 port,const uint8 *pbuf,uint32 len); void usr_print(const char *pbuf,uint32 len) { uart_send_string(g_port,(uint8 *)pbuf,len); } void usr_lwip_print(char *pbuf,uint32 value) { sprintf(strBuf,pbuf,value); usr_print(strBuf,strlen(strBuf)); } #define STATS_PRINT(x) do {printf x;} while(0) #include #include //#if USE_ETH_DBG extern s_USR_DBG_ETH udbg_eth; //打印自定义的状态 void usr_stats_print() { /*STATS_PRINT(("\n%s\n\t", "usr_eth")); STATS_PRINT(("eth_int: %d\n\t", udbg_eth.eth_int_in_cnt)); STATS_PRINT(("eth_recv_sem: %d\n\t", udbg_eth.eth_recv_sem_cnt)); STATS_PRINT(("eth_tcpip: %d\n\t", udbg_eth.eth_recv_tcpip_cnt)); STATS_PRINT(("eth_tcp_in: %d\n\t", udbg_eth.eth_tcp_in_cnt)); STATS_PRINT(("eth_ip4_in: %d\n\t", udbg_eth.eth_ip4_in_cnt)); STATS_PRINT(("eth_udp_in: %d\n\t", udbg_eth.eth_udp_in_cnt)); STATS_PRINT(("eth_icmp_in: %d\n\t", udbg_eth.eth_icmp_in_cnt)); STATS_PRINT(("eth_tcp_listen: %d\n\t", udbg_eth.eth_tcp_listen_cnt)); STATS_PRINT(("http_accept: %d\n\t", udbg_eth.eth_http_accept_c)); STATS_PRINT(("http_recv: %d\n\t", udbg_eth.eth_http_recv_c)); STATS_PRINT(("http_parse: %d\n\t", udbg_eth.eth_http_parse_c)); STATS_PRINT(("http_sent: %d\n\t", udbg_eth.eth_http_send_c)); STATS_PRINT(("tcp_out: %d\n\t", udbg_eth.eth_tcp_out_c)); STATS_PRINT(("lvl_alloc_err: %d\n\t", udbg_eth.low_level_in_alloc_err)); STATS_PRINT(("memp_tcp_seg_reset: %d\n\t", udbg_eth.memp_tcp_seg_reset_c));*/ usr_lwip_print("\nusr_eth %d\n\t", 0); usr_lwip_print("eth_int: %d\n\t", udbg_eth.eth_int_in_cnt); usr_lwip_print("eth_recv_sem: %d\n\t", udbg_eth.eth_recv_sem_cnt); usr_lwip_print("eth_tcpip: %d\n\t", udbg_eth.eth_recv_tcpip_cnt); usr_lwip_print("eth_tcp_in: %d\n\t", udbg_eth.eth_tcp_in_cnt); usr_lwip_print("eth_ip4_in: %d\n\t", udbg_eth.eth_ip4_in_cnt); usr_lwip_print("eth_udp_in: %d\n\t", udbg_eth.eth_udp_in_cnt); usr_lwip_print("eth_icmp_in: %d\n\t", udbg_eth.eth_icmp_in_cnt); usr_lwip_print("eth_tcp_listen: %d\n\t", udbg_eth.eth_tcp_listen_cnt); usr_lwip_print("http_accept: %d\n\t", udbg_eth.eth_http_accept_c); usr_lwip_print("http_recv: %d\n\t", udbg_eth.eth_http_recv_c); usr_lwip_print("http_parse: %d\n\t", udbg_eth.eth_http_parse_c); usr_lwip_print("http_sent: %d\n\t", udbg_eth.eth_http_send_c); usr_lwip_print("tcp_out: %d\n\t", udbg_eth.eth_tcp_out_c); usr_lwip_print("lvl_alloc_err: %d\n\t", udbg_eth.low_level_in_alloc_err); usr_lwip_print("memp_tcp_seg_reset: %d\n\t", udbg_eth.memp_tcp_seg_reset_c); } #include "memp_priv.h" extern uint8 other_place_call_seg; //打印seg使用状态 void usr_seg_stats_print() { uint8 i=0; /*STATS_PRINT(("\n%s\n\t", "tcp_seg_alloc")); STATS_PRINT(("other_call_seg: %d\n\t", other_place_call_seg)); for(i=0;iclaimer_id,usr_seg_addr[i]->release_id)); }*/ sprintf(strBuf,"\ntcp_seg_alloc\n\t"); usr_print(strBuf,strlen(strBuf)); sprintf(strBuf,"other_call_seg: %d\n\t", other_place_call_seg); usr_print(strBuf,strlen(strBuf)); for(i=0;iclaimer_id,usr_seg_addr[i]->release_id); usr_print(strBuf,strlen(strBuf)); } } #include "tcp.h" #include "memp_priv.h" //打印tcp_pcb使用情况 void usr_tcp_pcb_stats_print() { struct tcp_seg * unsent; struct tcp_seg * unacked; struct tcp_seg * ooseq; uint8 i=0; //STATS_PRINT(("\n%s\n\t", "tcp_pcb_stats")); sprintf(strBuf,"\ntcp_pcb_stats\n\t"); usr_print(strBuf,strlen(strBuf)); for(i=0;iunsent!=NULL){ unsent = (struct tcp_seg *)((uint8*)usr_tcp_pcb_addr[i]->unsent - MEMP_SIZE); }else{ unsent = usr_tcp_pcb_addr[i]->unsent; } if(usr_tcp_pcb_addr[i]->unacked!=NULL){ unacked = (struct tcp_seg *)((uint8*)usr_tcp_pcb_addr[i]->unacked - MEMP_SIZE); }else{ unacked = usr_tcp_pcb_addr[i]->unacked; } if(usr_tcp_pcb_addr[i]->ooseq!=NULL){ ooseq = (struct tcp_seg *)((uint8*)usr_tcp_pcb_addr[i]->ooseq - MEMP_SIZE); }else{ ooseq = usr_tcp_pcb_addr[i]->ooseq; } /*STATS_PRINT(("tcp_pcb ofs %2d: stat-%2d unsend-0x%8x uack-0x%8x ooseq-0x%8x \n\t", i, usr_tcp_pcb_addr[i]->state,unsent,unacked,ooseq));*/ sprintf(strBuf,"tcp_pcb ofs %2d: stat-%2d unsend-0x%8x uack-0x%8x ooseq-0x%8x \n\t", i, usr_tcp_pcb_addr[i]->state,unsent,unacked,ooseq); usr_print(strBuf,strlen(strBuf)); } } #define USR_PRINTF_TIME 1000 // 10s extern void stats_display(void); extern uint32 check_delay_over(uint32 *ptick,uint32 cycle); static void lwip_stats_print(uint32 port) { //static uint32 print_intv; g_port = port; if(1){ //if(check_delay_over(&print_intv,USR_PRINTF_TIME)){ stats_display(); usr_stats_print(); usr_seg_stats_print(); usr_tcp_pcb_stats_print(); /*printf("checked_rels_times:%3d occupy:%3d rels_lis:%3d rels_bod:%3d rels_act:%3d rels_tw:%3d \n",checked_times,occupyed_num, rels_lis_num,rels_bod_num,rels_act_num,rels_tw_num);*/ sprintf(strBuf,"rels_times:%3d occupy:%3d rels_lis:%3d rels_bod:%3d rels_act:%3d rels_tw:%3d \n\t", checked_times,occupyed_num, rels_lis_num,rels_bod_num,rels_act_num,rels_tw_num); usr_print(strBuf,strlen(strBuf)); sprintf(strBuf,"reset_pbufPool:%4d used:%3d \n\t", reset_pbuf_pool_cnt,lwip_stats.memp[14]->used); usr_print(strBuf,strlen(strBuf)); //} } } uint32 protocol_print_lwip_info(uint8 *pbufin,uint32 port) { if(pbufin[3]==0x70) { lwip_stats_print(port); return 0; } return 1; } #endif//USE_UART_CMD_PRINT_LWIP