Skip to content

Commit 541952e

Browse files
added readPartitions, unified Logger for C33, H7 and opta
1 parent 17f9203 commit 541952e

File tree

14 files changed

+282
-211
lines changed

14 files changed

+282
-211
lines changed

README.md

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,8 @@ The Arduino_UnifiedStorage library provides a unified interface to access differ
1313
## 👀 Instructions
1414
1. Download and install this library
1515
2. Check compatibility with your platform
16-
3. To use internal storage, you need to make sure it is partitioned and formatted correctly:
17-
18-
### Formatting the Portenta H7 / Portenta Machine Control / Opta Internal Storage
19-
* Flash the `QSPIFormat` example that can be found in the `STM32H747_System` folder
20-
* Open the serial monitor and select answer with "n" when this appears "Do you want to use partition scheme 1? Y/[n]"
21-
* The sketch will warn you that the content of the QSPI flash will be erased. Answer with "Y".
22-
* When asked if you'd like to use LittleFS on the data partition, select "n". Most of the examples assume that the drive is formatted as FAT. You can use the library to format to LittleFS later.
23-
* Reboot the board
24-
25-
### Formatting the Portenta C33 Internal Storage
26-
* Flash the `QSPIFormat` example that can be found in the `Storage` folder for Portenta C33.
27-
* Open the Serial Monitor. The sketch will warn you that the content of the QSPI flash will be erased. Answer with "Y".
28-
* When asked if you'd like to use LittleFS on the data partition, select "n". Most of the examples assume that the drive is formatted as FAT. You can use the library to format to LittleFS later.
29-
* Reboot the board
16+
17+
3018

3119
## ✨ Features
3220
* Access files and directories on internal storage, SD cards, and USB mass storage devices.
@@ -36,6 +24,7 @@ The Arduino_UnifiedStorage library provides a unified interface to access differ
3624
* List files and subfolders in a directory.
3725
* Manipulate files and folders from one storage medium to another
3826
* Format partitions and drives (FAT and LittleFS)
27+
* Create and modify partitions on the internal storage
3928

4029
## Compatibility
4130
This library has been tested with the following STM32 and Renesas based Arduino boards. The availability of storage mediums depends on the hardware interfaces:

examples/AdvancedInternalStorage/AdvancedInternalStorage.ino

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,38 @@
55

66
void testWriting(Arduino_UnifiedStorage * storage){
77
Folder root = storage->getRootFolder();
8+
89
UFile file = root.createFile("file.txt", FileMode::WRITE);
10+
Serial.println("\t\t - File path: " + file.getPathAsString());
911
file.write("writing stuff to the file");
1012
file.changeMode(FileMode::READ);
11-
Serial.println("Reading from file: " + file.readAsString());
13+
Serial.println("\t\t - File contents: " + file.readAsString());
1214
file.close();
1315
file.remove();
1416
}
1517

1618
const char* createPartitionName(int i) {
17-
char buffer[20]; // Adjust the size accordingly
18-
snprintf(buffer, sizeof(buffer), "Part%d", i);
19-
return buffer;
19+
switch(i){
20+
case 1: return "uno";
21+
case 2: return "due";
22+
case 3: return "tre";
23+
case 4: return "quattro";
24+
default: return "";
25+
}
2026
}
2127

2228
void testAllPartitions(std::vector<Partition> partitions){
2329
for (size_t i = 1; i < partitions.size() + 1; ++i) {
24-
const char * partitionName = createPartitionName(i);
25-
26-
InternalStorage thisPartition = InternalStorage(i, partitionName, partitions[i - 1].fs);
30+
const char * partitionName = createPartitionName(i);
31+
InternalStorage thisPartition = InternalStorage(i, partitionName, partitions[i - 1].fileSystem);
2732
if(thisPartition.begin()){
28-
Serial.println("Succesfully initialised partition: " + String(partitionName));
33+
Serial.println("\t - Succesfully mounted partition: /" + String(partitionName));
34+
Serial.println("\t - Testing file opperations: ");
2935
testWriting(&thisPartition);
36+
3037
}
38+
39+
Serial.println();
3140
}
3241
}
3342

