#tcp #stm32 #ethernet #freertos #lwip
#tcp #stm32 #ethernet #freertos #lwip
Вопрос:
У меня есть встроенное клиентское приложение TCP, которое использует стек TCP / IP LwIP и raw API в локальной сети. Устройство непрерывно опрашивает серверные устройства каждые 2 секунды. Сценарий похож на приведенный ниже:
- Клиент подключается к серверному устройству.
- Он отправляет запрос.
- Он получает ответ от сервера.
- Он анализирует и обрабатывает данные.
- Клиент закрывает соединение, чтобы подключить другое серверное устройство с другим IP.
- Возвращается к первому шагу, и конечный автомат непрерывно запускается в этом сценарии.
Через некоторое время (300 опросов), когда я вызываю функцию tcp_connect, она возвращает ошибку памяти ERR_MEM. После этого я не могу подключать серверные устройства. Похоже, что мое приложение получает всю память после непрерывного процесса подключения-отключения, потому что это всегда происходит после определенного количества опроса.
Я проанализировал отправляющие / принимающие фреймы в Wireshark, и процесс подключения / отключения работает так, как ожидалось. В стороннем программном обеспечении TCP-сервера я проверил, работает ли процесс отключения правильно или нет.
Мне нужны некоторые рекомендации, чтобы избежать ошибки памяти в этом сценарии.
С наилучшими пожеланиями
struct tcp_pcb *pxPCBMaster;
struct sTCPMasterClient sTCPMasterClient;
/*
* This function continously runs in super loop.
* It connects and disconnects successfully but after some time
* tcp_connect function returns ERR_MEM.
*/
void vTCPSocketTestFunc (void)
{
pxPCBMaster = tcp_new();
ip_addr_t xDestIPAddress;
IP4_ADDR (amp;xDestIPAddress, 192, 168, 10, 7);
// Connect to test server
err_t eConnStatus = tcp_connect (pxPCBMaster,
amp;xDestIPAddress,
80,
prveMBTCPMPortConnectionCallback);
if (eConnStatus != ERR_OK)
{
printf("DEBUG_MBTCPM_PORT: TCP Connection Error Occuredn");
printf("DEBUG_MBTCPM_PORT: Exception Code: %dn", eConnStatus);
}
else
{
printf("DEBUG_MBTCPM_PORT: TCP Connection is successfuln");
// Refresh Ethernet Driver and Add 2 secs Delay
for (int i = 0; i < 200; i )
{
ethernetif_input(amp;tcpNetif);
HAL_Delay (10);
}
if (sTCPMasterClient != NULL)
{
mem_free(sTCPMasterClient );
}
// Close connection
tcp_close(pxPCBMaster);
// Aborts the connection by sending a RST (reset) segment to the remote
// host. The pcb is deallocated
tcp_abort(pxPCBMaster);
// Refresh Ethernet Driver and Add 2 secs Delay
for (int i = 0; i < 200; i )
{
ethernetif_input(amp;tcpNetif);
HAL_Delay (10);
}
}
}
Комментарии:
1. Звучит как проблема с утечкой памяти или фрагментацией памяти.
2. Да, но я не знаю, как это происходит, потому что, когда мы вызываем функции tcp_close и tcp_abort, созданный объект tcb освобождается.
3. Вы сказали, что вы также обрабатываете данные во время каждого подключения. Если это связано с динамическим выделением памяти, это также может вызвать проблему. Причиной этого могут быть любые выделения, а не только те, которые связаны строго с TCP-соединением.
4. Я создал тестовый код, который непрерывно подключается к серверному устройству и отключается без отправки / получения и обработки каких-либо данных. Результат тот же, поэтому я уверен, что это не связано с обработкой данных.
5. Если нет конкретной причины не делать этого, вы должны установить
sTCPMasterClient
значениеNULL
после его освобождения.