Hard Fault STM32H755 + lwip

Hi,

I’m using STM32H755 nucleo board. I’m running FREERTOS on M7 core and M4 core is bare metal. I’m doing some measurements with strict timing requirements on M4 core and I’m using shared memory to communicate with M7 core. M7 core is communicating with TCPIP with outside world. Some ADC data is transferred with UDP.

Now, I’m having problem that I’m getting Hard Fault when sending command to start measurement on M4 core. I’m not sure if that has anything to do with the problem, but the code is very unstable. I might work few command sequence, but sooner or later I’m getting hard fault.

I’m not too experienced with FREERTOS/lwip/SMT32H7, but I’m not sure how to tackle the problem. I have been playing around with stack sizes and heap sizes and memory addresses, but it seems that I cannot find solution to the problem. Any hints where to search?
M7 FLASH

.lwip_sec (NOLOAD) :
{
. = ABSOLUTE(0x30040000);
*(.RxDecripSection)

. = ABSOLUTE(0x30040060);
*(.TxDecripSection)

. = ABSOLUTE(0x30040200);
*(.Rx_PoolSection)  

} >RAM_D2

lwipopts.h:

/* USER CODE BEGIN Header */

/**


  • File Name : Target/lwipopts.h

  • Description : This file overrides LwIP stack default configuration

  • done in opt.h file.


  • @attention

  • Copyright (c) 2025 STMicroelectronics.

  • All rights reserved.

  • This software is licensed under terms that can be found in the LICENSE file

  • in the root directory of this software component.

  • If no LICENSE file comes with this software, it is provided AS-IS.


*/

/* USER CODE END Header */

/* Define to prevent recursive inclusion --------------------------------------*/

#ifndef LWIPOPTS__H

#define LWIPOPTS__H

#include “main.h”

/-----------------------------------------------------------------------------/

/* Current version of LwIP supported by CubeMx: 2.1.2 -*/

/-----------------------------------------------------------------------------/

/* Within ‘USER CODE’ section, code will be kept by default at each generation */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

#ifdef __cplusplus

