Skip to content

Commit

Permalink
Storage folder
Browse files Browse the repository at this point in the history
  • Loading branch information
marqdevx committed Feb 4, 2021
1 parent ea1062e commit 6e3b047
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 133 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Helper functions for calculating limits for the FlashIAP block device
* */

#pragma once

#include <Arduino.h>
#include <FlashIAP.h>
#include <FlashIAPBlockDevice.h>

using namespace mbed;

// An helper struct for FlashIAP limits
struct FlashIAPLimits {
size_t flash_size;
uint32_t start_address;
uint32_t available_size;
};

// Get the actual start address and available size for the FlashIAP Block Device
// considering the space already occupied by the sketch.
FlashIAPLimits getFlashIAPLimits()
{
// Alignment lambdas
auto align_down = [](uint64_t val, uint64_t size) { return (((val) / size)) * size; };
auto align_up = [](uint32_t val, uint32_t size) { return (((val - 1) / size) + 1) * size; };

size_t flash_size;
uint32_t flash_start_address;
uint32_t start_address;
FlashIAP flash;

auto result = flash.init();
if (result != 0)
return { };

// Find the start of first sector after text area
int sector_size = flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR);
start_address = align_up(FLASHIAP_APP_ROM_END_ADDR, sector_size);
flash_start_address = flash.get_flash_start();
flash_size = flash.get_flash_size();

result = flash.deinit();

int available_size = flash_start_address + flash_size - start_address;
if (available_size % (sector_size * 2)) {
available_size = align_down(available_size, sector_size * 2);
}

return { flash_size, start_address, available_size };
}
Original file line number Diff line number Diff line change
@@ -1,133 +1,133 @@
#include <FlashIAPBlockDevice.h>
#include <TDBStore.h>

using namespace mbed;

// Get limits of the In Application Program (IAP) flash, ie. the internal MCU flash.
#include "FlashIAPLimits.h"
auto iapLimits { getFlashIAPLimits() };

// Create a block device on the available space of the FlashIAP
FlashIAPBlockDevice blockDevice(iapLimits.start_address, iapLimits.available_size);

// Create a key/value store on the Flash IAP block device
TDBStore store(&blockDevice);

// Dummy sketch stats for demonstration purposes
struct SketchStats {
uint32_t startupTime;
uint32_t randomValue;
uint32_t runCount;
};

void setup()
{
Serial.begin(115200);
while (!Serial);

// Wait for terminal to come up
delay(1000);

Serial.println("FlashIAPBlockDevice + TDBStore Test");

// Feed the RNG for later content generation
srand(micros());

// Initialize the flash IAP block device and print the memory layout
blockDevice.init();
Serial.printf("FlashIAP block device size: %llu\r\n", blockDevice.size());
Serial.printf("FlashIAP block device read size: %llu\r\n", blockDevice.get_read_size());
Serial.printf("FlashIAP block device program size: %llu\r\n", blockDevice.get_program_size());
Serial.printf("FlashIAP block device erase size: %llu\r\n", blockDevice.get_erase_size());
// Deinitialize the device
blockDevice.deinit();

// Initialize the key/value store
Serial.print("Initializing TDBStore: ");
auto result = store.init();
Serial.println(result == MBED_SUCCESS ? "OK" : "KO");
if (result != MBED_SUCCESS)
while (true);

// An example key name for the stats on the store
const char statsKey[] { "stats" };

// Keep track of the number of sketch executions
uint32_t runCount { 0 };

// Previous stats
SketchStats previousStats;

// Get previous run stats from the key/value store
Serial.println("Retrieving Sketch Stats");
result = getSketchStats(statsKey, &previousStats);
if (result == MBED_SUCCESS) {
Serial.println("Previous Stats");
Serial.print("\tStartup Time: ");
Serial.println(previousStats.startupTime);
Serial.print("\tRandom Value: ");
Serial.println(previousStats.randomValue);
Serial.print("\tRun Count: ");
Serial.println(previousStats.runCount);

runCount = previousStats.runCount;

} else if (result == MBED_ERROR_ITEM_NOT_FOUND) {
Serial.println("First execution");
} else {
Serial.println("Error reading from key/value store.");
while (true);
}

//Update the stats and save them to the store
SketchStats currentStats { millis(), rand(), ++runCount };
result = setSketchStats(statsKey, currentStats);

if (result == MBED_SUCCESS) {
Serial.println("Sketch Stats updated");
Serial.println("Current Stats");
Serial.print("\tStartup Time: ");
Serial.println(currentStats.startupTime);
Serial.print("\tRandom Value: ");
Serial.println(currentStats.randomValue);
Serial.print("\tRun Count: ");
Serial.println(currentStats.runCount);
} else {
Serial.println("Error storing to key/value store");
while (true);
}
}

void loop()
{
// Do nothing
}

