Есть проблема с 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)