I am developing a project running on an STM32 target, using Eclipse,
openOCD and CodeSourceryLite 2009q1-161. Part of the design is that the
user should be able to upgrade the code in flash, so I partition it into
a bootloader and two equal sectors, with the topmost page of flash used
to store configuration data. The code running in one sector can be used
to download new code into the other sector. When the download is
complete and error-free the configuration data is modified so that after
a reset the bootloader then jumps to the code in the second sector.
I was able to debug this code (using optimization level 0) on an
STM32F103xD (which has 384K of flash) when unoptimized code was about
160K. However, the code has now grown to 220K unoptimized, 130K at
optimization level 's'. Therefore I have been able to finish debugging
the rest of the code, but I can only use the flash upgrade functionality
on optimized code.
To allow for future growth I have upgraded to an STM32F103xG, which has
1M of flash configured in two banks. I have been able to continue
debugging, and I can run the flash upgrade into either bank when in
debug mode. However, if I build the code at optimize level 's' I can
only write to flash bank 1. Any attempt to erase a page in Bank 2 times
out.
I assumed this to be a gcc issue, so I tried upgrading to the latest
version, Sourcery CodeBench Lite 2012.03-56. However, this is even
worse!
My code now fails near the very start, when it tries to enable the
prefetch buffer by setting bit 4 in the Flash Assess Control Register
(Address 0x4002200). The disassembly code is:
1 | 38 FLASH_PRFTBE = ENABLE; /* Enable Prefetch Buffer */
|
2 | 08000558: InitFlash+8 movw r3, #50692 ; 0xc604
|
3 | 0800055c: InitFlash+12 movt r3, #2049 ; 0x801
|
4 | 08000560: InitFlash+16 ldr r2, [r3, #0]
|
5 | 08000562: InitFlash+18 ldrb r3, [r2, #0]
|
6 | 08000564: InitFlash+20 orr.w r3, r3, #16
|
7 | 08000568: InitFlash+24 strb r3, [r2, #0
|
You will see that this loads a pointer to the flash module into r2, then
tries to read the first register in the module. At line InitFlash+16 I
can confirm that the content of r2 is 0x40022000. However, when this
instruction is executed the processor jumps to the HardFault_Handler,
suggesting that that address does not contain any valid data.
When the project is built with CodeSourceryLite 2009q1-161 the above
code is virtually identical and doesn't fail.
I therefore have one instance of gcc that doesn't allow access to Flash
Bank 2 and another instance that won't even get past the initialisation!
Any ideas?