Skip to content

Commit 07b405d

Browse files
refactoring partitioning
1 parent 02e852f commit 07b405d

File tree

9 files changed

+84
-59
lines changed

9 files changed

+84
-59
lines changed

examples/AdvancedUSBInternalOperations/AdvancedUSBInternalOperations.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
2424
*/
2525

26+
#define UNIFIED_STORAGE_DEBUG
2627
#include "Arduino_UnifiedStorage.h"
2728

2829
// Two instances are made for the USB and internal storage respectively

examples/InternalStoragePartitioning/InternalStoragePartitioning.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
3. `listPartitions`: This function reads the MBR sector on the QSPI drive and retrieves the partitioning scheme, if this sketch is succesful it should return exactly the partitioning scheme you created
2222
2323
24-
Instructions:
24+
INSTRUCTIONS:
2525
1. Check compatibility with your board and make sure you have "POSIXStorage" and "Arduino_UnifiedStorage" installed
2626
2. Connect your board to the serial monitor
2727
3. Wait for the sketch to run

examples/Logger/Logger.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef Logger_H
2+
#define Logger_H
3+
4+
#if defined(ARDUINO_OPTA)
5+
#include <ArduinoRS485.h>
6+
7+
static void beginRS485(const int baudrate)
8+
{
9+
const auto bitduration { 1.f / baudrate };
10+
const auto wordlen { 9.6f }; // OR 10.0f depending on the channel configuration
11+
const auto preDelayBR { bitduration * wordlen * 3.5f * 1e6 };
12+
const auto postDelayBR { bitduration * wordlen * 3.5f * 1e6 };
13+
14+
RS485.begin(baudrate);
15+
RS485.setDelays(preDelayBR, postDelayBR);
16+
RS485.noReceive();
17+
}
18+
#endif
19+
20+
static void printlnToSerialOrRS485(String s){
21+
#if !defined(ARDUINO_OPTA)
22+
Serial.println(s);
23+
#else
24+
RS485.beginTransmission();
25+
RS485.write(s.c_str(), strlen(s.c_str()));
26+
RS485.write('\n');
27+
RS485.endTransmission();
28+
#endif
29+
}
30+
31+
#endif

examples/Logger/Logger.ino

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#include "Arduino_UnifiedStorage.h"
26+
#include "Logger.h"
2627
#include <vector>
2728

2829

@@ -46,18 +47,15 @@ unsigned long lastLog = 0;
4647
unsigned long lastMove = 0;
4748
unsigned long lastBackup = 0;
4849

49-
5050
volatile bool usbAvailable = false;
5151
bool backingUP = false;
5252

5353
void connectionCallback(){
54-
printToSerialOrRS485("CONNECTION CALLBACK RAISED !!!");
5554
usbAvailable = true;
5655
usbStorage.removeOnConnectCallback();
5756
}
5857

