Files

369 lines
11 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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