extern “C” {

#endif

/* STM32CubeMX Specific Parameters (not defined in opt.h) ---------------------*/

/* Parameters set in STM32CubeMX LwIP Configuration GUI -*/

/----- WITH_RTOS enabled (Since FREERTOS is set) -----/

#define WITH_RTOS 1

/* Temporary workaround to avoid conflict on errno defined in STM32CubeIDE and lwip sys_arch.c errno */

#undef LWIP_PROVIDE_ERRNO

/----- CHECKSUM_BY_HARDWARE enabled -----/

#define CHECKSUM_BY_HARDWARE 1

/-----------------------------------------------------------------------------/

/* LwIP Stack Parameters (modified compared to initialization value in opt.h) -*/

/* Parameters set in STM32CubeMX LwIP Configuration GUI -*/

/----- Default value in ETH configuration GUI in CubeMx: 1524 -----/

#define ETH_RX_BUFFER_SIZE 1536

/----- Value in opt.h for MEM_ALIGNMENT: 1 -----/

#define MEM_ALIGNMENT 4

/----- Default Value for MEM_SIZE: 1600 —/

#define MEM_SIZE 131048

/----- Default Value for H7 devices: 0x30004000 -----/

#define LWIP_RAM_HEAP_POINTER 0x30020000

/----- Value supported for H7 devices: 1 -----/

#define LWIP_SUPPORT_CUSTOM_PBUF 1

/----- Value in opt.h for LWIP_ETHERNET: LWIP_ARP || PPPOE_SUPPORT -/

#define LWIP_ETHERNET 1

/----- Value in opt.h for LWIP_DNS_SECURE: (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) -/

#define LWIP_DNS_SECURE 7

/----- Default Value for TCP_MSS: 536 —/

#define TCP_MSS 1460

/----- Default Value for TCP_SND_BUF: 2920 —/

#define TCP_SND_BUF 5840

/----- Default Value for TCP_SND_QUEUELEN: 17 —/

#define TCP_SND_QUEUELEN 16

/----- Default Value for LWIP_NETIF_STATUS_CALLBACK: 0 —/

#define LWIP_NETIF_STATUS_CALLBACK 1

/----- Value in opt.h for LWIP_NETIF_LINK_CALLBACK: 0 -----/

#define LWIP_NETIF_LINK_CALLBACK 1

/----- Value in opt.h for TCPIP_THREAD_STACKSIZE: 0 -----/

#define TCPIP_THREAD_STACKSIZE 2048

/----- Value in opt.h for TCPIP_THREAD_PRIO: 1 -----/

#define TCPIP_THREAD_PRIO 24

/----- Value in opt.h for TCPIP_MBOX_SIZE: 0 -----/

#define TCPIP_MBOX_SIZE 6

/----- Value in opt.h for SLIPIF_THREAD_STACKSIZE: 0 -----/

#define SLIPIF_THREAD_STACKSIZE 1024

/----- Value in opt.h for SLIPIF_THREAD_PRIO: 1 -----/

#define SLIPIF_THREAD_PRIO 3

/----- Value in opt.h for DEFAULT_THREAD_STACKSIZE: 0 -----/

#define DEFAULT_THREAD_STACKSIZE 2048

/----- Value in opt.h for DEFAULT_THREAD_PRIO: 1 -----/

#define DEFAULT_THREAD_PRIO 3

/----- Value in opt.h for DEFAULT_UDP_RECVMBOX_SIZE: 0 -----/

#define DEFAULT_UDP_RECVMBOX_SIZE 6

/----- Value in opt.h for DEFAULT_TCP_RECVMBOX_SIZE: 0 -----/

#define DEFAULT_TCP_RECVMBOX_SIZE 6

/----- Value in opt.h for DEFAULT_ACCEPTMBOX_SIZE: 0 -----/

#define DEFAULT_ACCEPTMBOX_SIZE 6

/----- Value in opt.h for RECV_BUFSIZE_DEFAULT: INT_MAX -----/

#define RECV_BUFSIZE_DEFAULT 2000000000

/----- Value in opt.h for LWIP_STATS: 1 -----/

#define LWIP_STATS 0

/----- Value in opt.h for CHECKSUM_GEN_IP: 1 -----/

#define CHECKSUM_GEN_IP 0

/----- Value in opt.h for CHECKSUM_GEN_UDP: 1 -----/

#define CHECKSUM_GEN_UDP 0

/----- Value in opt.h for CHECKSUM_GEN_TCP: 1 -----/

#define CHECKSUM_GEN_TCP 0

/----- Value in opt.h for CHECKSUM_GEN_ICMP6: 1 -----/

#define CHECKSUM_GEN_ICMP6 0

/----- Value in opt.h for CHECKSUM_CHECK_IP: 1 -----/

#define CHECKSUM_CHECK_IP 0

/----- Value in opt.h for CHECKSUM_CHECK_UDP: 1 -----/

#define CHECKSUM_CHECK_UDP 0

/----- Value in opt.h for CHECKSUM_CHECK_TCP: 1 -----/

#define CHECKSUM_CHECK_TCP 0

/----- Value in opt.h for CHECKSUM_CHECK_ICMP6: 1 -----/

#define CHECKSUM_CHECK_ICMP6 0

/-----------------------------------------------------------------------------/

/* USER CODE BEGIN 1 */

#define TCP_WND 11680 // 8 * MSS, enough for smooth flow

/* ETH_CODE: first 2 macros solve errno issue with GCC 10 and ST LwIP

  • LWIPERF_CHECK_RX_DATA enables data check for iperf. Removing it might improve performance.

*/

#undef LWIP_PROVIDE_ERRNO

#define LWIP_ERRNO_STDINCLUDE

#define LWIPERF_CHECK_RX_DATA 1

/* ETH_CODE: macro and prototypes for proper (hopefuly?)

  • multithreading support

*/

#define LOCK_TCPIP_CORE sys_lock_tcpip_core

#define UNLOCK_TCPIP_CORE sys_unlock_tcpip_core

#define LWIP_ASSERT_CORE_LOCKED sys_check_core_locking

#define LWIP_MARK_TCPIP_THREAD sys_mark_tcpip_thread

void sys_lock_tcpip_core(void);

void sys_unlock_tcpip_core(void);

void sys_check_core_locking(void);

void sys_mark_tcpip_thread(void);

/* USER CODE END 1 */

#ifdef __cplusplus

}

#endif

#endif /*LWIPOPTS__H */

If you are using a custom/own implemented ethernet interface of LWIP, I would suggest posting on the LWIP forums/mailing list.

Apart from that make sure that there aren’t any ISRs that are run with logical priority above configMAX_SYSCALL_INTERRUPT_PRIORITY if they are using any FreeRTOS APIs.

Also if you are interested here are a couple of STM32H7 demos that are using FreeRTOS+TCP:

The call stack shows a LWIP thread, so might be good to check with LWIP maintainers.