Writing to internal FLASH

Thanks to the amazing support of this community I have a system writing to external FLASH and communicating via BLE.

I was looking to understand the memory map of the NRF52840 (non mBed) and how I might write a few bytes to the internal 1Mb FLASH. This way I can be assured that when I format my external 2MB Flash, I can maintain some persistent preferences.
I understand the internal is used for program memory but some should be available for the user.

I am sure PJGlasso on here has this knowledge base!.. standby for news!

Hi there
We have a demo for this. Maybe you can have a try:

Hi and thanks for the response.

This demo appears to be for the external 2MB QSPI Flash that I have working well. I’m looking to add data to the internal 1MB Flash.
Warm regards,
James

Any thoughts team? I’m still not finding much on this topic

HI there,

SO If you’re using an nRF52840 Arduino core that supports LittleFS (e.g., the Adafruit nRF52 core or a similar fork), you can store files in flash without manually erasing pages:

Try this one:

#include <Adafruit_LittleFS.h>
#include <InternalFileSystem.h>

void setup() {
  Serial.begin(115200);
  if (!InternalFS.begin()) {
    Serial.println("Failed to mount InternalFS!");
    while (1) { delay(10); }
  }
  Serial.println("InternalFS mounted.");

const char data[] = "Hello Flash!";
  writeData("/hello.txt", (uint8_t*)data, strlen(data));
  readData("/hello.txt");
}

void writeData(const char* filename, const uint8_t* data, size_t length) {
  using namespace Adafruit_LittleFS_Namespace; 
  File myFile(InternalFS);

  myFile.open(filename, FILE_O_WRITE);
  if (!myFile) {
    Serial.println("Failed to open file for writing.");
    return;
  }
  myFile.write(data, length);
  myFile.close();
  Serial.println("Data written to flash.");
}

void readData(const char* filename) {
  using namespace Adafruit_LittleFS_Namespace;
  File myFile(InternalFS);

  myFile.open(filename, FILE_O_READ);
  if (!myFile) {
    Serial.println("Failed to open file for reading.");
    return;
  }
  while (myFile.available()) {
    Serial.write(myFile.read());
  }
  myFile.close();
  Serial.println("\nData read complete.");
}

Pros:

  • Very easy to use: files instead of raw flash addresses.
  • Automatically handles wear leveling, erases, etc.

Cons:

  • Requires your nRF52840 core to support Adafruit_LittleFS or a similar internal FS library.
  • Slight overhead in flash usage (for file system metadata).

Conclusion: On the Xiao nRF52840, you can write data to internal flash either via a file system approach (LittleFS) or direct NVMC calls. YMMV, for ease and safety, a file system is recommended if it’s supported by your Arduino core. Otherwise, carefully pick a free flash page and use the Nordic NVMC methods to erase and write data.

HTH
GL :slight_smile: PJ :v:

Some Hint:

im my project myFile.open(filename, FILE_O_WRITE);
does not overwrite the file

Read gives everytime the values of the first write.

It was nessesary to delete the existing file first and than write it new. Only with this workthru my Data which are nessesare for the next awake from Deepsleep are actually.

They also exists after new Programmupdate from ArduinoIde

Writing to a file like that appends to the end of the file if it already exists. You can either delete the file or open it and use the seek() method to overwrite it from the beginning like this:

InternalFS.begin()

file.open(kPathBootCount, FILE_O_WRITE);
if (file) {
  file.seek(0);
  file.write((uint8_t*) &sensor.boot_count, sizeof(sensor.boot_count));
  file.close();
}

InternalFS.end();

EDIT

This odd behaviour is because the API is based on that of the Arduino SD library. InternalFileSystem, which provides a wrapper to LittleFS, is poorly documented but the SD library has relevant information.

Arduino SD Library