@@ -38,20 +47,22 @@ void setup(){
3847
Serial.begin(115200);
3948
while(!Serial);
4049

41-
std::vector<Partition> onePartition = {{16384, FS_LITTLEFS}};
50+
51+
Serial.println("Creating one partition of 16MB: ");
52+
std::vector<Partition> onePartition = {{8192, FS_LITTLEFS}};
4253
InternalStorage::partition(onePartition);
4354
testAllPartitions(onePartition);
4455
delay(5000);
4556

4657

47-
std::vector<Partition> fourPartitions = {{4096, FS_LITTLEFS}, {4096, FS_LITTLEFS}, {4096, FS_LITTLEFS}, {4096, FS_LITTLEFS}};
48-
InternalStorage::partition(fourPartitions);
49-
testAllPartitions(fourPartitions);
50-
delay(5000);
58+
std::vector<Partition> partitions = InternalStorage::readPartitions();
59+
for(auto p: partitions){
60+
Serial.println("partition size: " + String(p.size));
61+
Serial.println("partition type: " + String(p.fileSystem));
62+
Serial.println();
63+
}
5164

5265
}
5366

5467
void loop(){
55-
56-
5768
}

examples/BackupInternalPartitions/BackupInternalPartitions.ino

Lines changed: 8 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,10 @@ void move(Folder * source, Folder * dest){
7070
}
7171

7272

