STM32H573 TrustZone Hard Fault during NonSecure_Init switch (CMake Project)
- June 19, 2026
- 1 reply
- 24 views
Hello,
I am trying to create a very simple TZ-Enabled application on the STM32H573 in a CMake project. My application can build and flash to the IC and execute the main.c of the secure world but it hard faults, I believe when switching to the non-secure world. I am unsure of why it does this and would like help figuring that out.
I’ve attached the project to this post and I will provide information below:
Fault Analyzer Output

R0: 0x2009FC00 ← Non-Secure RAM (Non-Secure SP?)
R1: 0x08110B68 ← Non-Secure FLASH (See Vector Table Non-Secure Memory (Non-Secure Main Entry?))
R2: 0x08110B68 ← See Above
R3: 0x08110B68 ← See Above
R12: 0x08110B68 ← See Above
SP: 0x3004FF74 ← Secure RAM
LR: 0xFFFFFFA9
PC: 0x0C000FF6
XPSR: 0x09000003
Vector Table Non-Secure Memory
This is some data from memory address 0x0810 0000
| Address | 0 | 4 | 8 | C |
| 0x0810 0000 | 200A 0000 | 0811 0B69 | 0811 0BC5 | 0811 0BC5 |
| 0x810 0010 | 0810 03BD | 0811 0BC5 | 0810 03C3 | 0811 0BC5 |
| 0x0810 0020 | 0000 0000 | 0000 0000 | 0000 0000 | 0810 03C9 |
Option Bytes
Key OB
- TZEN: 0xB4 (Trust Zone enabled)
- Bank1 - Flash watermark area definition:
-
SECWM1_STRT : 0x0 (0x8000000)
-
SECWM1_END : 0x7F (0x80FE000)
-
-
Bank2 - Flash watermark area definition:
-
SECWM2_STRT : 0x7F (0x81FE000)
-
SECWM2_END : 0x0 (0x8100000)
-
STM32_Programmer_CLI Terminal Output (In case I missed anything important, all are included)
OPTION BYTES BANK: 0
Product state:
PRODUCT_STATE: 0xED (Open)
BOR Level:
BOR_LEV : 0x0 (BOR Level 1, the threshold level is low (around 2.1 V))
BORH_EN : 0x0 (0x0)
User Configuration:
IO_VDD_HSLV : 0x0 (0x0)
IO_VDDIO2_HSLV: 0x0 (0x0)
IWDG_STOP : 0x1 (0x1)
IWDG_STDBY : 0x1 (0x1)
BOOT_UBE : 0xB4 (OEM-iRoT (user flash) selected)
SWAP_BANK : 0x0 (0x0)
IWDG_SW : 0x1 (0x1)
NRST_STOP : 0x1 (0x1)
NRST_STDBY : 0x1 (0x1)
OPTION BYTES BANK: 1
User Configuration 2:
TZEN : 0xB4 (Trust zone enabled)
USBPD_DIS : 0x1 (Disabled)
SRAM2_ECC : 0x1 (SRAM2 ECC check disabled)
SRAM3_ECC : 0x1 (SRAM3 ECC check disabled)
BKPRAM_ECC : 0x1 (BKPRAM ECC check disabled)
SRAM2_RST : 0x1 (SRAM2 not erased when a system reset occurs)
SRAM1_3_RST : 0x1 (SRAM1 and SRAM3 not erased when a system reset occurs)
OPTION BYTES BANK: 2
Boot Configuration:
NSBOOTADD : 0x80000 (0x8000000) ← Note: I have changed this value to 0x08100000 and have not had success
NSBOOT_LOCK : 0xC3 (The SWAP_BANK and NSBOOTADD can still be modified following their individual rules.)
SECBOOT_LOCK : 0xC3 (The BOOT_UBE, SWAP_BANK and SECBOOTADD can still be modified following their individual rules.)
SECBOOTADD : 0xC0000 (0xC000000)
OPTION BYTES BANK: 3
Bank1 - Flash watermark area definition:
SECWM1_STRT : 0x0 (0x8000000)
SECWM1_END : 0x7F (0x80FE000)
Write sector group protection 1:
WRPSGn1 : 0xFFFFFFFF (0x0)
OPTION BYTES BANK: 4
Bank2 - Flash watermark area definition:
SECWM2_STRT : 0x7F (0x81FE000)
SECWM2_END : 0x0 (0x8100000)
Write sector group protection 2:
WRPSGn2 : 0xFFFFFFFF (0x8000000)
OPTION BYTES BANK: 5
OTP write protection:
LOCKBL : 0x0 (0x0)
OPTION BYTES BANK: 6
Flash data bank 1 sectors:
EDATA1_EN : 0x1 (Flash high-cycle data is used)
EDATA1_STRT : 0x7 (0x0)
OPTION BYTES BANK: 7
Flash data bank 2 sectors :
EDATA2_EN : 0x1 (Flash high-cycle data is used)
EDATA2_STRT : 0x7 (0x0)
OPTION BYTES BANK: 8
Flash HDP bank 1:
HDP1_STRT : 0x1 (0x2000)
HDP1_END : 0x0 (0x0)
OPTION BYTES BANK: 9
Flash HDP bank 2:
HDP2_STRT : 0x1 (0x2000)
HDP2_END : 0x0 (0x0)
NonSecure_Init() Function Code
This is the code that jumps to the non secure world on initialization. It should just be the default code that is provided on project creation.
/**
* @brief Non-secure call function
* This function is responsible for Non-secure initialization and switch
* to non-secure state
* @retval None
*/
static void NonSecure_Init(void)
{
funcptr_NS NonSecure_ResetHandler;
SCB_NS->VTOR = VTOR_TABLE_NS_START_ADDR;
/* Set non-secure main stack (MSP_NS) */
__TZ_set_MSP_NS((*(uint32_t *)VTOR_TABLE_NS_START_ADDR));
/* Get non-secure reset handler */
NonSecure_ResetHandler = (funcptr_NS)(*((uint32_t *)((VTOR_TABLE_NS_START_ADDR) + 4U)));
/* Start non-secure state software application */
NonSecure_ResetHandler();
}
Memory Definitions
Non-Secure
- RAM: 0x20050000
- FLASH: 0x8100000
Secure
- RAM: 0x30000000
- FLASH: 0xc000000
- FLASH_NSC: 0xc0fe000
SAU Configuration (As defined in STM32CubeMX & partition_stm32h573xx.h)
Region 0
- Start Address: 0x0C0F E000
- Block Size: 0x2000
- Attribute: Non-Secure Callable
Region 1
- Start Address: 0x0810 0000
- Block Size: 0x100000
- Attribute: Non-Secure
Region 2
- Start Address: 0x2005 0000
- Block Size: 0x80000
- Attribute: Non-Secure
Region 3
- Start Address: 0x4000 0000
- Block Size: 0x10000000
- Attribute: Non-Secure
Region 4
- Start Address: 0x6000 0000
- Block Size: 0x40000000
- Attribute: Non-Secure
Region 5
- Start Address: 0x0BF9 0000
- Block Size: 0x19000
- Attribute: Non-Secure
Build and Flash script
In the project repository there is a build_and_flash.sh script that I have been using the build and flash the project. Refer to that if you’re curious on how its being flashed.
Any help towards getting this running would be great, thanks.
