lwIP UDP消息传递-在PBUF#uPool#u大小乘以PBUF#x27之后,接收器停止工作;他们被释放了
我在STM32芯片上使用lwIP来实现UDP回波。(我从DHCP模块复制了很多代码,它似乎工作得很好。)我有一个简单的Python脚本作为ECHO服务器 我在NO_SYS模式下运行-所有东西都是从主循环调用的 在发送请求后,服务器会做出响应(我在wireshark中看到了这一点),但接收到的数据包根本不会被lwIP接收到 N可以通过更改配置变量PBUF_POOL_SIZE可靠地进行更改,因此您可能认为PBUF在使用后没有被释放,因此池将耗尽。但事实似乎并非如此 我正在使用的实现(与DHCP一样)是使用相同的pcb和pbuf对进行发送和接收。代码如下所示:lwIP UDP消息传递-在PBUF#uPool#u大小乘以PBUF#x27之后,接收器停止工作;他们被释放了,udp,stm32f4,lwip,Udp,Stm32f4,Lwip,我在STM32芯片上使用lwIP来实现UDP回波。(我从DHCP模块复制了很多代码,它似乎工作得很好。)我有一个简单的Python脚本作为ECHO服务器 我在NO_SYS模式下运行-所有东西都是从主循环调用的 在发送请求后,服务器会做出响应(我在wireshark中看到了这一点),但接收到的数据包根本不会被lwIP接收到 N可以通过更改配置变量PBUF_POOL_SIZE可靠地进行更改,因此您可能认为PBUF在使用后没有被释放,因此池将耗尽。但事实似乎并非如此 我正在使用的实现(与DHCP一样)
typedef enum SIGNAL_STATE {
SIGNAL_STATE_IDLE, // 0
SIGNAL_STATE_WAIT_ACK, // 1
} SIGNAL_STATE;
void send_app_broadcast_msg(char *msg);
static void app_inc_pcb_refcount(void);
static void app_dec_pcb_refcount(void);
void rcv_app_msg(void *arg, struct udp_pcb *pcb, struct pbuf *p,
const ip_addr_t *addr, u16_t port);
SIGNAL_STATE signal_state = SIGNAL_STATE_IDLE;
// allocation and ref counting, copied from DHCP code
static struct udp_pcb *pcb_out = NULL;
struct pbuf *p_out = NULL;
static u8_t app_pcb_refcount = 0;
static char *msg = "MSG #17";
static uint32_t rx_flag = 0;
static uint32_t timeout_ctr = 0;
void app_send_signal(void)
{
// send "button" was pressed, what to do?
switch (signal_state) {
case SIGNAL_STATE_IDLE :
rx_flag = 0;
send_app_broadcast_msg(msg);
signal_state = SIGNAL_STATE_WAIT_ACK;
break;
case SIGNAL_STATE_WAIT_ACK:
// double press, ignore
break;
default:
// illegal state, fatal error!
fatal_error("%s : Illegal State: %d\n", __func__, signal_state);
break;
}
}
void app_check_timeouts(void){
// this is called every half second by the main loop
uint8_t c = 0;
uint32_t end_flag = 0;
// handle msg response and timeout
switch (signal_state) {
case SIGNAL_STATE_IDLE :
// do nothing
break;
case SIGNAL_STATE_WAIT_ACK:
timeout_ctr++;
if (rx_flag){
xprintf("OK\n");
end_flag = 1;
} else if ( timeout_ctr > PIXEE_TIMEOUT ) {
xprintf("TIMED OUT\n");
end_flag = 1;
}
if (end_flag)
{
c = pbuf_free(p_out);
xprintf("p_out=%d ref=%d, c=%d\n", p_out, p_out->ref, c);
app_dec_pcb_refcount();
p_out = NULL;
pcb_out = NULL;
timeout_ctr = 0;
rx_flag = 0;
signal_state = SIGNAL_STATE_IDLE;
}
break;
default:
// illegal state, fatal error!
fatal_error("%s : Illegal State: %d\n", __func__, signal_state);
break;
}
}
void send_app_broadcast_msg(char *msg)
{
uint32_t sz = strlen(msg);
if ( sz > APP_MAX_MSG_SIZE )
{
fatal_error("%s : requested message too large (%d, %d) \n", __func__, sz, APP_MAX_MSG_SIZE);
}
xprintf("sending broadcast msg \"%s\"... ", msg);
pixee_inc_pcb_refcount();
if ( pcb_out == NULL )
{
fatal_error("%s : could not allocate out pcb\n", __func__);
}
ip_set_option(pcb_out, SOF_BROADCAST);
udp_bind(pcb_out, IP4_ADDR_ANY, APP_PORT_NUM);
udp_connect(pcb_out, IP4_ADDR_ANY, APP_PORT_NUM);
udp_recv(pcb_out, rcv_app_msg, NULL);
p_out = pbuf_alloc(PBUF_TRANSPORT, sz, PBUF_RAM);
if ( p_out == NULL )
{
fatal_error("%s : could not allocate out pbuf of %d\n", __func__, sz);
}
p_out->payload = msg;
udp_sendto(pcb_out, p_out, IP_ADDR_BROADCAST, APP_PORT_NUM);
}
static void app_inc_pcb_refcount(void)
{
if (app_pcb_refcount == 0) {
if ( pcb_out != NULL )
{
fatal_error( "%s : memory leak\n", __func__ );
}
pcb_out = udp_new();
if (pcb_out == NULL)
{
fatal_error( "%s : could not allocate pcb\n", __func__ );
}
udp_bind(pcb_out, IP4_ADDR_ANY, APP_PORT_NUM);
udp_connect(pcb_out, IP4_ADDR_ANY, APP_PORT_NUM);
udp_recv(pcb_out, rcv_app_msg, NULL);
}
pixee_pcb_refcount++;
return;
}
static void app_dec_pcb_refcount(void)
{
if (!(app_pcb_refcount > 0))
{
fatal_error( "%s : refcount error\n", __func__ );
}
app_pcb_refcount--;
if (app_pcb_refcount == 0) {
udp_remove(pcb_out);
pcb_out = NULL;
}
}
void rcv_app_msg(void *arg, struct udp_pcb *pcb, struct pbuf *p,
const ip_addr_t *addr, u16_t port)
{
// callback from the ISR
rx_flag = 1;
}
我怎么知道相同的pbuf不断被重复使用?以下是xprintf()的控制台输出:
在这个过程中,PBUF_POOL_SIZE=5。如果我把它改为8,我将得到8次良好的运行,然后超时。如您所见,“c”是被释放的pbuf的数量,它始终是1,并且每次调用指向pbuf的指针都是相同的。因此,似乎同一个pbuf被反复使用
(为了记录在案,我还尝试了一个单独的pcb和pbuf用于发送和接收的版本-我根本无法接收到它。)
有什么想法吗
sending broadcast msg "MSG #17"... OK
p_out=536900484 ref=0, c=1
sending broadcast msg "MSG #17"... OK
p_out=536900484 ref=0, c=1
sending broadcast msg "MSG #17"... OK
p_out=536900484 ref=0, c=1
sending broadcast msg "MSG #17"... OK
p_out=536900484 ref=0, c=1
sending broadcast msg "MSG #17"... OK
p_out=536900484 ref=0, c=1
sending broadcast msg "MSG #17"... TIMED OUT
p_out=536900484 ref=0, c=1