Skocz do zawartości
MaciejZyskowski

lwIP - problem z wysylaniem danych przez UDP

Pomocna odpowiedź

Witam serdecznie.

Prosze wybaczyc, ze bez pisze bez polskich znakow, ale teraz do rzeczy. Chce nawiazac komunikacje pc - mcu  przez Ethernet. Pracuje na Nucleo F746ZG. Stworzylem projekt z pomoca CubeMX (v4.27.0) w ktorym uruchomilem lwIP i podstawowe protokoly (w tym UDP), jako IDE uzywam Eclipse OpenSTM32.

Ustalenie IP mikrokontrolera wykonywane jest przez DHCP. Ping oraz echo UDP dziala bez problemu (wyslanie pakietu UDP z dowolnego pc w sieci skutkuje odeslaniem wiadomosci na ten sam adres ip oraz port).

Moj problem zaczyna sie wowczas, gdy zmodyfikowalem funkcje udpecho_raw_recv() i chce umiescic inne dane w odsylanym pakiecie.

udp_sendto(pcb, p, addr, port); /* dziala jak echo */

udp_sendto(pcb, ethTxBuffer_p_x, addr, port); /* wysyla dane z bufora */

Po przeslaniu zwykle okolo 10 pakietow z pc i uzyskaniu odpowiedzi od mcu z pakietem o innej tresci nagle mikrokontroler przestaje odpowiadac (obrazek screenshot_udp.jpg). Wyglada mi to na problem z buforem pbuf w funkcji udpecho_raw_recv(), lecz nie wiem jak sie za to zabrac.

Czy ktos z Was ma moze doswiadczenie z lwIP i moglby mi podpowiedziec co z tym zrobic? Przegladalem wiele stron z podobnymi problemami, ale jednak opisane tam rozwiazania lub rady mi nie pomogly.

Z gory dziekuje!

Kod wyglada nastepujaco:

Zmienne globalne:

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
extern struct netif gnetif;
static struct udp_pcb *udpPcb1_p;

ip_addr_t ipaddress;

static const char clientPacket_c[] =
{
		0x49, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x63, 0x61, 0x74, 0x73, 0x2e
};

static const char reply[] =
{
		0x67, 0x6f, 0x74, 0x20, 0x69, 0x74, 0x20, 0x62, 0x72, 0x6f
};
/* USER CODE END PV */

Funkcje:

static void udpecho_raw_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
{
	static struct pbuf	*ethTxBuffer_p_x;

	ethTxBuffer_p_x = pbuf_alloc(PBUF_TRANSPORT, sizeof(reply), PBUF_RAM);

	memcpy(ethTxBuffer_p_x->payload, reply, sizeof(reply));

	udp_sendto(pcb, ethTxBuffer_p_x, addr, port);

	pbuf_free(ethTxBuffer_p_x);
}
/*-----------------------------------------------------------------------------------*/
void udpecho_raw_server_init(u16_t port)
{
	struct udp_pcb *pcb;

	printf("%s() ..........\n", __func__);

	pcb = udp_new();
	udp_bind(pcb, gnetif.ip_addr.addr, port);

	/* no need to loop forever */
	udp_recv(pcb , udpecho_raw_recv, pcb);
}

W main() z rzeczy dodanych przeze mnie jest tylko:

udpecho_raw_server_init(20);

while(1)
{
  MX_LWIP_Process();
}

 

screenshot_UDP.jpg

Udostępnij ten post


Link to post
Share on other sites

Got it!

Rozwiazanie jest niesamowicie trywialne. Do funkcji udpecho_raw_recv() nalezy dopisac:

pbuf_free(p);

Konieczne jest czyszczenie obydwu buforow, zarowno tego nadawczego (ethTxBuffer_p_x) i odbiorczego (p).

Moze chociaz komus pomoga moje rozkminy, a tymczasem temat do zamkniecia. :)

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@MaciejZyskowski dziękuję za podzielenie się rozwiązaniem! Na pewno pomoże to w przyszłości jakiejś innej osobie, która trafi tu podczas szukania rozwiązania swojego problemu. W takiej sytuacji nie ma nic bardziej irytującego od znalezienia tematu, w którym autor na końcu publikuje informację "Już działa" i nie dzieli się konkretnymi wskazówkami 🙂

Udostępnij ten post


Link to post
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »

×