ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
28 марта
848982
michas (17.06.2018 16:47, просмотров: 1666)
Есть проблема с 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); } } //---------------------------------------------------------------------------------