Flash (Key-Pair Storage)

When developing an application, sometimes developers need to store data values in a local non-volatile storage. The LFlash class exports a key-pair storage function (NVDM: Non-Volatile Data Management) from the native LinkIt SDK to Arduino users. By using LFlash APIs, user data can be stored in the on-board flash and indexed by a string-based key. In Files / Examples / LFlash / ClickCount, an example counts the number of times that the USR button is clicked. You can check the example code for an application of the LFlash class. After running this example, open the Serial Monitor and click the USR button on LinkIt 7697, you'll see a message like "USR button has been pressed for XXX times." being shown. Every time you click the USR button, the displayed counting value will increase.

Next, we describe the basics about using the LFlash class.

The total accessible storage size for NVDM on LinkIt 7697 is 64KB. And this storage partition is shared between the LFlash class and the EEPROM class, which are both implemented by NVDM. Therefore, if you consume all the 1KB storage provided by the EEPROM class, you'll have 63KB left for LFlash. If you don't need any storage for EEPROM, then LFlash can use all the 64KB storage allocated to NVDM.

In short, size(LFlash + EEPROM) := 64KB and max_size(EEPROM) := 1KB.

Initialization

Include the header file "LFlash.h" in the beginning of your code. An instance of the LFlash class is by default instantiated when the system is up, so developers can call LFlash.begin() directly to initialize the flash module for doing key-pair storing.

Write and Read

LFlash.write() and LFlash.read() are used to access the user stored data. The function prototypes are:

LFlashStatus write(
  const char *sectionName,
  const char *propertyName,
  LFlashDataType dataType,
  const uint8_t *buffer,
  uint32_t dataSize);
 
LFlashStatus read(
  const char *sectionName, 
  const char *propertyName, 
  uint8_t *buffer, 
  uint32_t *size);

The definitions of corresponding parameters are:

  • [IN] sectionName: the name of the data section.

  • [IN] propertyName: the name of the property inside the data section specified above.

  • [IN] dataType: the data type to be stored. The data type can be string data or raw data. The valid enumeration for this parameter is LFLASH_STRING_DATA or LFLASH_RAW_DATA.

  • [IN] buffer: the buffer which contains the data.

  • [IN] dataSize: the size of the input data.

  • [IN/OUT] size: as the input, it's the size of the buffer. As the output, it's the size of the read-out data.

Take the ClickCount example as an instance, when writing the number of click counts into the flash, a call like:

LFlash.write(
  SECTION_NAME,
  PROPERTY_NAME,
  LFLASH_RAW_DATA,
  (const uint8_t *)&_count,
  sizeof(_count));

is issued to store the raw data of _count variable into the flash with a section name SECTION_NAME and a property name PROPERTY_NAME.

And in the setup() routine of the example, it would read back the current click count and show it to the Serial Monitor. It's done by calling:

LFlash.read(
  SECTION_NAME, 
  PROPERTY_NAME, 
  (uint8_t *)&_count, 
  &size);

where the size is initially set to the length of the _count buffer and it will be updated to the length of the data pointed by the SECTION_NAME and PROPERTY_NAME keys.

Example Code

#include "Arduino.h"
#include "LFlash.h"
#include <string.h>

#define BUFFER_LENGTH (4)

#define SECTION_NAME "MONITOR"
#define PROPERTY_NAME "BTN_CLICK"

#define LED_PIN (7)
#define BUTTON_PIN (6)

static uint32_t _count = 0;

void show_message(uint32_t times)
{
  Serial.print("USR button has been pressed for ");
  Serial.print(times);
  Serial.print(" time");
  
  if (times < 2)
  {
    Serial.println(".");
  }
  else
  {
    Serial.println("s.");
  }
}

void button_press(void)
{
  _count++;
  
  // write the count into the flash
  LFlash.write(
    SECTION_NAME,
    PROPERTY_NAME,
    LFLASH_RAW_DATA,
    (const uint8_t *)&_count,
    sizeof(_count));

  show_message(_count);
}

void setup() {
  uint32_t size = BUFFER_LENGTH;

  Serial.begin(115200);
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  if (LFlash.begin() != LFLASH_OK)
  {
    Serial.println("Flash init failed.");
    return;
  }

  // flash init done and okay
  digitalWrite(LED_PIN, LOW);

  attachInterrupt(BUTTON_PIN, button_press, RISING);

  // read back the current click count
  LFlash.read(SECTION_NAME, PROPERTY_NAME, (uint8_t *)&_count, &size);

  show_message(_count);
}

void loop() {
  delay(1000);
}

Last updated