2025-11-26 8:06 AM - last edited on 2025-11-27 12:44 AM by mƎALLEm
According to RM0433 Rev 8:
The Run* mode is entered after a POR reset and a wakeup from Standby. In Run* mode, the performance is limited and the system supply configuration shall be programmed in PWR control register 3 (PWR_CR3). The system enters Run mode only when the ACTVOSRDY bit in PWR control status register 1 (PWR_CSR1) is set to 1.
and
As long as ACTVOSRDY indicates that voltage levels are invalid, the system is in Run* mode, write accesses to the RAMs are not permitted and VOS shall not be changed.
Now, the startup code first jumps (bl ExitRun0Mode) to the C function `ExitRun0Mode()` which probably might involves writes to stack.
Is this construct (calling a C function from ASM) just relying on the compiler not touching the stack or am I'm reading the docs wrongly?
best regards
Torsten
2025-11-26 11:13 AM - edited 2025-11-26 11:14 AM
The bl instruction places the return address in the lr register. If ExitRun0Mode is a leaf function (does not call other functions), there is no need for the compiler to save lr on the stack, but just to generate a bx lr instruction for return. The current implementation is indeed a leaf function that just sets PWR->CR3 and waits for the PWR_CSR1_ACTVOSRDY condition. No need to touch the stack.
But, interestingly, when compiled in Debug configuration (-O0 optimization), it will use the stack for saving r7 (callers frame pointer):
08000434 <ExitRun0Mode>:
8000434: b480 push {r7}
8000436: af00 add r7, sp, #0
8000438: 4b09 ldr r3, [pc, #36] @ (8000460 <ExitRun0Mode+0x2c>)
800043a: 68db ldr r3, [r3, #12]
800043c: 4a08 ldr r2, [pc, #32] @ (8000460 <ExitRun0Mode+0x2c>)
800043e: f023 0302 bic.w r3, r3, #2
8000442: 60d3 str r3, [r2, #12]
8000444: bf00 nop
8000446: 4b06 ldr r3, [pc, #24] @ (8000460 <ExitRun0Mode+0x2c>)
8000448: 685b ldr r3, [r3, #4]
800044a: f403 5300 and.w r3, r3, #8192 @ 0x2000
800044e: 2b00 cmp r3, #0
8000450: d0f9 beq.n 8000446 <ExitRun0Mode+0x12>
8000452: bf00 nop
8000454: bf00 nop
8000456: 46bd mov sp, r7
8000458: f85d 7b04 ldr.w r7, [sp], #4
800045c: 4770 bx lr
800045e: bf00 nop
8000460: 58024800 .word 0x58024800This is pointless as the caller is the startup code that does not use r7 at that time.
Hmm.
hth
KnarfB
2025-11-26 11:12 PM
I think it's not surprising, that the compiler generate sub-optimal code without any optimization.
Do you think, I read the documentation correctly and the startup code is broken?