Есть проблема с STM32F207 и LWIP Делаю простенький UDP сервер.
В режиме запрос - непрерывный ответ в поллинге - все работет нормально.
При однократном запросе - ответе не освобождает память pbuf_free(x_udppbuf);
Память кончается после 12 успешных запросов и все.
http://joxi.ru/Y2L6p8dI7QnZ0r
Почему не освобождает память?
/*----------------------------------------------------------------------------
* Name: UDP_server.с
* Purpose:
* Note(s):
*----------------------------------------------------------------------------
API function Description
udp_new Creates a new UDP PCB.
udp_remove Removes and de-allocates a UDP PCB.
udp_bind Binds a UDP PCB with a local IP address and port.
udp_connect Sets up a UDP PCB remote IP address and port.
udp_disconnect Removes a UDP PCB remote IP and port.
udp_send Sends UDP data.
udp_recv Specifies a callback function which is called when a datagram is received
*----------------------------------------------------------------------------*/
#include "main.h"
#include "UDP_server.h"
#include "netconf.h"
//------------------------------------------------------------------------------
//#define CONTINUE_TRANSMIT // непрерывная передача после одного запроса, иначе запрос-ответ
//------------------------------------------------------------------------------
#define msr(a) (sizeof(a) / sizeof((a)[0]))
// глобальные
// строка для вывода в порт
extern char casoutUDP1[];
// настройки UDP порта
extern struct IP_STR conf_UDP1_SD;
//--------------------------------
bool start_tx;
struct udp_pcb *udppcb;
struct pbuf *x_udppbuf;
struct ip_addr x_dest_ip_addr;
u16_t x_port;
uint32_t count_err_pbuf_alloc, count_dealloc, count_err_send;
// для отладки
void stats_udpserver(void)
{
printf("\n\rUDP server: errAlloc %d; counter errSend %d; counter deAlloc %d;\n\r",
count_err_pbuf_alloc,count_err_send,count_dealloc);
}
/*******************************************************************************
* Прием
Parameter:
Return:
*******************************************************************************/
static void udp_server_recv(void *arg, struct udp_pcb* u_pcb, struct pbuf *udp_pbuf,
struct ip_addr* addr, u16_t port)
{
start_tx = 1; // флаг разрешения передачи ответа на датаграмму
x_dest_ip_addr = *addr; // установим адрес получателя из принятой датаграммы
x_port = port; // установим порт получателя из принятой датаграммы
}
void UDP1_Periodic_Handle(uint32_t localtime)
{
static uint32_t Timer = 0;
if (localtime - Timer >= conf_UDP1_SD.interval)
{
Timer = localtime;
// ----------------------------------------------------------
#ifdef CONTINUE_TRANSMIT // запрос - поток
if (start_tx == 1)
{
if(conf_UDP1_SD.regime == 1) // если CAS протокол
{
// готовим буфер
x_udppbuf = pbuf_alloc(PBUF_RAW, strlen((char*)casoutUDP1), PBUF_RAM);
// в буфер кладем сообщение
pbuf_take(x_udppbuf, (char*)casoutUDP1, strlen((char*)casoutUDP1));
// отправляем в нужный адрес и порт
udp_sendto(udppcb, x_udppbuf, &x_dest_ip_addr, x_port);
}
}
// освобождаем буфер
pbuf_free(x_udppbuf);
#endif
#ifndef CONTINUE_TRANSMIT // запрос - ответ
if (start_tx == 1)
{
if(conf_UDP1_SD.regime == 1) // если CAS протокол
{
// готовим буфер
x_udppbuf = pbuf_alloc(PBUF_RAW, strlen((char*)casoutUDP1), PBUF_RAM);
if (x_udppbuf != 0)
{
// в буфер кладем сообщение
pbuf_take(x_udppbuf, (char*)casoutUDP1, strlen((char*)casoutUDP1));
// отправляем в нужный адрес и порт
if (udp_sendto(udppcb, x_udppbuf, &x_dest_ip_addr, x_port) != ERR_OK)
{
count_err_send++;
}
count_dealloc = (uint32_t)pbuf_free(x_udppbuf);
}
else
{
count_err_pbuf_alloc++;
}
pbuf_free(x_udppbuf);
}
start_tx = 0;
}
#endif
// ----------------------------------------------------------
}
}
/*******************************************************************************
* Инициализация сервера
Parameter:
Return:
вызываем перед майном
*******************************************************************************/
void UDP_server_init(void)
{
/* Create a new UDP control block */
udppcb = udp_new();
/* Bind the upcb to the UDP_PORT port */
/* Using IP_ADDR_ANY allow the upcb to be used by any local interface */
if ((udp_bind(udppcb,IP_ADDR_ANY,conf_UDP1_SD.port)) != ERR_OK)
{
udp_remove(udppcb);
}
else
{
udp_recv(udppcb,udp_server_recv,NULL);
}
}
//---------------------------------------------------------------------------------
-
- By the way, кто в udp_serv_recv() освобождает pbuf принятого пакета? - lloyd(17.06.2018 17:21)
- О! Огромное спасибо. Я бы не догадался. - michas(17.06.2018 17:39)
- Чой-та кажется там все в корне неправильно. lloyd(101 знак., 17.06.2018 17:03)
- Да вроде последовательно идут. Да куда я его только не совал. michas(69 знак., 17.06.2018 17:13)
- By the way, кто в udp_serv_recv() освобождает pbuf принятого пакета? - lloyd(17.06.2018 17:21)