369 lines
11 KiB
C
369 lines
11 KiB
C
|
||
#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; i<PBUF_POOL_SIZE; i++){
|
||
p = usr_pbuf_pool_addr[i];
|
||
pbuf_free(p);
|
||
}
|
||
|
||
lwip_stats.memp[14]->err=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;i<MEMP_NUM_TCP_PCB;i++)
|
||
{
|
||
for(j=0;j<MEMP_NUM_TCP_SEG;j++)
|
||
{
|
||
if((usr_tcp_pcb_addr[i]->unsent == (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 <stdio.h>
|
||
#include <stdlib.h>
|
||
|
||
//#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;i<MEMP_NUM_TCP_SEG;i++){
|
||
STATS_PRINT(("seg_addr%2d: 0x%x alloc_id:%4d release_id:%4d \n\t", i,usr_seg_addr[i],usr_seg_addr[i]->claimer_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;i<MEMP_NUM_TCP_SEG;i++){
|
||
sprintf(strBuf,"seg_adr%2d: 0x%x aloc_id:%4d rels_id:%4d \n\t", i,usr_seg_addr[i],usr_seg_addr[i]->claimer_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;i<MEMP_NUM_TCP_PCB;i++){
|
||
if(usr_tcp_pcb_addr[i]->unsent!=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
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|