Skip to content

Storage: align partition scheme to mbed boards #470

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 124 additions & 16 deletions libraries/Storage/examples/QSPIFormat/QSPIFormat.ino
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

The sketch formats the board QSPI flash as follow:

* Partition 1 5MB: used for network certificates and OTA
* Partition 2 11MB: general purpose
* Partition 1 1MB: used for network certificates
* Partition 2 5MB: OTA
* Partition 3 1MB: Provisioning KVStore
* Partition 4 7MB: User data

This example code is in the public domain.
*/
Expand All @@ -13,34 +15,54 @@
#include "MBRBlockDevice.h"
#include "LittleFileSystem.h"
#include "FATFileSystem.h"
#include "certificates.h"

BlockDevice* root = BlockDevice::get_default_instance();
MBRBlockDevice sys_bd(root, 1);
MBRBlockDevice user_bd(root, 2);
FATFileSystem sys_fs("sys");
MBRBlockDevice wifi_data(root, 1);
MBRBlockDevice ota_data(root, 2);
MBRBlockDevice kvstore_data(root, 3);
MBRBlockDevice user_data(root, 4);
FATFileSystem wifi_data_fs("wlan");
FATFileSystem ota_data_fs("fs");
FileSystem * user_data_fs;

bool waitResponse() {
bool confirmation = false;
bool proceed = false;
while (confirmation == false) {
if (Serial.available()) {
char choice = Serial.read();
switch (choice) {
case 'y':
case 'Y':
confirmation = true;
return true;
proceed = true;
break;
case 'n':
case 'N':
confirmation = true;
return false;
proceed = false;
break;
default:
continue;
}
}
}
return proceed;
}

void printProgress(uint32_t offset, uint32_t size, uint32_t threshold, bool reset) {
static int percent_done = 0;
if (reset == true) {
percent_done = 0;
Serial.println("Flashed " + String(percent_done) + "%");
} else {
uint32_t percent_done_new = offset * 100 / size;
if (percent_done_new >= percent_done + threshold) {
percent_done = percent_done_new;
Serial.println("Flashed " + String(percent_done) + "%");
}
}
}

void setup() {
Expand All @@ -49,21 +71,75 @@ void setup() {
while (!Serial);

Serial.println("\nWARNING! Running the sketch all the content of the QSPI flash will be erased.");
Serial.println("The following partitions will be created:");
Serial.println("Partition 1: Network certificates 1MB");
Serial.println("Partition 2: OTA 5MB");
Serial.println("Partition 3: Provisioning KVStore 1MB");
Serial.println("Partition 4: User data 7MB"),
Serial.println("Do you want to proceed? Y/[n]");

if (true == waitResponse()) {
MBRBlockDevice::partition(root, 1, 0x0B, 0, 5 * 1024 * 1024);
MBRBlockDevice::partition(root, 2, 0x0B, 5 * 1024 * 1024, 15 * 1024 * 1024);
MBRBlockDevice::partition(root, 3, 0x0B, 15 * 1024 * 1024, 16 * 1024 * 1024);
if (root->init() != BD_ERROR_OK) {
Serial.println(F("Error: QSPI init failure."));
return;
}

int err = sys_fs.reformat(&sys_bd);
if (err) {
Serial.println("Error formatting sys partition");
Serial.println("Do you want to perform a full erase of the QSPI flash before proceeding? Y/[n]");
Serial.println("Note: Full flash erase can take up to one minute.");
bool fullErase = waitResponse();
if (fullErase == true) {
Serial.println("Full erase started, please wait...");
root->erase(0x0, root->size());
Serial.println("Full erase completed.");
} else {
// Erase only the first sector containing the MBR
root->erase(0x0, root->get_erase_size());
}

MBRBlockDevice::partition(root, 1, 0x0B, 0, 1 * 1024 * 1024);
MBRBlockDevice::partition(root, 2, 0x0B, 1 * 1024 * 1024, 6 * 1024 * 1024);
MBRBlockDevice::partition(root, 3, 0x0B, 6 * 1024 * 1024, 7 * 1024 * 1024);
MBRBlockDevice::partition(root, 4, 0x0B, 7 * 1024 * 1024, 14 * 1024 * 1024);
// free space from 15.5MB to 16 MB

bool reformat = true;
if (!wifi_data_fs.mount(&wifi_data)) {
Serial.println("\nPartition 1 already contains a filesystem, do you want to reformat it? Y/[n]");
wifi_data_fs.unmount();

reformat = waitResponse();
}

if (reformat && wifi_data_fs.reformat(&wifi_data)) {
Serial.println("Error formatting WiFi partition");
return;
}

bool restore = true;
if (reformat || fullErase) {
Serial.println("\nDo you want to restore the WiFi firmware and certificates? Y/[n]");
restore = waitResponse();
}

if (reformat && restore) {
flashCertificates();
}

reformat = true;
if (!ota_data_fs.mount(&ota_data)) {
Serial.println("\nPartition 2 already contains a filesystem, do you want to reformat it? Y/[n]");
ota_data_fs.unmount();

reformat = waitResponse();
}

if (reformat && ota_data_fs.reformat(&ota_data)) {
Serial.println("Error formatting OTA partition");
return;
}

Serial.println("\nDo you want to use LittleFS to format user data partition? Y/[n]");
Serial.println("If No, FatFS will be used to format user partition.");

if (true == waitResponse()) {
Serial.println("Formatting user partition with LittleFS.");
user_data_fs = new LittleFileSystem("user");
Expand All @@ -72,9 +148,17 @@ void setup() {
user_data_fs = new FATFileSystem("user");
}

err = user_data_fs->reformat(&user_bd);
if (err) {
reformat = true;
if (!user_data_fs->mount(&user_data)) {
Serial.println("\nPartition 4 already contains a filesystem, do you want to reformat it? Y/[n]");
user_data_fs->unmount();

reformat = waitResponse();
}

if (reformat && user_data_fs->reformat(&user_data)) {
Serial.println("Error formatting user partition");
return;
}

Serial.println("\nQSPI Flash formatted!");
Expand All @@ -83,6 +167,30 @@ void setup() {
Serial.println("It's now safe to reboot or disconnect your board.");
}

const uint32_t file_size = 421098;
extern const unsigned char wifi_firmware_image_data[];

void flashCertificates() {
FILE* fp = fopen("/wlan/cacert.pem", "wb");

Serial.println("Flashing certificates");
uint32_t chunck_size = 128;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am guessing the chunck in the variable name is a misspelling of "chunk".

uint32_t byte_count = 0;
printProgress(byte_count, cacert_pem_len, 10, true);
while (byte_count < cacert_pem_len) {
if(byte_count + chunck_size > cacert_pem_len)
chunck_size = cacert_pem_len - byte_count;
int ret = fwrite(&cacert_pem[byte_count], chunck_size, 1 ,fp);
if (ret != 1) {
Serial.println("Error writing certificates");
break;
}
byte_count += chunck_size;
printProgress(byte_count, cacert_pem_len, 10, false);
}
fclose(fp);
}

void loop() {

}
1 change: 1 addition & 0 deletions libraries/Storage/examples/QSPIFormat/certificates.h
Loading