How to get a persistent area in the flash memory of the nano 33 ble?

Hello List,

I am trying to use part of the flash memory in the nano 33 ble as persistent memory because of the lack of eeprom on the nano 22 ble. An example of how to use the NVMC to program a page of flash can be found at: https://github.com/tjpetz/BLESenseFlash. But there the result is not persistent across reprogrammings of the device.

My attempt to achieve that is to change the linker script linker_script.ld as follows.

MEMORY
{
  FLASH (rx )  : ORIGIN = 0x10000, LENGTH = 0xef000
  FLASH2 (rx ) : ORIGIN = 0xff000, LENGTH = 0x01000
        ....
  }

So not use the last page for the regular code but for a persistent store. And a section to access it:

  .persistent :
  {
  PROVIDE(__spersistent = .);
  } > FLASH2

The hope is that using __spersistent in the code gives me access to the FLASH2 region, but this does not work! In my code, the value using

  extern "C" unsigned long __spersistent;
  Serial.print("__spersistent: "); Serial.println(__spersistent, HEX);

yields 0. I would expect 0xff000. And now all 256 pages are flashed. Not defining __spersistent solves that, but then how to access the FLASH2 region?

So my question is, how can I access the FLASH2 region from C in order to use it with the NVMC and as a read only area for my persistent data.

Thanks in advance, Sietse

If you want data to persist across a reprogram of the board I don't think this will be achievable with the linker alone. The programming (loading the program into the flash of the microcontroller) of the board is controlled by the bossac application. I'm pretty sure that the default Arduino IDE configuration of bossac is to force and erase of the entire flash before uploading your sketch.

It might be possible to control bossac in such a way that it will only erase a certain range of pages of the flash memory. (Sorry, I'm not a bossac expert and haven't even played around with any settings but the defaults.)

If you want a small number of values to survive a reprogramming (flash erase) you might consider using the UICR section of flash in the nRF52840. There are only 32 registers in this reserved space. However, you should be able to set the Access Port Protection to prevent these 32 registers from being erased when an erase all flash command is issued by bossac. (Note, I've not tried this myself, I've only read the documentation.)

The nRF52840 doesn't seem to offer individual page protection of pages in the flash memory. So, other than the use of the UICR registers I don't thing you can preserve portions of memory from a reprogramming.

Perhaps, we can find an answer to your question if we understand why you want to retain information even though you've reprogrammed the system?

Thanks for the reply! I can do without data persisting across a reprogram, but it is convenient. In my use case the Arduino controls a mechanical system where I need to permanently store the mechanical state of the system. This has to be done on a frequent base, so I also log the number of programmings to see whether I am nearing the limit of the maximum number of programmings. It is convenient to leave that data intact when installing a new version of the system.

It would be convenient if bossa, via a new option, is able to only erase the pages to be overwritten. In my case I can use the UICR because there are only 8 values to store.

Thanks again, Sietse