Reputation: 439
I'm making bootloader for STM32F103 ARM microprocessor. I already wrote program that is able to execute code stored in RAM memory (16-bit Thumb instructions stored in uint16_t array). Everything runs fine until I set breakpoint at RAM address.
When I start program in debug mode w/o breakpoints in RAM, code runs fine. When I start program in debug mode, then I set breakpoint at the first instruction of my program (jump to main procedure), code also runs fine. Problem happens when I leave that breakpoint set, I stop the execution and then try to run it in debug mode again. Then, instead of first jump instruction (0xe000) I get (probably not) random number (0x6816).
Code:
uint16_t program[] = {
// Program code
0xe000, // b.n 0x20000004 <program+4>
0xe7fd, // b.n 0x20000000 <program> -- infinite loop if previous instruction would not work
0xfb00, 0xf000, // mul.w r0, r0, r0
0x4770, // bx lr
0xbf00, // nop
};
int main(void)
{
int (*entry_addr)(int) = (void*)((uint32_t)program | 1); // last bit set for Thumb mode
int ret = entry_addr(7);
if (ret == 49) {
while(1);
} else {
while(1);
}
}
When I set breakpoint on each instruction, I get following numbers:
0x6816, 0x2e00, 0xd018, 0xf000, 0x42b5, 0xd0f9
. Fourth one doesn't change, probably because it's part of 32-bit instruction (breakpoint was not set on this number's address).
Using SW4STM32 v2.4 with OpenOCD 0.10.0-dev-00007-g58350bc-dirty.
EDIT: I set breakpoint on the beginning of ResetHandler and I noticed that when breakpoint in RAM is set, given memory address is locked for write.
startup_stm32.s:
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1] /* This instruction works only when breakpoint is not set */
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
That explains why I have garbage in RAM - initial data is not copied to its destination address. So my question is: why debugger locks memory for write and how to prevent it?
Upvotes: 1
Views: 1228
Reputation: 1910
If "w/o breakpoints in RAM" means break on read or write access at defined address in RAM, then the behavior you observe is the flash to RAM copy at startup.
At reset, the RAM is random and before the flash main()
function, there is a copy from your constants into RAM. If you set the RAM breakpoint after startup this process is hidden, if it is set before, RAM is "random" at first break. If you continue execution, you should go to main() and then break a second time in RAM.
Upvotes: -1