.NET MF port to STM32F4 - first flash sector always gets erased

Hello!

I am working on a GCC port of .NET MF for a custom platform based on STM32F4. I got to the point when the Tinybooter compiles and executes, however after the power-up, the tinybooter always erases the first flash sector of the MCU.

I am able to debug and step the code and I pinpointed the line of code that is responsible for the erasing. But I am unsure about the code surrounding it, its meaning and why it eventually leads to the erasure. I would be grateful for any help with understanding this. Below you can find the details that I have discovered so far.

[line]

The target platform is based on STM32F407ZG which is the same MCU as on Discovery4, only in a bigger package (144 vs 100 pins). Thats why I use Discovery4 as my development platform.

The .NET MF port that I used as a starting point is the port made by Oberon which includes a ready made Discovery4 solution. I made some modifications to it but only in order to be able to compile it via GCC, no additions or modifications regarding its functionality. The GCC version being used is 4.7.2 included in Yagarto-20121222.

Upon stepping the Tinybooter exectuion, I localized that the flash erase takes place inside the call on line 948 in Application/TinyBooter/Commands.cpp:


    g_BitFieldManager.EraseOnSignatureCheckFail();

Further inside this call, I realize that the erasure is triggered based on the results of GetNextSignatureCheck(device, bitField) call on line 314 in Commands.cpp.

However, I was unable to decipher the meaning of the bitField data structure (I somehow realize that each bit of the BitField[n] must correspond to a block/sector/region in Flash but I lack a deeper understanding of this as well as the overall meaning of the bitField structure). I would be grateful for any explanation regarding this.

The second thing - where do the BitField values come from? When stepping inside GetNextSectorSignatureCheck(device, bitField), the values are loaded on line 262 and below in Commands.cpp. It seems to me that the data are acquired from flash on the address pointed by m_cfgPhysicalAddress (which is in my case 0x0800C000, the correct address of the first flash config. sector). But how did they get there in the first place?

The erasing itself is then performed on line 347 within EraseOnSignatureCheckFail() by calling:


       device->EraseBlock( eraseAddress );

In this case the eraseAddress points to 0x08000000 which is the starting address of the MCU’s flash memory. This perfectly corresponds to the observed result - after running this, the first flash sector gets wiped clean.

The MCU’s memory model that is used in the .NET MF port I am working with is best illustrated in the following presentation by Oberon, slide 31:
http://www.mountaineer.org/app/download/6083569375/NETMF+for+STM32+-+Tour+d’Horizon.pdf?t=1339779332

To summarize, the things I am unsure about is:

  • what is the precise meaning of the bitField data structure?
  • where do the bitField values come from?

Thank you for any help. In case any further info is needed, let me know and I’ll post it straightaway.

AFAIK GCC 4.7 doesn’t work for STM32F4 port.
Just have a look at that: Why compile with GCC V4.6 · NicolasG3/NETMF4.3_Community Wiki · GitHub

1 Like

Hi NicolasG,

thx for the info. I will give it a try and compile the .NET MF using GCC 4.6. However I haven’t observed that 4.7 would refuse to compile .NETMF in thumb mode as described on the wiki above. I had to modify the “Microsoft.Spot.system.gcc.targets” file in order to force it to the thumb mode, though. (-mthumb switch for GCC)

Maybe Ive just came across the possible cause of the original problem - the binary image that my GCC 4.7 produces seems bigger than 3*16 kB (first 3 flash sectors of the MCU) – the size that is reserved for the bootstrap code as shown in the memory model in the pdf linked above. Thus it overlaps with the config sector a probably causes the signature failure. I’ll check this out.

Jan

Yes, I can now confirm that the problem was caused by improper memory map w.r.t. the size of the compiled Tinybooter binary. After making the BlockRange::BLOCKTYPE_BOOTSTRAP in STM32F4_BlConfig.cpp larger, the Tinybooter now runs on F4Discovery without any problems and I am able to “ping” it using MFDeploy.

How much FLASH does your Tinybooter binary image occupy when compiled from GitHub - NicolasG3/NETMF4.3_Community: NETMF 4.3 Community features and GCC compatibility using GCC 4.6?

My Tinybooter compiled from the Oberon sources of .NET MF 4.2 (linked above) has 56.8 kB (compiled with the “release” flag, i.e. -Os optimizations). My goal would be to get below 48 kB so that it fits inside the first three flash sectors of the STM32F4 (3*16 kB).

TinyBooter.dfu files size is 49065 bytes. I don’t know if it is one to one match, but it looks like it is just right to fit 48K.

1 Like

Thank you for info. I will try to compile it myself (NETMF 4.3 + GHI Opensource NETMF port + eventually NETMF 4.3 Community) to see what makes the resulting code so smaller.

With GCC, you have to remove all unused features from TinyBooter.proj.
Just compare the Cerberus Community and the original.

Thx, I have tried this (I followed the tinybooter.proj from FEZCerberus_community) but I am still 2500 bytes over the the three sectors limit (48 kB). Seems that there have been other changes between my version 4.2 and the community port of 4.3 that reduced the code size. I also studied the Tinybooter.axfdump and Tinybooter.dump for any apparent differences between my version and the communit port but neither of them ringed any bells.

I will probably adjust the memory model in STM32F4_BlConfig.cpp to accomodate the slightly larger binary image and in the future move to the 4.3 community port that fits into the original flash memory layout.

Thanks again to all for your suggestions.

You should also look at Microsoft.Spot.system.gcc.targets for the specific gcc config.
The code is smaller (and faster) when the floating point unit is enabled.

1 Like

Hi, thx for the tip. I tried enabling the floating point unit in Microsoft.spot.system.gcc and I used the same switches as the ones used in NETMF 4.3 community port but it still was not enough to get inside the flash sector limit. However, this is not that important, I adjusted the Flash memory model in STM32F4_BlConfig.cpp and everything works fine from that point on. Thanks to all for all the helpful ideas. :slight_smile: