Skip to content

Qspi formatter #32

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

Merged
merged 4 commits into from
May 19, 2025
Merged
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
113 changes: 4 additions & 109 deletions src/flashFormatter/C33FlashFormatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,121 +7,16 @@
*/
#if defined(ARDUINO_PORTENTA_C33)
#include "C33FlashFormatter.h"
#define BD_ERROR_OK 0
#include "certificates.h"

C33FlashFormatter::C33FlashFormatter():
_root(BlockDevice::get_default_instance()),
_sys_bd(_root, 1),
_sys_fs("sys"),
_user_bd(_root, 2),
_kvStore_bd(_root, 3) {
}

bool C33FlashFormatter::checkPartition()
{
if (_root->init() != BD_ERROR_OK)
{
return false;
}

if(!checkCACertificatesPartition())
{
return false;
}

if (_user_bd.init() != BD_ERROR_OK)
{
return false;
}

_user_bd.deinit();

if (_kvStore_bd.init() != BD_ERROR_OK)
{
return false;
}

_kvStore_bd.deinit();
_root->deinit();

return true;
}

bool C33FlashFormatter::formatPartition() {
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(!flashCACertificates())
{
return false;
}

_user_data_fs = new LittleFileSystem("user");
int err = _user_data_fs->reformat(&_user_bd);
if (err) {
return false;
}
_user_data_fs->unmount();
_root->deinit();
return true;
}

bool C33FlashFormatter::checkCACertificatesPartition()
bool C33FlashFormatter::checkWiFiData()
{
/*Inspired by the CertificateUploader.ino example for Portenta C33*/
if (_sys_bd.init() != BD_ERROR_OK || _sys_fs.mount(&_sys_bd) != FR_OK)
{
return false;
}

DIR *dir;
struct dirent *ent;

if ((dir = opendir("/sys")) == NULL) {
return false;
}

bool foundCert = false;
while ((ent = readdir (dir)) != NULL) {
String fullname = "/sys/" + String(ent->d_name);
if (fullname == "/sys/cacert.pem") {
foundCert = true;
break;
}
}
closedir (dir);

_sys_fs.unmount();
_sys_bd.deinit();
return foundCert;
return checkFile("/wlan", "cacert.pem");
}

bool C33FlashFormatter::flashCACertificates()
bool C33FlashFormatter::restoreWifiData()
{
int err = _sys_fs.reformat(&_sys_bd);
if (err) {
return false;
}

int chunck_size = 128;
int byte_count = 0;
FILE* fp = fopen("/sys/cacert.pem", "wb");
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) {
return false;
}
byte_count += chunck_size;
}
fclose(fp);

_sys_fs.unmount();

return true;
return writeFile("/wlan", "cacert.pem", cacert_pem, cacert_pem_len, 128);
}

#endif
23 changes: 4 additions & 19 deletions src/flashFormatter/C33FlashFormatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,10 @@
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "FlashFormatterBase.h"
#include "BlockDevice.h"
#include "MBRBlockDevice.h"
#include "LittleFileSystem.h"
#include "FATFileSystem.h"
#include "FlashFormatterQSPI.h"