// Retrieve a SketchStats from the k/v store
int getSketchStats(const char* key, SketchStats* stats)
{
// Retrieve key/value info
TDBStore::info_t info;
auto result = store.get_info(key, &info);
if (result == MBED_ERROR_ITEM_NOT_FOUND)
return result;

// Allocate space for the value
uint8_t buffer[info.size] {};
size_t actual_size;

// Get the value
result = store.get(key, buffer, sizeof(buffer), &actual_size);
if (result != MBED_SUCCESS)
return result;

memcpy(stats, buffer, sizeof(SketchStats));
return result;
}

// Store a SketchStats to the the k/v store
int setSketchStats(const char* key, SketchStats stats)
{
auto result = store.set(key, reinterpret_cast<uint8_t*>(&stats), sizeof(SketchStats), 0);
return result;
}
#include <FlashIAPBlockDevice.h>
#include <TDBStore.h>

using namespace mbed;

// Get limits of the In Application Program (IAP) flash, ie. the internal MCU flash.
#include "FlashIAPLimits.h"
auto iapLimits { getFlashIAPLimits() };

// Create a block device on the available space of the FlashIAP
FlashIAPBlockDevice blockDevice(iapLimits.start_address, iapLimits.available_size);

// Create a key/value store on the Flash IAP block device
TDBStore store(&blockDevice);

// Dummy sketch stats for demonstration purposes
struct SketchStats {
uint32_t startupTime;
uint32_t randomValue;
uint32_t runCount;
};

void setup()
{
Serial.begin(115200);
while (!Serial);

// Wait for terminal to come up
delay(1000);

Serial.println("FlashIAPBlockDevice + TDBStore Test");

// Feed the RNG for later content generation
srand(micros());

// Initialize the flash IAP block device and print the memory layout
blockDevice.init();
Serial.printf("FlashIAP block device size: %llu\r\n", blockDevice.size());
Serial.printf("FlashIAP block device read size: %llu\r\n", blockDevice.get_read_size());
Serial.printf("FlashIAP block device program size: %llu\r\n", blockDevice.get_program_size());
Serial.printf("FlashIAP block device erase size: %llu\r\n", blockDevice.get_erase_size());
// Deinitialize the device
blockDevice.deinit();

// Initialize the key/value store
Serial.print("Initializing TDBStore: ");
auto result = store.init();
Serial.println(result == MBED_SUCCESS ? "OK" : "KO");
if (result != MBED_SUCCESS)
while (true);

// An example key name for the stats on the store
const char statsKey[] { "stats" };

// Keep track of the number of sketch executions
uint32_t runCount { 0 };

// Previous stats
SketchStats previousStats;

// Get previous run stats from the key/value store
Serial.println("Retrieving Sketch Stats");
result = getSketchStats(statsKey, &previousStats);
if (result == MBED_SUCCESS) {
Serial.println("Previous Stats");
Serial.print("\tStartup Time: ");
Serial.println(previousStats.startupTime);
Serial.print("\tRandom Value: ");
Serial.println(previousStats.randomValue);
Serial.print("\tRun Count: ");
Serial.println(previousStats.runCount);

runCount = previousStats.runCount;

} else if (result == MBED_ERROR_ITEM_NOT_FOUND) {
Serial.println("First execution");
} else {
Serial.println("Error reading from key/value store.");
while (true);
}

//Update the stats and save them to the store
SketchStats currentStats { millis(), rand(), ++runCount };
result = setSketchStats(statsKey, currentStats);

if (result == MBED_SUCCESS) {
Serial.println("Sketch Stats updated");
Serial.println("Current Stats");
Serial.print("\tStartup Time: ");
Serial.println(currentStats.startupTime);
Serial.print("\tRandom Value: ");
Serial.println(currentStats.randomValue);
Serial.print("\tRun Count: ");
Serial.println(currentStats.runCount);
} else {
Serial.println("Error storing to key/value store");
while (true);
}
}

void loop()
{
// Do nothing
}

// Retrieve a SketchStats from the k/v store
int getSketchStats(const char* key, SketchStats* stats)
{
// Retrieve key/value info
TDBStore::info_t info;
auto result = store.get_info(key, &info);
if (result == MBED_ERROR_ITEM_NOT_FOUND)
return result;

// Allocate space for the value
uint8_t buffer[info.size] {};
size_t actual_size;

// Get the value
result = store.get(key, buffer, sizeof(buffer), &actual_size);
if (result != MBED_SUCCESS)
return result;

memcpy(stats, buffer, sizeof(SketchStats));
return result;
}

// Store a SketchStats to the the k/v store
int setSketchStats(const char* key, SketchStats stats)
{
auto result = store.set(key, reinterpret_cast<uint8_t*>(&stats), sizeof(SketchStats), 0);
return result;
}

0 comments on commit 6e3b047

Please sign in to comment.