Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Start address for flash_fstorage with BLE and DFU

Hello,

I have an nRF52833 that receives data from another microcontroller during start-up. This is a 32-byte number, that needs to be used throughout the time the application is running. If for example the nRF crashes and performs a reset (as it's in release mode), that 32-byte number will be re-initialised to zero, as it's stored in an array (static uint8_t m_app[32]). I don't really want to have to change the other microcontrollers code, so I was thinking that when I receive this number at start-up, to store it in flash. 

I was looking at the fstorage example, and it seems straightforward, where I initialise the fstorage instance, then I can write or read to flash. The end address can be obtained using the nrf5_flash_end_addr_get() function. But how can I get the start address? Keep in mind I'm using Bluetooth, as well as a bootloader to have firmware updates.

--------------------

I merged the example in my code to see what gets printed about the flash storage, and I think the nrf5_flash_end_addr_get() is getting the address where I can start writing data, so the start address and not the end address, unless I'm mixing things up. The screenshot below is what I got when merging the example in my main application. I'm not sure where the bootloader part comes into play, as to program the application I use the command line to merge the application, softdevice and settings: mergehex.exe -m APP.hex BL.hex SD.hex SETTINGS.hex -o APP+SETTINGS+BL+SD.hex

Looking more into it, I believe that the 0x7800 is where the bootloader starts and/or the end of the application memory. From the image below, my application ends at 0x38C6B. As I only am using the storage once, and only to store 32 bytes, I'm thinking just to just pick a start and end address for the size I need, within the limits. My code has no dynamic memory, so no data should get overwritten over time. If I need 32 bytes of uin8_t then I need storage for 8*32 = 0x190. Going from the top of the address space 0x78000, I could put the data in for example 0x70000 to 0x70190? Does this make sense in what I want to do, as well as the calculations?

Parents
  • Hello Jerome,

    I understand, I think. Usually, the start and end addresses are used for FDS, which is a different way of storing data. The FDS uses fstorage, and the end and start addresses to define it's flash area. FDS, uses record token tags instead of addresses directly. In general it is a bit more complex. 

    If you are not using FDS, and you are not using bonding (in Bluetooth), which would be handled by the peer manager, which would use FDS, which would use Fstorage, then you can pick an address directly beneath the flash end address. If you use FDS directly, or via the peer manager, then you would need to stay away from the pages used by FDS. Other than that, I would say that you would want to put the data on an address as high as possible. If you don't use FDS/peer manager, and never intend to do so (by adding it through an update via DFU), then pick the address directly beneath the bootloader itself. If you want to save space for FDS in the future, or if you are already using FDS/peer manager, then leave N pages below the bootloader, where N is the number of FDS pages you are using.

    So let us say that you don't use FDS, and your bootloader starts at 0x78000, then I would store your data on 0x77000. You would need to use 32 bytes, so this would occupy 0x77000 -> 0x77020 (0x20 bytes = 32 bytes)

    Obviously, you could store it at 0x77FDF -> 0x77FFF, but there is really no point. If you for some reason want to change whatever is located on address 0x77000 -> 0x77FFF, you would need to erase the entire page either way.

    The point of putting it as close to the bootloader as possible is that it leaves the maximum possible free space above the application. This is used for DFU, and it needs to be continuous. 

    So the short answer is that you can put it on address 0x77000. Remember to set the bootloaders settings so that it doesn't erase this area during a DFU. It never actively erase it if it is not needed, but if the new application is large enough, you can reserve some space using:

    NRF_DFU_APP_DATA_AREA_SIZE

    in sdk_config.h in the bootloader project. This is what it is called in SDK17.1.0, but the name may change in different SDK versions. 

    By default this is set to 8192, which is 2 pages. (unless I changed it at some point). You can set it to 4096 if you are only using this one page. (one page = 4096 bytes = 0x1000 bytes). 

    Best regards,

    Edvin

Reply
  • Hello Jerome,

    I understand, I think. Usually, the start and end addresses are used for FDS, which is a different way of storing data. The FDS uses fstorage, and the end and start addresses to define it's flash area. FDS, uses record token tags instead of addresses directly. In general it is a bit more complex. 

    If you are not using FDS, and you are not using bonding (in Bluetooth), which would be handled by the peer manager, which would use FDS, which would use Fstorage, then you can pick an address directly beneath the flash end address. If you use FDS directly, or via the peer manager, then you would need to stay away from the pages used by FDS. Other than that, I would say that you would want to put the data on an address as high as possible. If you don't use FDS/peer manager, and never intend to do so (by adding it through an update via DFU), then pick the address directly beneath the bootloader itself. If you want to save space for FDS in the future, or if you are already using FDS/peer manager, then leave N pages below the bootloader, where N is the number of FDS pages you are using.

    So let us say that you don't use FDS, and your bootloader starts at 0x78000, then I would store your data on 0x77000. You would need to use 32 bytes, so this would occupy 0x77000 -> 0x77020 (0x20 bytes = 32 bytes)

    Obviously, you could store it at 0x77FDF -> 0x77FFF, but there is really no point. If you for some reason want to change whatever is located on address 0x77000 -> 0x77FFF, you would need to erase the entire page either way.

    The point of putting it as close to the bootloader as possible is that it leaves the maximum possible free space above the application. This is used for DFU, and it needs to be continuous. 

    So the short answer is that you can put it on address 0x77000. Remember to set the bootloaders settings so that it doesn't erase this area during a DFU. It never actively erase it if it is not needed, but if the new application is large enough, you can reserve some space using:

    NRF_DFU_APP_DATA_AREA_SIZE

    in sdk_config.h in the bootloader project. This is what it is called in SDK17.1.0, but the name may change in different SDK versions. 

    By default this is set to 8192, which is 2 pages. (unless I changed it at some point). You can set it to 4096 if you are only using this one page. (one page = 4096 bytes = 0x1000 bytes). 

    Best regards,

    Edvin

Children
No Data
Related