2025-03-16 9:27 AM - last edited on 2025-03-18 2:18 AM by Andrew Neil
Hello everyone,
I’m currently working with the STM32H723ZG Nucleo board and am trying to interface microROS using UDP transport. I’m using the following environment:
I’ve carefully reviewed several guides covering MPU, Ethernet, LWIP, and FreeRTOS configurations. I was able to get microROS working over USART (per the Micro_ROS guide), but when I attempt the UDP transport I encounter a hard fault. I’ve tried replicating setups from the STM32H723_Nucleo_ETH and LWIP_UDP_Echo_Server examples (generated by CubeMX), but they don’t work as expected.
My project files are available here: tapererwaj/h723zg_microros_udp
Below, I have summarized my current configuration:
SCB_EnableICache();
SCB_EnableDCache();
/* Region 0: Ethernet DMA descriptors */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x0;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Region 1: Ethernet/LWIP heap region */
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x30000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Region 2: Additional region (512B) */
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.Size = MPU_REGION_SIZE_512B;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
/* Modification start */
.lwip_sec (NOLOAD) :
{
. = ABSOLUTE(0x30000000);
*(.RxDecripSection)
. = ABSOLUTE(0x30000100);
*(.TxDecripSection)
} >RAM_D2
/* Modification end */
#define WITH_RTOS 1
#undef LWIP_PROVIDE_ERRNO
#define CHECKSUM_BY_HARDWARE 1
#define ETH_RX_BUFFER_SIZE 1536
#define MEM_ALIGNMENT 4
#define MEM_SIZE 32232
#define LWIP_RAM_HEAP_POINTER 0x30000200
#define LWIP_SUPPORT_CUSTOM_PBUF 1
#define LWIP_ETHERNET 1
#define LWIP_DNS_SECURE 7
#define TCP_MSS 1460
#define TCP_SND_BUF 5840
#define TCP_SND_QUEUELEN 16
#define LWIP_NETIF_LINK_CALLBACK 1
#define TCPIP_THREAD_STACKSIZE 2048
#define TCPIP_THREAD_PRIO osPriorityNormal
#define TCPIP_MBOX_SIZE 6
#define SLIPIF_THREAD_STACKSIZE 1024
#define SLIPIF_THREAD_PRIO 3
#define DEFAULT_THREAD_STACKSIZE 2048
#define DEFAULT_THREAD_PRIO 3
#define DEFAULT_UDP_RECVMBOX_SIZE 6
#define DEFAULT_TCP_RECVMBOX_SIZE 6
#define DEFAULT_ACCEPTMBOX_SIZE 6
#define RECV_BUFSIZE_DEFAULT 2000000000
#define LWIP_STATS 0
#define CHECKSUM_GEN_IP 0
#define CHECKSUM_GEN_UDP 0
#define CHECKSUM_GEN_TCP 0
#define CHECKSUM_GEN_ICMP6 0
#define CHECKSUM_CHECK_IP 0
#define CHECKSUM_CHECK_UDP 0
#define CHECKSUM_CHECK_TCP 0
#define CHECKSUM_CHECK_ICMP6 0
Issue:
When running the project, I encounter a hard fault. I suspect this might be due to potential MPU region overlap or an incorrect memory allocation in D2. (For example, my MPU configuration for Region 1 covers 0x30000000–0x30008000, which might conflict with the reserved descriptors.)
My Questions:
Any guidance or suggestions would be greatly appreciated!
Thank you in advance.
2025-03-18 2:19 AM - edited 2025-03-18 2:40 AM
@tapererwaj wrote:When running the project, I encounter a hard fault. .
Debugging Hard Faults:
PS:
Similar:
2025-07-21 1:36 AM
@tapererwaj were you able to get micro-ros over UDP working?
2025-07-21 1:41 AM - edited 2025-07-21 1:55 AM
More of a question for https://micro.ros.org/ than ST:
Have you got basic UDP with LwIP working before getting into Micro-ROS?
PS:
The micro-ROS Supported Hardware page lists NUCLEO-H743ZI as a Supported Target:
Unfortunately, ST list that as Obsolete:
https://www.st.com/en/evaluation-tools/nucleo-h743zi.html
But maybe you can find a distributor with some old stock?
ST's suggested replacement is NUCLEO-H753ZI:
https://www.st.com/en/evaluation-tools/nucleo-h753zi.html
Or look at the other supported Nucleo boards on the micro-ROS Supported Hardware page...
2025-07-24 10:35 PM
Hi @ak52, thanks for reaching out!
Unfortunately, I wasn’t able to get micro-ROS over UDP fully working. I did manage to configure the STM32 to send out UDP packets to the micro-ROS agent, but the node always failed to initialize properly. From what I observed during debugging, the STM was sending an invalid packet that the agent couldn't interpret.
If you're interested, I’d be happy to share my project files in case you'd like to take a closer look or troubleshoot further.
In my experience, using UDP with micro-ROS also required a substantial amount of heap memory, which limited the number of tasks I could run in my application. Because of this constraint, I eventually opted for a simpler setup using a custom ROS 2 node with pyserial to handle communication with the STM over UART.
Let me know if you'd like more details or a link to the project!
2025-07-24 10:43 PM
Hi @Andrew Neil, thanks for the follow-up!
Yes, I was able to get basic UDP communication working using LwIP. A few key considerations I found important during the process:
MPU configuration: Make sure it’s correctly set up, especially if you're using FreeRTOS with memory protection.
FreeRTOS task stack size: The UDP stack requires a fair amount of memory, so tuning task sizes appropriately was crucial to avoid instability.
For testing, I configured my laptop with a static IP to act as the network host, and the STM32 successfully transmitted UDP packets to it.
Regarding the hardware—thanks for pointing that out. I also noticed that the NUCLEO-H743ZI is marked obsolete on ST’s website, even though it’s still listed on the micro-ROS supported hardware page. The H753ZI does look like a viable replacement, and I’ll consider checking out other supported Nucleo boards as well.
Let me know if you'd like more details on the LwIP setup or testing environment!
2025-07-24 11:04 PM
Hi @tapererwaj ,
Yes, it would be helpful if you could share a link to the project files, we are currently in the process of selecting the correct STM32 MCU for running microros with UDP transport.(Choosing between STM32H7 or STM32F7 based on successful UDP transport)
@tapererwaj wrote:In my experience, using UDP with micro-ROS also required a substantial amount of heap memory, which limited the number of tasks I could run in my application
We will not be using the MCU for anything else other than running microros, so the number of tasks and other multi-threading activities will be limited to one maybe two.
A couple of questions:
2025-07-26 12:48 AM
Thanks for the clarification on your project setup—it definitely makes sense if you're dedicating the MCU solely to micro-ROS. That should help reduce complexity, especially when managing memory for UDP transport.
To answer your questions:
Ping: Yes, I was able to ping the STM32 board using a static IP. I also successfully sent UDP packets from the STM32 to my host machine, confirming basic LwIP functionality.
micro-ROS agent behavior: When attempting to initialize the micro-ROS node, the STM32 consistently sent a 44-byte packet with the following contents:
81 80 00 00 01 07 22 00 00 0A 00 01 01 03 00 00 14 00 00 00 00 01 00 00 0C 00 00 00 63 75 62 65 6D 78 5F 6E 6F 64 65 00 00 00 00 00
However, on the agent side, I observed that it was receiving either all zeros (0x00...) or occasionally corrupted data. This suggests there may have been memory reuse issues or payload corruption during transmission.
You can take a look at the full project setup here: https://github.com/tapererwaj/h723zg_microros_udp/tree/dev
I’d be happy to collaborate if you plan to test it on an STM32F7 or a different H7 variant—curious to see if the behavior is consistent across families.
Let me know if you need guidance on specific parts of the project or want help walking through the socket initialization/debugging steps.
2025-07-28 9:05 AM - edited 2025-07-28 9:12 AM
Thanks, I am currently testing the UDP transport on an stm32F767ZI nucleo board.
Did you move the ethernets RX and TX descriptors and the lwip heap pointer to the same SRAM bank? And use the other SRAM bank for uRos?
PS:
As of now I am successfully able to ping the MCU so my eth/FreeRTOS+ lwip works. But since I place the rx and TX descriptors in SRAM2, when debugging it works , but when I do a power cycle the ping fails.Need to find a way around this..
2025-07-28 9:34 AM
@ak52 wrote:when debugging it works , but when I do a power cycle the ping fails.
There's been several threads with that symptom; eg,
STM32H745 nucleo: Ethernet ping works in debug mode; fails in standalone.
NetXDuo Ethernet on nucleo-h753zi only works with delay.