Integrating micro‑ROS over UDP using LWIP and FreeRTOS on Nucleo-H723ZG
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
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:
- STM32CubeIDE: v1.16.1
- STM32Cube Firmware: H7 V1.11.2
- Toolchain: GNU Tools for STM32 (GCC 12.3.rel1)
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:
MPU 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);
FreeRTOS Configuration
- Task definition:
FREERTOS.Tasks01=defaultTask,24,512,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL - Stack overflow checking enabled: FREERTOS.configCHECK_FOR_STACK_OVERFLOW=1
- Minimal stack size: FREERTOS.configMINIMAL_STACK_SIZE=512
- Total heap size: FREERTOS.configTOTAL_HEAP_SIZE=30*1024
- Newlib reentrancy enabled: FREERTOS.configUSE_NEWLIB_REENTRANT=1
Ethernet (ETH) Settings
- Interface: ETH.MediaInterface=HAL_ETH_RMII_MODE
- Receive Buffer Address: ETH.RxBuffAddress=0x30000200
- Receive Buffer Length: ETH.RxBuffLen=1536
- Tx Descriptor Address: ETH.TxDescAddress=0x30000100
LWIP Configuration
- Default thread stack size: LWIP.DEFAULT_THREAD_STACKSIZE=2048
- Static IP: LWIP.IP_ADDRESS=192.168.1.10
- DHCP disabled: LWIP.LWIP_DHCP=0
- LWIP heap pointer: LWIP.LWIP_RAM_HEAP_POINTER=0x30000200
- MEM_SIZE: LWIP.MEM_SIZE=32232
- Netmask: LWIP.NETMASK_ADDRESS=255.255.255.0
- TCP/IP thread stack size: LWIP.TCPIP_THREAD_STACKSIZE=2048
- TCP MSS: LWIP.TCP_MSS=1460
- TCP SND_BUF: LWIP.TCP_SND_BUF=5840
- TCP SND_QUEUELEN: LWIP.TCP_SND_QUEUELEN=16
Linker Script Modifications
/* 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:
- How should I adjust the MPU configuration or memory allocation so that the lwIP heap (32232 bytes) in D2 does not overlap with the Ethernet DMA descriptors?
- Is there a recommended strategy for relocating the Ethernet RX buffers to AXI SRAM (RAM_D1) while keeping the lwIP heap entirely in D2?
- Are there any known issues with STM32CubeIDE v1.16.1 or FW H7 V1.11.2 that might contribute to this hard fault in the context of using microros over UDP?
- What would be the best configuration for reliable, fast, and stable communication with a Micro-ROS agent on an Ubuntu 22.04 running ROS2 Humble?
Any guidance or suggestions would be greatly appreciated!
Thank you in advance.
- Labels:
-
STM32H7 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
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:
A complex system designed from scratch never works and cannot be patched up to make it work.
