Skip to content

Commit ad4c1d3

Browse files
authored
Merge pull request #32 from pennam/qspi-formatter
Qspi formatter
2 parents 399d7c0 + 2d0c08f commit ad4c1d3

8 files changed

+257
-314
lines changed

src/flashFormatter/C33FlashFormatter.cpp

Lines changed: 4 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -7,121 +7,16 @@
77
*/
88
#if defined(ARDUINO_PORTENTA_C33)
99
#include "C33FlashFormatter.h"
10-
#define BD_ERROR_OK 0
1110
#include "certificates.h"
1211

13-
C33FlashFormatter::C33FlashFormatter():
14-
_root(BlockDevice::get_default_instance()),
15-
_sys_bd(_root, 1),
16-
_sys_fs("sys"),
17-
_user_bd(_root, 2),
18-
_kvStore_bd(_root, 3) {
19-
}
20-
21-
bool C33FlashFormatter::checkPartition()
22-
{
23-
if (_root->init() != BD_ERROR_OK)
24-
{
25-
return false;
26-
}
27-
28-
if(!checkCACertificatesPartition())
29-
{
30-
return false;
31-
}
32-
33-
if (_user_bd.init() != BD_ERROR_OK)
34-
{
35-
return false;
36-
}
37-
38-
_user_bd.deinit();
39-
40-
if (_kvStore_bd.init() != BD_ERROR_OK)
41-
{
42-
return false;
43-
}
44-
45-
_kvStore_bd.deinit();
46-
_root->deinit();
47-
48-
return true;
49-
}
50-
51-
bool C33FlashFormatter::formatPartition() {
52-
MBRBlockDevice::partition(_root, 1, 0x0B, 0, 5 * 1024 * 1024);
53-
MBRBlockDevice::partition(_root, 2, 0x0B, 5 * 1024 * 1024, 15 * 1024 * 1024);
54-
MBRBlockDevice::partition(_root, 3, 0x0B, 15 * 1024 * 1024, 16 * 1024 * 1024);
55-
56-
if(!flashCACertificates())
57-
{
58-
return false;
59-
}
60-
61-
_user_data_fs = new LittleFileSystem("user");
62-
int err = _user_data_fs->reformat(&_user_bd);
63-
if (err) {
64-
return false;
65-
}
66-
_user_data_fs->unmount();
67-
_root->deinit();
68-
return true;
69-
}
70-
71-
bool C33FlashFormatter::checkCACertificatesPartition()
12+
bool C33FlashFormatter::checkWiFiData()
7213
{
73-
/*Inspired by the CertificateUploader.ino example for Portenta C33*/
74-
if (_sys_bd.init() != BD_ERROR_OK || _sys_fs.mount(&_sys_bd) != FR_OK)
75-
{
76-
return false;
77-
}
78-
79-
DIR *dir;
80-
struct dirent *ent;
81-
82-
if ((dir = opendir("/sys")) == NULL) {
83-
return false;
84-
}
85-
86-
bool foundCert = false;
87-
while ((ent = readdir (dir)) != NULL) {
88-
String fullname = "/sys/" + String(ent->d_name);
89-
if (fullname == "/sys/cacert.pem") {
90-
foundCert = true;
91-
break;
92-
}
93-
}
94-
closedir (dir);
95-
96-
_sys_fs.unmount();
97-
_sys_bd.deinit();
98-
return foundCert;
14+
return checkFile("/wlan", "cacert.pem");
9915
}
10016

101-
bool C33FlashFormatter::flashCACertificates()
17+
bool C33FlashFormatter::restoreWifiData()
10218
{
103-
int err = _sys_fs.reformat(&_sys_bd);
104-
if (err) {
105-
return false;
106-
}
107-
108-
int chunck_size = 128;
109-
int byte_count = 0;
110-
FILE* fp = fopen("/sys/cacert.pem", "wb");
111-
while (byte_count < cacert_pem_len) {
112-
if(byte_count + chunck_size > cacert_pem_len)
113-
chunck_size = cacert_pem_len - byte_count;
114-
int ret = fwrite(&cacert_pem[byte_count], chunck_size, 1 ,fp);
115-
if (ret != 1) {
116-
return false;
117-
}
118-
byte_count += chunck_size;
119-
}
120-
fclose(fp);
121-
122-
_sys_fs.unmount();
123-
124-
return true;
19+
return writeFile("/wlan", "cacert.pem", cacert_pem, cacert_pem_len, 128);
12520
}
12621

