Skip to main content
Senior
February 11, 2026
Question

STM32H7 Stack overflow detection using MPU fails on Keil/MDK

  • February 11, 2026
  • 2 replies
  • 213 views

Hello,

I'm on a custom H75x board and I want to implement a stack (+ RTOS heap) overflow detection using the MPU.

I placed stack, heap and RTOS heap into DTCM like this:

; ____________________ __ 0x20000000
; | |
; | ^ | -> 0x4000 = 16KB
; | C-Stack / \ |
; | | |
; |_______________|____| __ 0x20004000
; | | |
; | | |
; | \ / C-Heap | -> 0x10000 = 64KB
; | v |
; |____________________| __ 0x20014000
; | | |
; | | |
; | RTOS-Heap \ / | -> 0xC000 = 48kB
; | v |
; |____________________| __ 0x20020000

I intend to supervise memory access above and below the DTCM memory via MPU.

For stack overflow test, I call a function which allocates an array in the stack with size > stacksize, e.g.

static void fTest(uint32_t len)
{
	int8_t abFill[len];

	abFill[0] = (uint8_t)0xCD;
	abFill[len-1] = (uint8_t)0xAB;
:
}

If I step-debug thru these lines I can see that the SP is outside of stack memory and the array write ends up in a bus fault. If I configure the MPU then the mem fault handler is fired. Seems the MPU is not explicitly necessary for overflow check?

Unfortunately, this is only true for ST/GNU/FreeRTOS.

If I do the same on Keil/MDK/RTX5 no fault handler is triggered. The PC ends up in a code region which doesn't seem related to what I expected.

What's wrong?

Thank you

 

2 replies

Pavel A.
Super User
February 11, 2026

With Keil you have also a different compiler and runtime library. Look at disassembly and registers inside this function.

 

regjoeAuthor
Senior
February 12, 2026

Hi @Pavel A. 

I see the compiler generate different instructions but both doing the same: writing to an invalid memory address.
I know that there are different runtimes but at this time, this doesn't matter, isn't it?

I remembered that some time ago I moved the ISR code into ITCM, just for fun to test the scatter file. Because everything was OK, even all user ISR handlers are properly executed, I forget about that.

If all code is executed from internal flash, the expected hardfault ISR is executed.

I guess I have to manually patch addresses in the vector table? Where and how?  

 

P.S., I noticed that if I set a breakpoint e.g. in a timer IRQ handler, the debugger halts, but uVision displays the wrong source code. Is this simply a debugging problem?

Pavel A.
Super User
February 12, 2026

Hi @regjoe ,

Difference in the runtime library can be in different position of the stack (as you've noticed in another thread) and different initialization code. Keil compresses the initialized data in ROM and expands when it is copied to RAM. It can do something else that causes different behavior. 

About moving ISR to RAM, this is a new topic, better open a new thread. Any questions about Keil IDE and library can be answered by their support. When you relocate the code in runtime, debugger may be confused. But again, disassembly tells you the truth.