2026-01-12 9:18 PM
Hello community members,
I am using a STM32H5 with acitvated MPU region. I want to check and test dection of nullpointer access.
Because of safety reasons. I have configured and activated the mpu so far. When doing a write access to the declared null pointer, the MemManageFault Handler is called as expected.
uint32_t *m_pTest = nullptr;
*m_pTest = m_value; // -> MemManageHandler is called (as expected)
when doing a read access, the BusFaulthandler is called
m_value = *m_pTest; // ->BusFaultHandler is called (not my expectation)
//here my mpu configuration and settings
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk |
SCB_SHCSR_BUSFAULTENA_Msk |
SCB_SHCSR_USGFAULTENA_Msk;
/* Configure the MPU to prevent NULL-pointer dereferencing ... */
//check nullpointer access Region1
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x00U;
MPU_InitStruct.LimitAddress = 0x200U;//512Byte for example
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER1;
MPU_InitStruct.AccessPermission = MPU_REGION_PRIV_RO;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER1;
MPU_AttributesInit.Attributes = MPU_DEVICE_nGnRnE | MPU_NOT_CACHEABLE
| MPU_TRANSIENT | MPU_NO_ALLOCATE;
HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);
/* Enables the MPU */
HAL_MPU_Enable(static_cast<uint32_t>(MPU_PRIVILEGED_DEFAULT));
////////////////////////
My question is:
can I configure MPU, that either a read or a write access to a nullpointer
the MemoryManagementFault - Handler is called ? Maybe changing of parameter:
AccessPermission, DisableExec, IsShareable, MPU_AttributesInit.Attributes
Many thansk in advance for your help.
Best regards
jhoerd
Solved! Go to Solution.
2026-01-26 4:56 AM
Hello @jhoerd ,
On this STM32H5, the behavior comes directly from what NULL is and how the H5 memory map looks.
In the toolchain, NULL ends up as a ((void *)0) in C, so a null pointer dereference is literally an access to address 0x00000000. On STM32H5, that address is in the External memories remap region in the memory map – it’s not internal Flash or SRAM, it’s an external/aliased bus region.
When you do:
uint32_t *p = NULL;
g_value = *p; // read from 0x00000000the core issues a read to 0x00000000 on that external‑remap bus path. That access fails at the bus/memory level, so the CPU reports a BusFault. The fault is raised by the bus interface, not by the MPU permission logic.
On other STM32 ARMv8‑M parts, the same code will not give a BusFault if 0x00000000 is mapped differently (for example to an internal Flash alias).
And when you run as a Non‑Secure image with TrustZone enabled, a null dereference can also be classified as a SecureFault rather than MemManage.
kind regards,
2026-01-26 4:56 AM
Hello @jhoerd ,
On this STM32H5, the behavior comes directly from what NULL is and how the H5 memory map looks.
In the toolchain, NULL ends up as a ((void *)0) in C, so a null pointer dereference is literally an access to address 0x00000000. On STM32H5, that address is in the External memories remap region in the memory map – it’s not internal Flash or SRAM, it’s an external/aliased bus region.
When you do:
uint32_t *p = NULL;
g_value = *p; // read from 0x00000000the core issues a read to 0x00000000 on that external‑remap bus path. That access fails at the bus/memory level, so the CPU reports a BusFault. The fault is raised by the bus interface, not by the MPU permission logic.
On other STM32 ARMv8‑M parts, the same code will not give a BusFault if 0x00000000 is mapped differently (for example to an internal Flash alias).
And when you run as a Non‑Secure image with TrustZone enabled, a null dereference can also be classified as a SecureFault rather than MemManage.
kind regards,
2026-01-26 10:33 PM
Hello Khaled_DHIF
many thanks for your answer. You helped me to undertand what happens in my test cases.
Best regards
jhoerd