I have to create a RAM section using the linker script, then three functions: one to save RAM in FLASH, one to put FLASH in RAM and another one to dump the FLASH.
I have a working custom board with EFM32LG330F256G-QFN64, to debug and program I have an EFM32 Zero Gecko Starter Kit and I use mbed-os.
I’ve never worked with Silicon Labs MCU before.
I searched for application Note but could not find anything.
To compile my project I use in a terminal this command :
etc., until you know how many sectors are needed to store the related RAM.
In the neural network program create a pointer pointing to the begin of the RAM you’d like to save in flash and define the address in flash to store the RAM. For example:
Make sure the size of the neural network program < (flash_size - number_of_sectors_needed_for_RAM * sector_size). Otherwise the RAM cannot be stored in the flash memory.
Be aware of increased FLASH memory wear out and quite slow write speed!
So,
I tried to determine the number of sectors I need. The sectors have a size of 8 bytes, so I need at least 819 sectors [ (6496+52)/8 ] (I tried with several sectors, and I had always the same size).
Unfortunately, the neural network program I use is a crypted one. But I know that the library attributes a specific memory section called .neai for the knowledge variables (model hyperparameters). To use it, I need to create a memory section in the linker script according to my microcontroller architecture.
I have added :
.neai 0x0000000020007fff :
{
KEEP((.neai)) / keep my variable even if not referenced */
} >RAM
I eddited my previous reply, because I was writing the new memory section outside of the bracket of the SECTIONS part. I had to change the start address of the section too (I put the start adress of the data space of the SRAM from the datasheet).
Now I can compile my code properly.
But my program is stuck when I want to read the flash. I had to change the (const void *) to (void *) due to compilation error.
Is it because of mismatching size ?
No, it’s because by a mistake (I’m sorry for that ) I used the FlashIAP::program signature instead of the FlashIAP::read function, which is defined as:
int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size)
So the cast should be to (void*) rather than to (const void*).
It seems that the compiler is never mistaken
Try to pass the number_of_pages_needed_for_neai_RAM * page_size to the read function rather than the number_of_sectors_needed_for_neai_RAM * page_size.
Why are we dividing by sizeof(uint32_t) ?
In the brackets we suppose to specify the number of elements of the array. However, the size_of_the_neai_ram is given as number of bytes (6496+52 bytes). To get the number of array elements we have to divide it by the number of bytes occupied by one element. Because the array type is uint32_t the size_of(uint32_t) should return the number of bytes occupied by one element.
If you don’t like it that way you can change the type of the array to uint8_t. In that case we don’t have to divide because one element occupies one byte:
When I was debuging (before reading your answer) I found that the writing calculated address was 0xffdcd000 but the end address is 0x00100000…
It’s because when I calculated the number of sectors needed for my RAM I ended with 819 sectors (don’t know why I thought sector size was 8 bytes, meh) ! But one sector is 4096 bytes, sooooo 819 times sector size was the error. I only need 2 (rounded) sectors of 4096 bytes to store the 6496+52 bytes.
I checked with a tool the memory map and I properly write to the good place in the memory.
Thank you very much for your help ! I learnt a lot today.