5958
void disconnectionCallback(){
60-
printToSerialOrRS485("DISCONNECTION CALLBACK RAISED !!!");
6159
usbAvailable = false;
6260
usbStorage.onConnect(connectionCallback);
6361

@@ -76,7 +74,7 @@ void runPeriodically(void (*method)(), unsigned long interval, unsigned long* va
7674
void logDataToRAM() {
7775
int timeStamp = millis();
7876
int sensorReading = analogRead(A0);
79-
String line = String(timeStamp) + "," + String(random(9999)) + "\n";
77+
String line = String(timeStamp) + "," + String(random(9999));
8078
sensorDataBuffer.push_back(line);
8179
}
8280

@@ -100,10 +98,10 @@ void performUpdate() {
10098
backingUP = true;
10199
unsigned lastUpdateBytes = lastUpdateFile.readAsString().toInt(); // Read the last update size from the file
102100

103-
printToSerialOrRS485("Last update bytes: " + String(lastUpdateBytes) + "\n");
101+
printlnToSerialOrRS485("Last update bytes: " + String(lastUpdateBytes));
104102

105103
if (lastUpdateBytes >= bytesWritten) {
106-
printToSerialOrRS485("No new data to copy. \n");
104+
printlnToSerialOrRS485("No new data to copy. ");
107105
backupFile.close();
108106
lastUpdateFile.close();
109107
backingUP = false;
@@ -112,14 +110,14 @@ void performUpdate() {
112110

113111
logFile.seek(lastUpdateBytes); // Move the file pointer to the last update position
114112
unsigned long totalBytesToMove = bytesWritten - lastUpdateBytes;
115-
printToSerialOrRS485("New update bytes: " + String(totalBytesToMove) + "\n");
113+
printlnToSerialOrRS485("New update bytes: " + String(totalBytesToMove));
116114

117115
uint8_t* buffer = new uint8_t[totalBytesToMove];
118116

119117
size_t bytesRead = logFile.read(buffer, totalBytesToMove);
120118
size_t bytesMoved = backupFile.write(buffer, bytesRead); // Only write the bytes that haven't been backed up yet
121119

122-
printToSerialOrRS485("Successfully copied " + String(bytesMoved) + " new bytes. \n");
120+
printlnToSerialOrRS485("Successfully copied " + String(bytesMoved) + " new bytes. ");
123121

124122
lastUpdateFile.changeMode(FileMode::WRITE); // Open the last update file in write mode
125123
lastUpdateFile.write(String(lastUpdateBytes + bytesMoved)); // Update the last update size
@@ -141,32 +139,32 @@ void performUpdate() {
141139
void backupToUSB() {
142140
if(usbAvailable && !usbIntialized){
143141
usbStorage.begin();
144-
printToSerialOrRS485("First drive insertion, creating folders... \n");
142+
printlnToSerialOrRS485("First drive insertion, creating folders... ");
145143
Folder usbRoot = usbStorage.getRootFolder();
146144
String folderName = "LoggerBackup" + String(random(9999));
147145
backupFolder = usbRoot.createSubfolder(folderName);
148-
printToSerialOrRS485("Succesfully created backup folder: " + backupFolder.getPathAsString() + "\n");
146+
printlnToSerialOrRS485("Succesfully created backup folder: " + backupFolder.getPathAsString());
149147
usbStorage.unmount();
150148
usbIntialized = true;
151149
}
152150
else if(usbAvailable && usbIntialized) {
153-
printToSerialOrRS485("USB Mass storage is available \n");
151+
printlnToSerialOrRS485("USB Mass storage is available ");
154152
delay(100);
155153
if (!usbStorage.isMounted()) {
156154

157-
printToSerialOrRS485("Mounting USB Mass Storage \n");
155+
printlnToSerialOrRS485("Mounting USB Mass Storage ");
158156
digitalWrite(USB_MOUNTED_LED, LOW);
159157
if(usbStorage.begin()){
160158
performUpdate();
161159
}
162160

163161
} else if (usbStorage.isMounted()) {
164-
printToSerialOrRS485("USB Mass storage is connected, performing update \n");
162+
printlnToSerialOrRS485("USB Mass storage is connected, performing update ");
165163
performUpdate();
166164

167165
}
168166
} else {
169-
printToSerialOrRS485("USB Mass storage is not available \n");
167+
printlnToSerialOrRS485("USB Mass storage is not available ");
170168
}
171169

172170

@@ -188,17 +186,17 @@ void setup() {
188186
usbStorage.onDisconnect(disconnectionCallback);
189187

190188
pinMode(USB_MOUNTED_LED, OUTPUT);
191-
printToSerialOrRS485("Formatting internal storage... \n");
189+
printlnToSerialOrRS485("Formatting internal storage... ");
192190
int formatted = internalStorage.format(FS_LITTLEFS);
193-
printToSerialOrRS485("QSPI Format status: " + String(formatted) + "\n");
191+
printlnToSerialOrRS485("QSPI Format status: " + String(formatted));
194192

195193

196194

197195
if (!internalStorage.begin()) {
198-
printToSerialOrRS485("Failed to initialize internal storage \n");
196+
printlnToSerialOrRS485("Failed to initialize internal storage ");
199197
return;
200198
} else {
201-
printToSerialOrRS485("Initialized storage \n");
199+
printlnToSerialOrRS485("Initialized storage ");
202200
}
203201

204202
}

src/Boards.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#define HAS_QSPI
55
#define USES_RENESAS_CORE
66
#define QSPI_STORAGE_SIZE 16384
7+
#define HAS_SERIAL
78
#endif
89

910
#if defined(ARDUINO_PORTENTA_H7_M7)
@@ -12,19 +13,22 @@
1213
#define HAS_QSPI
1314
#define USES_MBED_CORE
1415
#define QSPI_STORAGE_SIZE 16384
16+
#define HAS_SERIAL
1517
#endif
1618

1719
#if defined(ARDUINO_OPTA)
1820
#define HAS_USB
1921
#define HAS_QSPI
2022
#define USES_MBED_CORE
2123
#define QSPI_STORAGE_SIZE 16384
24+
#define HAS_RS485
2225
#endif
2326

2427
#if defined(ARDUINO_NICLA_VISION)
2528
#define HAS_QSPI
2629
#define USES_MBED_CORE
2730
#define QSPI_STORAGE_SIZE 16384
31+
#define HAS_SERIAL
2832
#endif
2933

3034

src/InternalStorage.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@
1010
*/
1111
class InternalStorage : public Arduino_UnifiedStorage {
1212
public:
13+
14+
1315
/**
14-
* Default constructor for the InternalStorage class.
16+
* Constructs an InternalStorage object with default settings.
17+
* If no partitions are available, it restores the default partitioning scheme (See restoreDefaultPartitions() for more info).
18+
* If partitions are available, it sets the partition number, file system type, and partition name based on the last partition available.
19+
* When using the default partitioning scheme the last partition would be the user partition.
1520
*/
1621
InternalStorage();
1722

src/Partitioning.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44
bool Partitioning::eraseMBRSector(BlockDeviceType * blockDevice)
55
{
6-
unsigned char buffer[MBRBlockSize];
6+
unsigned char buffer[mbrBlockSize];
77
memset(buffer, 0xFF, sizeof(buffer));
88

99
if(blockDevice-> program(buffer, 0, sizeof(buffer)) == 0){
10-
if(blockDevice -> erase(0, MBRBlockSize) == 0){
10+
if(blockDevice -> erase(0, mbrBlockSize) == 0){
1111
return true;
1212
} else {
1313
return false;
@@ -26,7 +26,7 @@
2626
totalSize += thisPartition.size;
2727
}
2828

29-
if(totalSize <= driveSize && partitions.size() <= 4){
29+
if(totalSize <= driveSize && partitions.size() <= maximumMBRPartitions){
3030
return true;
3131
} else {
3232
return false;
@@ -66,7 +66,7 @@
6666
for (size_t i = 1; i < partitions.size() + 1; ++i) {
6767
int thisPartitionEnd = (partitions[i - 1].size * 1024) + lastPartitionEnd;
6868

69-
if(MBRBlockDeviceType::partition(blockDevice, i, MBRPartitionType, lastPartitionEnd, thisPartitionEnd) == 0){
69+
if(MBRBlockDeviceType::partition(blockDevice, i, mbrPartitionType, lastPartitionEnd, thisPartitionEnd) == 0){
7070
success = formatPartition(blockDevice, i, partitions[i - 1].fileSystemType);
7171
} else {
7272
success = false;
@@ -101,7 +101,7 @@ std::vector<Partition> Partitioning::readPartitions(BlockDeviceType * blockDevic
101101

102102
auto ret = blockDevice->init();
103103
if (ret) {
104-
Serial.println("ERROR! Unable to read the Block Device.");
104+
debugPrint("ERROR! Unable to read the Block Device.");
105105
return partitions;
106106
}
107107

@@ -115,18 +115,20 @@ std::vector<Partition> Partitioning::readPartitions(BlockDeviceType * blockDevic
115115

116116
ret = blockDevice->read(buffer, 512 - buffer_size, buffer_size);
117117
if (ret) {
118-
Serial.println("ERROR! Unable to read the Master Boot Record");
118+
debugPrint("ERROR! Unable to read the Master Boot Record");
119119

120120
delete[] buffer;
121121
return partitions;
122122
}
123123

124+
124125
auto table_start_offset = buffer_size - sizeof(mbrTable);
125126
auto table = reinterpret_cast<mbrTable*>(&buffer[table_start_offset]);
126-
127-
if (table->signature[0] != 0x55 || table->signature[1] != 0xAA) {
128-
Serial.println("MBR Not Found");
129-
Serial.println("Flash Memory doesn't have partitions.");
127+
128+
if (table->signature[0] != mbrMagicNumbers[0] || table->signature[1] != mbrMagicNumbers[1]) {
129+
130+
debugPrint("MBR Not Found");
131+
debugPrint("Flash Memory doesn't have partitions.");
130132
delete[] buffer;
131133
return partitions;
132134
}
@@ -136,9 +138,15 @@ std::vector<Partition> Partitioning::readPartitions(BlockDeviceType * blockDevic
136138
for (auto const& entry : table->entries) {
137139
partitionIndex ++;
138140
Partition partition;
139-
partition.size = (entry.lbaSize * 4096) >> 10;
140141

141-
if (entry.type == 0x00) {
142+
/*This code calculates the size of a partition in kilobytes.
143+
It takes the Logical Block Address (LBA) size of the partition,
144+
multiplies it by 4096 (the size of a block in bytes),
145+
and then shifts the result 10 bits to the right to convert it to kilobytes.
146+
*/
147+
partition.size = (entry.lbaSize * 4096) >> 10;
148+
149+
if (entry.type == emptyPartitionType) {
142150
// Skip empty partitions
143151
continue;
144152
}

src/Partitioning.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
#include "Arduino_POSIXStorage.h"
55
#include <vector>
66

7-
constexpr int MBRBlockSize = 4096;
8-
constexpr int MBRPartitionType = 0x0B;
7+
constexpr int mbrBlockSize = 4096;
8+
constexpr int mbrPartitionType = 0x0B;
99
constexpr char * mountPointName = "mountPoint";
10+
constexpr int maximumMBRPartitions = 4;
11+
constexpr int emptyPartitionType = 0x00;
12+
constexpr uint8_t mbrMagicNumbers[] = {0x55, 0xAA};
1013

1114

1215
struct Partition {

src/Utils.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,6 @@
2525
return dynamicName;
2626
}
2727

28-
#if defined(ARDUINO_OPTA)
29-
#include <ArduinoRS485.h>
30-
31-
static void beginRS485(const int baudrate)
32-
{
33-
const auto bitduration { 1.f / baudrate };
34-
const auto wordlen { 9.6f }; // OR 10.0f depending on the channel configuration
35-
const auto preDelayBR { bitduration * wordlen * 3.5f * 1e6 };
36-
const auto postDelayBR { bitduration * wordlen * 3.5f * 1e6 };
37-
38-
RS485.begin(baudrate);
39-
RS485.setDelays(preDelayBR, postDelayBR);
40-
RS485.noReceive();
41-
}
42-
#endif
43-
44-
[[gnu::unused]] static int printToSerialOrRS485(String s){
45-
#if defined(ARDUINO_PORTENTA_C33) || defined(ARDUINO_PORTENTA_H7_M7)
46-
Serial.print(s);
47-
#elif defined(ARDUINO_OPTA)
48-
RS485.beginTransmission();
49-
RS485.write(s.c_str(), strlen(s.c_str()));
50-
RS485.endTransmission();
51-
#endif
52-
}
5328

5429
[[gnu::unused]] static bool copyFolder(const char* source, const char* destination) {
5530
DIR* dir = opendir(source);

0 commit comments

Comments
 (0)