cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429: push puts garbage on the stack

HSchi.2
Associate II

Hi,

im using a STM32F429ZI with CubeIDE 1.7.0 and firmware version 1.25.0 for my project. The project doesn't use an operationg system.

During coding, I worked with debug settings and without compiler optimizations and everything worked fine. When turning on compiler optimizations (-Os, -O3, -O2, doesn't matter), a hard fault occured during the initialization phase of the program, where I switch on various timers, IRQs, SPI busses and DMAs.

I started to investigate the problem and found some really strange behaviour: the push instruction at the entry of a function (HAL_TIM_RegisterCallbacks), pushing r4 and lr to the stack, failed. Lr was pushed correctly, but only the least significant byte of r4 was written to memory. The other three bytes contained the same value as before.

When I set a breakpoint right at the push instruction and then step debug the push, everything works fine. When I set a breakpoint at the instruction right after the push and inspect the memory at sp, only the least siginficant byte is set.

In order to investigate further, I added some inline assembler just before the function call pushing some registers to the stack and popping them back.

  1. Push 4 - Pop 40693W00000DpmEyQAJ.png
  2.  Push 5 - Pop 50693W00000DpmGpQAJ.png
  3. Push 4 - Pop 4 - Push 50693W00000DplwcQAB.png
  4. Push 4 - Push 5 - Pop 4 - Pop 50693W00000DpmIRQAZ.png
  5. Push 4 - Push 5 - Pop 4 - Pop 5 at other stack position0693W00000DpmJyQAJ.png
  6. Push 2 - Push 5 - Pop 2 - Pop 5 at other stack position0693W00000DpmROQAZ.png

To summarize:

Whenever I push to a specific, relative (to an unknown reference) stack position, only the least significant byte is written. This is independet on the number of push instructions needed to reach this stack position, the number of registers written with this instruction or the absolute stack position in memory.

Has anybody seen this behaviour before? Or does anybody have an idea, what could be the underlying problem here?

1 ACCEPTED SOLUTION

Accepted Solutions

> When I resume to the second code location, although it is the exact same stack position, the push fails. Same code, same stack pointer, different result.

By bisecting determine which part of your code causes this. I suspect some DMA with incorrectly set target.

JW

View solution in original post

6 REPLIES 6

Try to do this at the very beginning of the program, before anything else is run.

JW

HSchi.2
Associate II

Hi Jan,

thanks for the quick reply.

I added the same inline assembler at the start of main(). There, it works as expected.

When I resume to the second code location, although it is the exact same stack position, the push fails. Same code, same stack pointer, different result.

Heiko

KnarfB
Principal III

> During coding, I worked with debug settings and without compiler optimizations and everything worked fine

When I tried that with your code samples, I get an error about using the frame pointer (r7). Using -O2 etc.. works but doesn't show your effect.

Is it really a wrong value that you read back or maybe just a memory browser GUI update issue displaying garbage?

When I tried this with the inline assembler code, the pop did in fact get the correct values from the stack, although the memory browser showed the wrong value.

I then removed the inline assembler code and reproduced the situation which threw the hard fault.

From main(), I call TaskInit() which in turn calls HAL_TIM_RegisterCallbacks. Both functions take a pointer to TIM_HandleTypeDef as parameter. In my case, this is htim7 at 0x20002374.

First, I stopped in TaskInit() right before the branch to HAL_TIM_RegisterCallback.

0693W00000DpnYfQAJ.pngAs you can see, both r0 and r4 contain the correct address for htim7.

In the next turn, we stop just after the HAL_TIM_RegisterCallback() is branched to.

0693W00000Dpna7QAB.pngAs you can see, in HAL_TIM_RegisterCallback(), r4 and lr are pushed onto the stack. Unfortunately, the value stored to the stack for r4 is wrong.

Again, next turn, stopping just after the HAL_TIM_RegisterCallback has popped the stacked values and returns to TaskInit().

0693W00000DpnbtQAB.pngAs you can see, r4 doesn't point to htim7 anymore and my program hard faults (or does other things I don't want it to do...).

If I would have stepped through the instructions after the first breakpoint, everything would have worked as expected. But if I restart the program and disable the previous breakpoint(s), this is the result.

> When I resume to the second code location, although it is the exact same stack position, the push fails. Same code, same stack pointer, different result.

By bisecting determine which part of your code causes this. I suspect some DMA with incorrectly set target.

JW

HSchi.2
Associate II

Adding the missing "static" qualifier to an SPI DMA destination buffer variable fixes the problem.

Many thanks for the hint to the DMA.