STM32 ETHENRET #2. UDP SERVER

This is second tutorial in the STM32 ETHERNET Series, ands today we will see how to create UDP Server using STM32.
UDP is the simplest protocol, and this is why I am starting with it.

This tutorial will simply cover the UDP SERVER mode, the next one will cover UDP Client mode, and similarly we will move to TCP, and then later with HTTP.

Some Insight into the CODE

The cube MX Setup is same as that in the previous tutorial. Now let’s see some code.

Initialize the UDP SERVER

void udpServer_init(void)
{
	// UDP Control Block structure
   struct udp_pcb *upcb;
   err_t err;

   /* 1. Create a new UDP control block  */
   upcb = udp_new();

   /* 2. Bind the upcb to the local port */
   ip_addr_t myIPADDR;
   IP_ADDR4(&myIPADDR, 192, 168, 0, 111);

   err = udp_bind(upcb, &myIPADDR, 7);  // 7 is the server UDP port


   /* 3. Set a receive callback for the upcb */
   if(err == ERR_OK)
   {
	   udp_recv(upcb, udp_receive_callback, NULL);
   }
   else
   {
	   udp_remove(upcb);
   }
}

To initialize the UDP Server, the following steps are taken

  • Create a new UDP control block using udp_new.
  • Bind the block to the local IP address and Port
  • To do this we will first convert the IP address to the integer form
  • Then we will use the local IP address to bind the control block using the function udp_bind.
  • Once the bind is complete, the server will wait for the client to send the data.
  • To do this, we can set a callback (udp_recv), which will be called whenever the server will receive the data from the client.
  • Once the data is received, we can process the data, and send some reply to the client.

The Receive Callback

void udp_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
	struct pbuf *txBuf;

	/* Get the IP of the Client */
	char *remoteIP = ipaddr_ntoa(addr);

	char buf[100];


	int len = sprintf (buf,"Hello %s From UDP SERVER\n", (char*)p->payload);

	/* allocate pbuf from RAM*/
	txBuf = pbuf_alloc(PBUF_TRANSPORT,len, PBUF_RAM);

	/* copy the data into the buffer  */
	pbuf_take(txBuf, buf, len);

	/* Connect to the remote client */
	udp_connect(upcb, addr, port);

	/* Send a Reply to the Client */
	udp_send(upcb, txBuf);

	/* free the UDP connection, so we can accept new clients */
	udp_disconnect(upcb);

	/* Free the p_tx buffer */
	pbuf_free(txBuf);

	/* Free the p buffer */
	pbuf_free(p);
}

The receive callback is called, when the server receives some data from the client. The following shows a way to handle this data.

  1. First of all I am creating a new Packet Buffer (txBuf), which will be used to send the data.
  2. char *remoteIP = ipaddr_ntoa(addr); converts the IP address from integer format to the regular IP format.
  3. This is just in case if we want to utilize the address and port of the client.
  4. Next I am mixing the incoming data with some additional data.
  5. To send this new data to the client, first we need to allocate some memory for the packet buffer.
  6. This can be done with pbuf_alloc.
  7. Then we will copy the data into the packet buffer using pbuf_take.
  1. Next we will connect to the client.
  2. This can be done by using udp_connect. The parameters, address and port of the client, are the part of the function, where udp_connect is being called.
  3. Then we send the data using the udp_send(upcb, txBuf);
  4. Here upcb is the control block which have all the information about the local and remote connection.
  5. txBuf is the packet buffer, and it have all the information about the data.
  6. Once the data is sent, we will disconnect the client, so that a new client can connect.
  7. And in the end we will free all the memories.

The main code

/* USER CODE BEGIN 0 */

struct netif gnetif;

/* USER CODE END 0 */

int main(void)
{

  MPU_Config();

  /* Enable I-Cache---------------------------------------------------------*/
  SCB_EnableICache();

  /* Enable D-Cache---------------------------------------------------------*/
  SCB_EnableDCache();

  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_LWIP_Init();
  /* USER CODE BEGIN 2 */

  udpServer_init ();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	  ethernetif_input(&gnetif);
	  sys_check_timeouts();
  }
  /* USER CODE END 3 */
}
  • Here everything is similar to the previous tutorial, except that we will also call the uspServer_init () function.
  • ethernetif_input basically handles all the incoming requests.
  • It calls the appropriate low level function, based on what protocol is being used.
  • So we can just use the same code in the TCP also.



Result

You can see above, the data sent and received by the client.

Check out the Video Below









Info

You can help with the development by DONATING
To download the code, click DOWNLOAD button and view the Ad. The project will download after the Ad is finished.

5 Comments. Leave new

  • used the example you showed in the video, works fine, but when I ping to the stm32, only 50% or 25% ping succeeds, otherwise telling I get 50% loss of ping.
    I am working with a team and we are all connected over a switch and if some one sends every 0.01 sec a packet of 32 Byte, then my board will be busy receiving this packts and then ignore it, but my Ping will be lost and i cant communicate with my board, any solutions??

    Reply
  • hi, i want to send 1600 byte array (array[1600]) with udp from mcu to pc(server).can any one help me????

    Reply
  • Thanks mate, greatly appreciate these ethernet guides!

    Reply
  • The tutorials are really great. Keep doing this good job and sharing knowledge.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

keyboard_arrow_up

Adblocker detected! Please consider reading this notice.

We've detected that you are using AdBlock Plus or some other adblocking software which is preventing the page from fully loading.

We don't have any banner, Flash, animation, obnoxious sound, or popup ad. We do not implement these annoying types of ads!

We need money to operate the site, and almost all of it comes from our online advertising.

Please add controllerstech.com to your ad blocking whitelist or disable your adblocking software.

×