12722
#endif

src/flashFormatter/C33FlashFormatter.h

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,10 @@
66
file, You can obtain one at http://mozilla.org/MPL/2.0/.
77
*/
88
#pragma once
9-
#include "FlashFormatterBase.h"
10-
#include "BlockDevice.h"
11-
#include "MBRBlockDevice.h"
12-
#include "LittleFileSystem.h"
13-
#include "FATFileSystem.h"
9+
#include "FlashFormatterQSPI.h"
1410

15-
class C33FlashFormatter : public FlashFormatterClass {
16-
public:
17-
C33FlashFormatter();
18-
protected:
19-
bool checkPartition() override;
20-
bool formatPartition() override;
11+
class C33FlashFormatter : public FlashFormatterQSPI {
2112
private:
22-
bool checkCACertificatesPartition();
23-
bool flashCACertificates();
24-
BlockDevice* _root;
25-
MBRBlockDevice _sys_bd;
26-
MBRBlockDevice _user_bd;
27-
FATFileSystem _sys_fs;
28-
FileSystem * _user_data_fs;
29-
MBRBlockDevice _kvStore_bd;
13+
bool checkWiFiData() override;
14+
bool restoreWifiData() override;
3015
};

src/flashFormatter/FlashFormatter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ using FlashFormatter = MBEDH7FlashFormatter;
1515
using FlashFormatter = C33FlashFormatter;
1616
#else
1717
#include "FlashFormatterBase.h"
18-
using FlashFormatter = FlashFormatterClass;
18+
using FlashFormatter = FlashFormatterBase;
1919
#endif

src/flashFormatter/FlashFormatterBase.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
#pragma once
99
#include <Arduino.h>
1010

11-
class FlashFormatterClass {
11+
class FlashFormatterBase {
1212
public:
13-
virtual ~FlashFormatterClass() = default;
13+
virtual ~FlashFormatterBase() = default;
1414
virtual bool checkAndFormatPartition() {
1515
if(checkPartition()){
1616
return true;
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
Copyright (c) 2025 Arduino SA
3+
4+
This Source Code Form is subject to the terms of the Mozilla Public
5+
License, v. 2.0. If a copy of the MPL was not distributed with this
6+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) \
9+
|| defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA) || defined(ARDUINO_PORTENTA_C33)
10+
#include "FlashFormatterQSPI.h"
11+
12+
FlashFormatterQSPI::FlashFormatterQSPI():
13+
_root(BlockDevice::get_default_instance()),
14+
_wifiData(_root, 1),
15+
_wifiFS("wlan"),
16+
_otaData(_root, 2),
17+
_otaFS("fs"),
18+
_kvstoreData(_root, 3),
19+
_runtimeData(_root, 4),
20+
_runtimeFS("opt"),
21+
_runtimeFormat(false)
22+
{
23+
}
24+
25+
bool FlashFormatterQSPI::checkPartition()
26+
{
27+
if (_root->init() != BD_ERROR_OK) {
28+
_runtimeFormat = true;
29+
return false;
30+
}
31+
32+
/* check PLC runtime partition. This should be performed as first check to
33+
* correctly set the _runtimeFormat flag.
34+
*/
35+
_runtimeFormat = false;
36+
if (_runtimeData.init() != BD_ERROR_OK) {
37+
_runtimeFormat = true;
38+
return false;
39+
}
40+
_runtimeData.deinit();
41+
42+
/* check WiFi partition */
43+
if (_wifiData.init() != BD_ERROR_OK || _wifiFS.mount(&_wifiData) != 0) {
44+
return false;
45+
}
46+
47+
if (!checkWiFiData()) {
48+
return false;
49+
}
50+
51+
_wifiFS.unmount();
52+
_wifiData.deinit();
53+
54+
/* check OTA partition */
55+
if (_otaData.init() != BD_ERROR_OK || _otaFS.mount(&_otaData) != 0) {
56+
return false;
57+
}
58+
59+
if (_otaData.size() < 5 * 1024 * 1024) {
60+
return false;
61+
}
62+
63+
_otaFS.unmount();
64+
_otaData.deinit();
65+
66+
/* check KVStore partition */
67+
if (_kvstoreData.init() != BD_ERROR_OK) {
68+
return false;
69+
}
70+
71+
if (_kvstoreData.size() < 1 * 1024 * 1024) {
72+
return false;
73+
}
74+
_kvstoreData.deinit();
75+
76+
_root->deinit();
77+
return true;
78+
}
79+
80+
bool FlashFormatterQSPI::formatPartition() {
81+
82+
if (_root->init() != BD_ERROR_OK) {
83+
return false;
84+
}
85+
86+
if (_root->erase(0x0, _root->get_erase_size()) != BD_ERROR_OK) {
87+
return false;
88+
}
89+
90+
MBRBlockDevice::partition(_root, 1, 0x0B, 0, 1 * 1024 * 1024);
91+
if (_wifiFS.reformat(&_wifiData) != 0) {
92+
return false;
93+
}
94+
95+
if (!restoreWifiData()) {
96+
return false;
97+
}
98+
_wifiFS.unmount();
99+
100+
MBRBlockDevice::partition(_root, 2, 0x0B, 1 * 1024 * 1024, 6 * 1024 * 1024);
101+
if (_otaFS.reformat(&_otaData) != 0) {
102+
return false;
103+
}
104+
_otaFS.unmount();
105+
106+
MBRBlockDevice::partition(_root, 3, 0x0B, 6 * 1024 * 1024, 7 * 1024 * 1024);
107+
108+
if (_runtimeFormat) {
109+
MBRBlockDevice::partition(_root, 4, 0x0B, 7 * 1024 * 1024, 14 * 1024 * 1024);
110+
if (_runtimeFS.reformat(&_runtimeData) != 0) {
111+
return false;
112+
}
113+
_runtimeFS.unmount();
114+
}
115+
116+
_root->deinit();
117+
118+
return true;
119+
}
120+
121+
bool FlashFormatterQSPI::checkFile(const char* partition, const char* filename)
122+
{
123+
DIR *dir;
124+
struct dirent *ent;
125+
126+
if ((dir = opendir(partition)) == NULL) {
127+
return false;
128+
}
129+
130+
bool foundFile = false;
131+
while ((ent = readdir (dir)) != NULL) {
132+
String fullname = String(partition) + "/" + String(ent->d_name);
133+
if (fullname == String(partition) + "/" + String(filename)) {
134+
foundFile = true;
135+
break;
136+
}
137+
}
138+
closedir (dir);
139+
return foundFile;
140+
}
141+
142+
bool FlashFormatterQSPI::writeFile(const char* partition, const char* filename, const uint8_t* data, size_t size, size_t maxChunkSize)
143+
{
144+
String fullname = String(partition) + "/" + String(filename);
145+
FILE* fp = fopen(fullname.c_str(), "wb");
146+
if (!fp) {
147+
return false;
148+
}
149+
150+
size_t chunkSize = maxChunkSize;
151+
size_t byteCount = 0;
152+
while (byteCount < size) {
153+
if (byteCount + chunkSize > size)
154+
chunkSize = size - byteCount;
155+
int ret = fwrite(&data[byteCount], chunkSize, 1, fp);
156+
if (ret != 1) {
157+
fclose(fp);
158+
return false;
159+
}
160+
byteCount += chunkSize;
161+
}
162+
size_t written = ftell(fp);
163+
fclose(fp);
164+
165+
return written == size;
166+
}
167+
168+
bool FlashFormatterQSPI::writeFlash(const uint8_t* data, size_t size, size_t offset, size_t maxChunkSize)
169+
{
170+
size_t chunkSize = maxChunkSize;
171+
size_t byteCount = 0;
172+
while (byteCount < size) {
173+
if(byteCount + chunkSize > size)
174+
chunkSize = size - byteCount;
175+
int ret = _root->program(data, offset + byteCount, chunkSize);
176+
if (ret != 0) {
177+
return false;
178+
}
179+
byteCount += chunkSize;
180+
}
181+
return true;
182+
}
183+
184+
#endif

0 commit comments

Comments
 (0)