2025-05-29 6:41 PM
Hello wonderful ST Community!
It has been 2 days since my last major project halting problem! Haha, must be time for a new one!
In the last two years since I started to learn STM32 I have never had a Memory management fault so I have no clue what to do! From my research online I have gotten to the point in the screenshot, my understanding form the two registers shown is that an instruction is trying to be executed from a bad mem address, something to do with function pointers?
Of other note is the lack of information in the debug panel on the left hand side, normally it shows the call stack (I think that's what it's called) but it's not showing anything useful. The breakpoint pointer is also not showing, the only reason I know it's a MemManage_Handler is from the Debugger Console.
I would love to be able to figure out where the error is originating form but under registers all the registers including the PC are blank, not helpful!
Any ideas would be great help!
Cheers,
Michael
2025-05-29 7:36 PM
Check MPU_Config() settings.
Add register dumping to MemManage_Handler in a manner similar to HardFault_Handler methods. PC should be recoverable from stack frame.
2025-05-29 8:39 PM
Thanks for the fast reply!
I'm unsure what I should be looking for in MPU_Config() so I will paste the function bellow:
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
I have (I think, with some help of co-pilot, still learning over here!) dumped the registers, however the assembly is not branching into the MemManage_dump function. It continues to run into the while loop at line 17, do I have a typo somewhere or is my process wrong? I'm not very fluent in assembly.
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
void MemManage_Handler(void)
{
__asm volatile
(
"TST lr, #4 \n"
"ITE EQ \n"
"MRSEQ r0, MSP \n"
"MRSNE r0, PSP \n"
"B MemManage_dump \n"
);
}
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
void MemManage_dump(uint32_t *stack_address)
{
volatile uint32_t r0 = stack_address[0];
volatile uint32_t r1 = stack_address[1];
volatile uint32_t r2 = stack_address[2];
volatile uint32_t r3 = stack_address[3];
volatile uint32_t r12 = stack_address[4];
volatile uint32_t lr = stack_address[5];
volatile uint32_t pc = stack_address[6];
volatile uint32_t psr = stack_address[7];
while (1);
}
Cheers!
2025-05-29 8:48 PM
I see the asm error and I feel very ***! Corrected Code:
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
__asm volatile
(
"TST lr, #4 \n"
"ITE EQ \n"
"MRSEQ r0, MSP \n"
"MRSNE r0, PSP \n"
"B MemManage_dump \n"
);
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
void MemManage_dump(volatile uint32_t *stack_address)
{
volatile uint32_t r0 = stack_address[0];
volatile uint32_t r1 = stack_address[1];
volatile uint32_t r2 = stack_address[2];
volatile uint32_t r3 = stack_address[3];
volatile uint32_t r12 = stack_address[4];
volatile uint32_t lr = stack_address[5];
volatile uint32_t pc = stack_address[6];
volatile uint32_t psr = stack_address[7];
while (1);
}
Output:
I'll get to digging up the stack pointer!
I'll mark as solution if I can track down the error otherwise will report back.
Cheers.