73-
#if defined(ARDUINO_PORTENTA_C33)
74-
void backupPartitionsC33(Folder * backupFolder){
75-
76-
Serial.println("* backup location: " + String(backupFolder -> getPathAsString()));
7773

78-
int otaMounted = ota.begin(FS_FAT);
79-
Serial.println("* ota partition mount: " + String(otaMounted));
8074

81-
int dataMounted = data.begin(FS_FAT);
82-
Serial.println("* data partition mount: " + String(dataMounted));
8375

84-
85-
if(otaMounted == 1){
76+
void backupPartitions(){
8677
Folder otaRoot = ota.getRootFolder();
8778
addSomeFakeFiles(&otaRoot);
8879
Folder otaFolder = backupFolder -> createSubfolder("ota");
@@ -91,66 +82,7 @@ void backupPartitionsC33(Folder * backupFolder){
9182
} else {
9283
Serial.println("OTA partition not mounted, cannot proceed");
9384
}
94-
95-
96-
if(dataMounted == 1){
97-
Folder dataRoot = data.getRootFolder();
98-
addSomeFakeFiles(&dataRoot);
99-
Folder dataFolder = backupFolder -> createSubfolder("data");
100-
move(&dataRoot, &dataFolder);
101-
data.unmount();
102-
} else {
103-
Serial.println("Data partition not mounted, cannot proceed");
104-
}
10585
}
106-
#endif
107-
108-
109-
#if defined(ARDUINO_PORTENTA_H7_M7)
110-
void backupPartitionsH7(Folder * backupFolder){
111-
Serial.println("* backup location: " + String(backupFolder -> getPathAsString()));
112-
113-
int wifiMounted = wifi.begin(FS_FAT);
114-
Serial.println("* wifi partition mount: " + String(wifiMounted));
115-
116-
int otaMounted = ota.begin(FS_FAT);
117-
Serial.println("* ota partition mount: " + String(otaMounted));
118-
119-
int dataMounted = data.begin(FS_FAT);
120-
Serial.println("* data partition mounted: " + String(dataMounted));
121-
122-
if(wifiMounted == 1){
123-
Folder wifiRoot = wifi.getRootFolder();
124-
addSomeFakeFiles(&wifiRoot);
125-
Folder wifiFolder = backupFolder -> createSubfolder("wifi");
126-
move(&wifiRoot, &wifiFolder);
127-
wifi.unmount();
128-
} else {
129-
Serial.println("WiFi partition not mounted, cannot proceed");
130-
}
131-
132-
if(otaMounted == 1){
133-
Folder otaRoot = ota.getRootFolder();
134-
addSomeFakeFiles(&otaRoot);
135-
Folder otaFolder = backupFolder -> createSubfolder("ota");
136-
move(&otaRoot, &otaFolder);
137-
ota.unmount();
138-
} else {
139-
Serial.println("OTA partition not mounted, cannot proceed");
140-
}
141-
142-
143-
if(dataMounted == 1){
144-
Folder dataRoot = data.getRootFolder();
145-
addSomeFakeFiles(&dataRoot);
146-
Folder dataFolder = backupFolder -> createSubfolder("data");
147-
move(&dataRoot, &dataFolder);
148-
data.unmount();
149-
} else {
150-
Serial.println("Data partition not mounted, cannot proceed");
151-
}
152-
}
153-
#endif
15486

15587
void setup(){
15688
randomSeed(analogRead(A0));
@@ -167,12 +99,13 @@ void setup(){
16799
String folderName = "InternalBackup_" + String(millis());
168100
Folder backupFolder = thumbRoot.createSubfolder(folderName);
169101

170-
171-
#if defined(ARDUINO_PORTENTA_H7_M7)
172-
backupPartitionsH7(&backupFolder);
173-
#elif defined(ARDUINO_PORTENTA_C33)
174-
backupPartitionsC33(&backupFolder);
175-
#endif
102+
int partitionIndex = 0;
103+
for (auto part: InternalStorage::readPartitions()){
104+
partitionBackupFolderName = "Part" + String(partitionIndex);
105+
backupFolder.createFolder(partitionBackupFolderName);
106+
107+
108+
}
176109

177110
thumbDrive.unmount();
178111

examples/PortentaH7Logger/PortentaH7Logger.ino renamed to examples/Logger/Logger.ino

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,21 @@ INSTRUCTIONS
2222

2323
#include "Arduino_UnifiedStorage.h"
2424
#include <vector>
25-
#include <Output.h>
2625

27-
constexpr auto baudrate { 115200 };
2826

2927
#if defined(ARDUINO_PORTENTA_H7_M7)
3028
#define USB_MOUNTED_LED LED_BLUE
3129
#elif defined(ARDUINO_PORTENTA_C33)
3230
#define USB_MOUNTED_LED LEDB
31+
#elif defined(ARDUINO_OPTA)
32+
#define USB_MOUNTED_LED LED_D0
3333
#endif
3434

3535

3636
InternalStorage internalStorage = InternalStorage();
3737
USBStorage usbStorage = USBStorage();
38+
Folder backupFolder = Folder();
39+
bool usbIntialized = false;
3840
std::vector<String> sensorDataBuffer;
3941

4042
unsigned long bytesWritten = 0;
@@ -47,10 +49,12 @@ volatile bool usbAvailable = false;
4749
bool backingUP = false;
4850

4951
void connectionCallback(){
52+
printToSerialOrRS485("CONNECTION CALLBACK RAISED !!!");
5053
usbAvailable = true;
5154
}
5255

5356
void disconnectionCallback(){
57+
printToSerialOrRS485("DISCONNECTION CALLBACK RAISED !!!");
5458
usbAvailable = false;
5559
}
5660
// Function to run a given method periodically
@@ -67,7 +71,7 @@ void runPeriodically(void (*method)(), unsigned long interval, unsigned long* va
6771
void logDataToRAM() {
6872
int timeStamp = millis();
6973
int sensorReading = analogRead(A0);
70-
String line = String(timeStamp) + "," + String(sensorReading) + "\n";
74+
String line = String(timeStamp) + "," + String(random(9999)) + "\n";
7175
sensorDataBuffer.push_back(line);
7276
}
7377

@@ -84,18 +88,17 @@ void moveDataToQSPI() {
8488

8589

8690
void performUpdate() {
87-
Folder usbRoot = usbStorage.getRootFolder(); // Get the root folder of the USB storage
8891
UFile logFile = internalStorage.getRootFolder().createFile("log.txt", FileMode::READ);
89-
UFile backupFile = usbRoot.createFile("backup_file.txt", FileMode::APPEND); // Create or open the backup file
90-
UFile lastUpdateFile = usbRoot.createFile("diff.txt", FileMode::READ); // Create or open the last update file
92+
UFile backupFile = backupFolder.createFile("backup_file.txt", FileMode::APPEND); // Create or open the backup file
93+
UFile lastUpdateFile = backupFolder.createFile("diff.txt", FileMode::READ); // Create or open the last update file
9194

9295
backingUP = true;
9396
unsigned lastUpdateBytes = lastUpdateFile.readAsString().toInt(); // Read the last update size from the file
9497

95-
Serial.print("Last update bytes: " + String(lastUpdateBytes) + "\n");
98+
printToSerialOrRS485("Last update bytes: " + String(lastUpdateBytes) + "\n");
9699

97100
if (lastUpdateBytes >= bytesWritten) {
98-
Serial.print("No new data to copy. \n");
101+
printToSerialOrRS485("No new data to copy. \n");
99102
backupFile.close();
100103
lastUpdateFile.close();
101104
backingUP = false;
@@ -104,14 +107,14 @@ void performUpdate() {
104107

105108
logFile.seek(lastUpdateBytes); // Move the file pointer to the last update position
106109
unsigned long totalBytesToMove = bytesWritten - lastUpdateBytes;
107-
Serial.print("New update bytes: " + String(totalBytesToMove) + "\n");
110+
printToSerialOrRS485("New update bytes: " + String(totalBytesToMove) + "\n");
108111

109112
uint8_t* buffer = new uint8_t[totalBytesToMove];
110113

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

114-
Serial.print("Successfully copied " + String(bytesMoved) + " new bytes.");
117+
printToSerialOrRS485("Successfully copied " + String(bytesMoved) + " new bytes. \n");
115118

116119
lastUpdateFile.changeMode(FileMode::WRITE); // Open the last update file in write mode
117120
lastUpdateFile.write(String(lastUpdateBytes + bytesMoved)); // Update the last update size
@@ -131,24 +134,34 @@ void performUpdate() {
131134

132135
// Function to backup data to USB storage
133136
void backupToUSB() {
134-
if (usbAvailable) {
135-
Serial.print("USB Mass storage is available \n");
137+
if(usbAvailable && !usbIntialized){
138+
usbStorage.begin();
139+
printToSerialOrRS485("First drive insertion, creating folders... \n");
140+
Folder usbRoot = usbStorage.getRootFolder();
141+
String folderName = "LoggerBackup" + String(random(9999));
142+
backupFolder = usbRoot.createSubfolder(folderName);
143+
printToSerialOrRS485("Succesfully created backup folder: " + backupFolder.getPathAsString() + "\n");
144+
usbStorage.unmount();
145+
usbIntialized = true;
146+
}
147+
else if(usbAvailable && usbIntialized) {
148+
printToSerialOrRS485("USB Mass storage is available \n");
136149
delay(100);
137150
if (!usbStorage.isMounted()) {
138151

139-
Serial.print("Mounting USB Mass Storage \n");
152+
printToSerialOrRS485("Mounting USB Mass Storage \n");
140153
digitalWrite(USB_MOUNTED_LED, LOW);
141154
if(usbStorage.begin()){
142155
performUpdate();
143156
}
144157

145158
} else if (usbStorage.isMounted()) {
146-
Serial.print("USB Mass storage is connected, performing update \n");
159+
printToSerialOrRS485("USB Mass storage is connected, performing update \n");
147160
performUpdate();
148161

149162
}
150163
} else {
151-
Serial.print("USB Mass storage is not available \n");
164+
printToSerialOrRS485("USB Mass storage is not available \n");
152165
}
153166

154167

@@ -157,24 +170,30 @@ void backupToUSB() {
157170

158171
void setup() {
159172
//beginRS485(baudrate);
160-
Serial.begin(115200);
161-
while(!Serial);
173+
randomSeed(analogRead(A0));
174+
175+
#if !defined(ARDUINO_OPTA)
176+
Serial.begin(115200);
177+
while(!Serial);
178+
#else
179+
beginRS485(115200);
180+
#endif
162181

163182
usbStorage.onConnect(connectionCallback);
164183
usbStorage.onDisconnect(disconnectionCallback);
165184

166185
pinMode(USB_MOUNTED_LED, OUTPUT);
167-
Serial.print("Formatting internal storage... \n");
186+
printToSerialOrRS485("Formatting internal storage... \n");
168187
int formatted = internalStorage.format(FS_LITTLEFS);
169-
Serial.print("QSPI Format status: " + String(formatted) + "\n");
170-
188+
printToSerialOrRS485("QSPI Format status: " + String(formatted) + "\n");
189+
171190

172191

173192
if (!internalStorage.begin()) {
174-
Serial.print("Failed to initialize internal storage \n");
193+
printToSerialOrRS485("Failed to initialize internal storage \n");
175194
return;
176195
} else {
177-
Serial.print("Initialized storage \n");
196+
printToSerialOrRS485("Initialized storage \n");
178197
}
179198

180199
}

examples/OptaLogger/OptaLogger.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ constexpr auto baudrate { 115200 };
3131

3232

3333

34-
InternalStorage internalStorage = InternalStorage(true, "userData", FS_FAT);
34+
InternalStorage internalStorage = InternalStorage(]);
3535
USBStorage usbStorage = USBStorage();
3636
std::vector<String> sensorDataBuffer;
3737

0 commit comments

Comments
 (0)