class C33FlashFormatter : public FlashFormatterClass {
public:
C33FlashFormatter();
protected:
bool checkPartition() override;
bool formatPartition() override;
class C33FlashFormatter : public FlashFormatterQSPI {
private:
bool checkCACertificatesPartition();
bool flashCACertificates();
BlockDevice* _root;
MBRBlockDevice _sys_bd;
MBRBlockDevice _user_bd;
FATFileSystem _sys_fs;
FileSystem * _user_data_fs;
MBRBlockDevice _kvStore_bd;
bool checkWiFiData() override;
bool restoreWifiData() override;
};
2 changes: 1 addition & 1 deletion src/flashFormatter/FlashFormatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ using FlashFormatter = MBEDH7FlashFormatter;
using FlashFormatter = C33FlashFormatter;
#else
#include "FlashFormatterBase.h"
using FlashFormatter = FlashFormatterClass;
using FlashFormatter = FlashFormatterBase;
#endif
4 changes: 2 additions & 2 deletions src/flashFormatter/FlashFormatterBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
#pragma once
#include <Arduino.h>

class FlashFormatterClass {
class FlashFormatterBase {
public:
virtual ~FlashFormatterClass() = default;
virtual ~FlashFormatterBase() = default;
virtual bool checkAndFormatPartition() {
if(checkPartition()){
return true;
Expand Down
184 changes: 184 additions & 0 deletions src/flashFormatter/FlashFormatterQSPI.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/*
Copyright (c) 2025 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) \
|| defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA) || defined(ARDUINO_PORTENTA_C33)
#include "FlashFormatterQSPI.h"

FlashFormatterQSPI::FlashFormatterQSPI():
_root(BlockDevice::get_default_instance()),
_wifiData(_root, 1),
_wifiFS("wlan"),
_otaData(_root, 2),
_otaFS("fs"),
_kvstoreData(_root, 3),
_runtimeData(_root, 4),
_runtimeFS("opt"),
_runtimeFormat(false)
{
}

bool FlashFormatterQSPI::checkPartition()
{
if (_root->init() != BD_ERROR_OK) {
_runtimeFormat = true;
return false;
}

/* check PLC runtime partition. This should be performed as first check to
* correctly set the _runtimeFormat flag.
*/
_runtimeFormat = false;
if (_runtimeData.init() != BD_ERROR_OK) {
_runtimeFormat = true;
return false;
}
_runtimeData.deinit();

/* check WiFi partition */
if (_wifiData.init() != BD_ERROR_OK || _wifiFS.mount(&_wifiData) != 0) {
return false;
}

if (!checkWiFiData()) {
return false;
}

_wifiFS.unmount();
_wifiData.deinit();

/* check OTA partition */
if (_otaData.init() != BD_ERROR_OK || _otaFS.mount(&_otaData) != 0) {
return false;
}

if (_otaData.size() < 5 * 1024 * 1024) {
return false;
}

_otaFS.unmount();
_otaData.deinit();

/* check KVStore partition */
if (_kvstoreData.init() != BD_ERROR_OK) {
return false;
}

if (_kvstoreData.size() < 1 * 1024 * 1024) {
return false;
}
_kvstoreData.deinit();

_root->deinit();
return true;
}

bool FlashFormatterQSPI::formatPartition() {

if (_root->init() != BD_ERROR_OK) {
return false;
}

if (_root->erase(0x0, _root->get_erase_size()) != BD_ERROR_OK) {
return false;
}

MBRBlockDevice::partition(_root, 1, 0x0B, 0, 1 * 1024 * 1024);
if (_wifiFS.reformat(&_wifiData) != 0) {
return false;
}

if (!restoreWifiData()) {
return false;
}
_wifiFS.unmount();

MBRBlockDevice::partition(_root, 2, 0x0B, 1 * 1024 * 1024, 6 * 1024 * 1024);
if (_otaFS.reformat(&_otaData) != 0) {
return false;
}
_otaFS.unmount();

MBRBlockDevice::partition(_root, 3, 0x0B, 6 * 1024 * 1024, 7 * 1024 * 1024);

if (_runtimeFormat) {
MBRBlockDevice::partition(_root, 4, 0x0B, 7 * 1024 * 1024, 14 * 1024 * 1024);
if (_runtimeFS.reformat(&_runtimeData) != 0) {
return false;
}
_runtimeFS.unmount();
}

_root->deinit();

return true;
}

bool FlashFormatterQSPI::checkFile(const char* partition, const char* filename)
{
DIR *dir;
struct dirent *ent;

if ((dir = opendir(partition)) == NULL) {
return false;
}

bool foundFile = false;
while ((ent = readdir (dir)) != NULL) {
String fullname = String(partition) + "/" + String(ent->d_name);
if (fullname == String(partition) + "/" + String(filename)) {
foundFile = true;
break;
}
}
closedir (dir);
return foundFile;
}

bool FlashFormatterQSPI::writeFile(const char* partition, const char* filename, const uint8_t* data, size_t size, size_t maxChunkSize)
{
String fullname = String(partition) + "/" + String(filename);
FILE* fp = fopen(fullname.c_str(), "wb");
if (!fp) {
return false;
}

size_t chunkSize = maxChunkSize;
size_t byteCount = 0;
while (byteCount < size) {
if (byteCount + chunkSize > size)
chunkSize = size - byteCount;
int ret = fwrite(&data[byteCount], chunkSize, 1, fp);
if (ret != 1) {
fclose(fp);
return false;
}
byteCount += chunkSize;
}
size_t written = ftell(fp);
fclose(fp);

return written == size;
}

bool FlashFormatterQSPI::writeFlash(const uint8_t* data, size_t size, size_t offset, size_t maxChunkSize)
{
size_t chunkSize = maxChunkSize;
size_t byteCount = 0;
while (byteCount < size) {
if(byteCount + chunkSize > size)
chunkSize = size - byteCount;
int ret = _root->program(data, offset + byteCount, chunkSize);
if (ret != 0) {
return false;
}
byteCount += chunkSize;
}
return true;
}

#endif
Loading
Loading