cancel
Showing results for 
Search instead for 
Did you mean: 

Flash write causes crash after porting code.

Posted on February 25, 2016 at 19:03

Hi, I have hit a rather strange problem that has completely stumped me!

I have a really simple bootloader for the STM32L100 device which uses the USB DFU interface to copy new firmware into the flash. The bootloader resides at 

0x08000000 

and is about 3K in size. The main firmware sits at 

0x08003000

. The original code was developed on the IAR platform and worked absolutely fine. Yesterday, I ported the code over to eclipse/gcc where I built both the firmware image and the bootloader image with no problems at all. I uploaded the bootloader and it appeared to run fine (at first). It creates a DFU device on the PC and seems to do everything it should until I try to actually upload the firmware.

For some reason, the GCC version of the bootloader hangs as soon as it tries to write to the flash memory whereas the IAR version does not!

I have run it with the debugger and I have tracked the problem down to a call to:

FLASH_ProgramHalfPage()

 which appears to be an ST Library function

I checked the parameters to the function using a breakpoint and both the address and buffer were correct. The Address was 

0x8003000 

and the buffer points to a valid ram location which contained the correct data. It all looks correct.

When I step into the 

FLASH_ProgramHalfPage()

 function, I find that the crash occurs 

at this line:

 *(__IO uint32_t*) (Address + (4 * count)) = *(pBuffer++)

and by stepping though the assembler, if find it is the 

STR 

instruction that causes the fault

str r2, [r3, r4]

That suggests to me that the flash is write protected at that point?

The source code is identical, it was just a case of porting it over and rebuilding it, I did not have to make any changes at all. 

The only possible causes that I can think of are

1 - Optimisation - I tried various settings. IAR was set to -Os. Also when I step through the code, everything seems to happen just as I expect (until it crashes!!!)

2 - Environment Variables (They all appear to be the Same), I could not find anything that could explain what I was seeing.

3 - A timing issue ?? - Again, I checked and it all looks right. The USB works, which indicates that the clock speeds are what I expect. Not surprising, it is the same source code!

4 - Some other hidden gem of config information that IAR is keeping to itself.

5 - Something so obvious that I cannot see it for looking! (Most probable!)

I know this is a shot in the dark, but can anyone offer me some clues where to look next?

What else could cause a fault at that point in the code? is there something about ST Flash memory and GCC that I need to know about? Or some Magic that IAR do in the background during initialisation. I have looked at everything I can think of.

I can provide version numbers and snippets of the source code if they help.

I have developed a lot of very low level code in GCC for  all sorts of hardware (it what I do for a living) and this is the first time I have ever seen a problem like this. I have Googled everything I can think of. I know it must be something very simple and probably quite low level. I also know that that  will probably be quite obvious when I know where to look! But I am darned if I can put my finger on it? 

Help Please!

Regards

Tim

#gcc-iar-flash-stm32l100
5 REPLIES 5
Posted on February 25, 2016 at 19:47

The values in R3 and R4 would be salient at the failing condition.

I might expect a fault if writing while the flash controller is locked, or the 32-bit write is unaligned.

You mentioned IAR optimization, but did you turn it off on GNU\GCC? Is this GCC 4.9 ?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on February 26, 2016 at 12:12

Hi,

Thanks for replying.

The values of R3 and R4 are:

R3 = 0x0

R4 = 0x08003000

R2 contains the 4 bytes of data to be written, just as one would expect.

That all looks correct to me.

I agree that the flash controller appears to be locked, but why? This is the same code as on IAR and it is using standard, unaltered, ST Library code.

With regard to optimisation, as a general rule, problems with optimisation normally boil down to logic errors in the source code being optimised. However, I did try all of the following -Os, -O1, -O2, -O3 and -Og before my original post. I had not tried -O0 (optimisation off) simply because the code it produced was too big to fit in the 12K that I have for the bootloader.

This morning I rebuilt the code with optimisation off and then changed the DFU to write the data to flash address 0x8005000 in order stop it overwriting the now too large bootloader. Although this would have put the firmware in  the wrong place, it will demonstrate if the problem with writing still existed. And, sure enough, it does. The exact same problem occurs at the same C instruction and in ASM it is the point that the processor attempts to write to the flash. 

The GCC Version is:

arm-none-eabi-gcc.exe (GNU Tools for ARM Embedded Processors) 4.8.4 20140725 (release) [ARM/embedded-4_8-branch revision 213147]

Why do you ask about GCC 4.9?

Regards

Tim.

Posted on February 26, 2016 at 13:58

I am not sure if this is helpful or not, but I tried compiling using GCC-4.9 and GCC-5.2 On both of those versions I get a new problem with the USB which claims to have an invalid device Descriptor for the DFU. 

I then tried an earlier version GCC-4.7. That did not have the problem with the USB but still crashed when attempting to write to the flash.

It is clear that the ST Libraries behave differently depending on the version of the compiler they are built with (which is concerning). This leads me to ask, which version of GCC were they tested with? Does anyone know?

Regards

Tim

Posted on February 26, 2016 at 16:09

Fixed it!!

The st library function 

FLASH_ProgramHalfPage() 

has 

__RAM_FUNC

 in front of it! 

That tells the linker to place the code in section 

.RamFunc

 rather than section 

.text.

 My linker definition file did not have that section defined (why would it?) and, unfortunately, the linker did not bother to tell me that the requested section did not exist, it just ignored it and placed the code in flash!

This causes a problem because flash gets locked for read during the write operations which prevents the next instruction from being read thus causing the crash - simple!!

I knew it would be something really silly! I guess the lesson there is never assume anything when using third party code!

Posted on February 26, 2016 at 18:10

Why do you ask about GCC 4.9?

Because 4.9.3 failed validation tests here. Had less issues with 4.6.2, 4.7.1 and 4.7.2

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..