This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Flash addresses and erasing

Hi, I'm working with flash, I've started with the example code from flash_storage, as I will need to use flash while using a SoftDevice. 

I use NRF52 Dongle and SDK17.0.2 + S340.

I have fundamental problems I think, understanding how this is supposed to work.

1) Once I call nrf5_flash_end_addr_get and see the end address and the bootloader address = 0xFFFFFFFF. does it mean the last page is NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 1)?

2) does this mean, than if NRF_FICR->CODESIZE is 256 then I can use all of them? say I can write 1 byt to address NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 1) and 1 byte to address NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 256)? In other words, is all flash area available to me and can write to address 0?

3) Do I always have to do nrf_fstorage_erase before nrf_fstorage_write and when don't I? Why don't you do nrf_fstorage_erase in the flash_storage example?

4) On my device When try to erase the page NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 1) my program freezes. Before, like 2 days ago, it worked. What could have happened? Erasing the device doesn't help. The same code works on the address from the example: 0x3e000

I'm lost, please help. Thanks

  • Hi,

    1) Once I call nrf5_flash_end_addr_get and see the end address and the bootloader address = 0xFFFFFFFF. does it mean the last page is NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 1)?

    This code checks if a bootloader is present (in that case BOOTLOADER_ADDRESS which is a pointer to a word in the UICR or MBR page depending on SDK version will be set to something other than 0xFFFFFFFF). If it is, the last flag page that is used by the example is the last page before the bootloader. If not, the last page that is used is the last physical page and therefor the nrf5_flash_end_addr_get() returns the end accordingly.

    Specifically answering your question, when a  bootloader is not present, NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 1) gives you the start address of the last page. And if you want the address of the last word (which is 4 byte), that would be NRF_FICR->CODEPAGESIZE  * NRF_FICR->CODESIZE - 4.

    2) does this mean, than if NRF_FICR->CODESIZE is 256 then I can use all of them? say I can write 1 byt to address NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 1) and 1 byte to address NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 256)? In other words, is all flash area available to me and can write to address 0?

    No, that depends on what else you have in your flash. You need to keep track of your memory layout. In this example there is only application code in the beginning of flash, and possibly a bootloader in the end. There could also be other things in your app. You can certainly not write to address 0, as that will contain either the MBR if using a SoftDevice or bootloader, or it will contain your interrupt vector etc. Again, if you want to use low level flash access like this you must understand your flash layout.

    3) Do I always have to do nrf_fstorage_erase before nrf_fstorage_write and when don't I? Why don't you do nrf_fstorage_erase in the flash_storage example?

    The nature of flash memory is so that writing can only change '1' to '0', and not the other way around. To change '0' to '1' can only be done with a page erase, where all bits in a full page are set to '1' again.

    4) On my device When try to erase the page NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 1) my program freezes. Before, like 2 days ago, it worked. What could have happened? Erasing the device doesn't help. The same code works on the address from the example: 0x3e000

    I cannot say without knowing more. What have you changed, and what do you find when you debug?

    Note that if you want something more like a file system that will handle the low level details for you, then perhaps using FDS is more suitable. You can refer to the FDS example in that case.

  • Ok. Thank you very much for your answer. It confirms what I thought I understood. My prblem was - I forgot that I have a bootloader and was trying to write to flash in its location.

    Anyway. I still have one more question. Is there a was to check from inside of the application, whre is the lower limit of available flash memory? The upper limit being my bootloader, the lower being the end of my application. I know I can check it even in th nrf connect programmer, but can I check from within the application?

    Thanks and best regards,

    Lukasz

  • Hi Lukasz,

    It is typically possible to get the flash size build time from the linker, but the exact method depends on the toolchain (see for instance this thread). However, it would typically be more usefull to make the memory map yourself and decide to use a specific set of pages for your data storage, and then instead modify the linker script / project file for your app so that you get a linker error if it becomes too large.

Related