#include "QSPIFBlockDevice.h"
#include "MBRBlockDevice.h"
#include "FATFileSystem.h"
void setup() {
// put your setup code here, to run once:
while(!Serial) {};
Serial.println("Start setup");
QSPIFBlockDevice root;
mbed::FATFileSystem ota("ota");
mbed::MBRBlockDevice ota_data(&root, 2);
Serial.println("Try to mount:");
ota.mount(&ota_data);
Serial.println("All setup, start reading...");
FILE* f = fopen("/ota/myFile.txt", "r");
Serial.print("Errno: ");
Serial.println(errno);
Serial.print("Opened file: ");
Serial.println((int)f);
const int bufferSize = 512;
char buffer[bufferSize];
int size = 0;
do {
size = fread(buffer, 1, bufferSize, f);
Serial.write(buffer, size);
} while(size == bufferSize);
fclose(f);
ota.unmount();
}
void loop() {
// put your main code here, to run repeatedly:
}
However when I try to read from the filesystem when I also use the WiFi, then I am unable to open the file, the file pointer is zero. The WiFi Network does get created successfully. Since the WiFi Firmware seems to be also stored on the flash, I assume there is some kind of problem with trying to access the flash twice? Sadly I am not sure how to fix it. My Sketch (does not work):
#include "QSPIFBlockDevice.h"
#include "MBRBlockDevice.h"
#include "FATFileSystem.h"
#include <SPI.h>
#include <WiFi.h>
char ssid[] = "myNetwork"; // your network SSID (name)
char pass[] = "myPassword"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key index number (needed only for WEP)
int status = WL_IDLE_STATUS;
void setup() {
// put your setup code here, to run once:
while(!Serial) {};
// print the network name (SSID);
Serial.print("Creating access point named: ");
Serial.println(ssid);
status = WiFi.beginAP(ssid, pass);
if (status != WL_AP_LISTENING) {
Serial.println("Creating access point failed");
// don't continue
while (true)
;
}
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print where to go in a browser:
Serial.print("To see this page in action, open a browser to http://");
Serial.println(ip);
Serial.println("Start setup");
QSPIFBlockDevice root;
mbed::FATFileSystem ota("ota");
mbed::MBRBlockDevice ota_data(&root, 2);
Serial.println("Try to mount:");
ota.mount(&ota_data);
Serial.println("All setup, start reading...");
FILE* f = fopen("/ota/myFile.txt", "r");
Serial.print("Errno: ");
Serial.println(errno);
Serial.print("Opened file: ");
Serial.println((int)f);
const int bufferSize = 512;
char buffer[bufferSize];
int size = 0;
do {
size = fread(buffer, 1, bufferSize, f);
Serial.write(buffer, size);
} while(size == bufferSize);
fclose(f);
ota.unmount();
}
void loop() {
// put your main code here, to run repeatedly:
}
My Questions:
Did anyone already read a file from the flash storage while using the WiFi? If yes could you provide me with some tips about how to do it?
Does anyone know if my first sketch (which does work because WiFi is not used) uses the API as intended? Sadly I did not find any examples, so it is my best guess on how to do things but I am not quite sure.
thank you for your help!
When creating the sketch I did already take a look at the QSPIFormat example, however the link to the Arduino Portenta OTA Library was new for me.
With that I managed to solve the problem:
In the sketch above I did create a QSPIFBlockDevice root;
in the same way as the QSPIFormat example also does it. This does work fine as long as the wifi is not used in parallel. It seems as there can only be one BlockDevice for the flash storage, so as soon as the wifi is used (which has its firmware on the flash storage), the BlockDevice does already exist and can not be created again (it actually doesnt throw an error when creating, however it is impossible to do any file interactions).
The right way to deal with that seems to be the way the Portenta OTA library does do it: mbed::BlockDevice* raw_qspi = mbed::BlockDevice::get_default_instance();
With this pointer the access to the Flash storage works fine, the file does get read successfully (no matter if wifi does get used or not).
Thank you very much for providing this helpful link!
With kind regards
efs95
PS: The corrected example script:
#include "QSPIFBlockDevice.h"
#include "MBRBlockDevice.h"
#include "FATFileSystem.h"
#include <SPI.h>
#include <WiFi.h>
char ssid[] = "myNetwork"; // your network SSID (name)
char pass[] = "myPassword"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key index number (needed only for WEP)
int status = WL_IDLE_STATUS;
void setup() {
// put your setup code here, to run once:
while(!Serial) {};
// print the network name (SSID);
Serial.print("Creating access point named: ");
Serial.println(ssid);
status = WiFi.beginAP(ssid, pass);
if (status != WL_AP_LISTENING) {
Serial.println("Creating access point failed");
// don't continue
while (true)
;
}
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print where to go in a browser:
Serial.print("To see this page in action, open a browser to http://");
Serial.println(ip);
Serial.println("Start setup");
mbed::BlockDevice* raw_qspi = mbed::BlockDevice::get_default_instance(); // <- This line changed, use of the already existing BlockDevice
mbed::FATFileSystem ota("ota");
mbed::MBRBlockDevice ota_data(raw_qspi, 2); // Use the BlockDevice specified above
Serial.println("Try to mount:");
ota.mount(&ota_data);
Serial.println("All setup, start reading...");
FILE* f = fopen("/ota/myFile.txt", "r");
Serial.print("Errno: ");
Serial.println(errno);
Serial.print("Opened file: ");
Serial.println((int)f);
const int bufferSize = 512;
char buffer[bufferSize];
int size = 0;
do {
size = fread(buffer, 1, bufferSize, f);
Serial.write(buffer, size);
} while(size == bufferSize);
fclose(f);
ota.unmount();
}
void loop() {
// put your main code here, to run repeatedly:
}
efs95 And thanks to your help I figured out a similar and even more basic issue I was having.
The QSPI FLASH must be formatted and partitioned before the WiFi OTA updater will work. This basic requirement isn't mentioned in the WiFi OTA Updater documentation and you get a -3 error when it tries to access the FLASH file system.
So for the benefit of others here's the necessary sequence.
Run File > Examples > STM32H747_System > QSPIFormat (Partition scheme 1 is good.)
Run File > Examples > STM32H747_System > WiFiFirmwareUpdater (Do this second otherwise it gets deleted when you Format and Partition
Now run the OTA updater code.
This sequence is slightly different than that given in the Flash section of the Cheat Sheet but it leaves you with a functioning WiFi vs the cheat sheet having overwritten it.
I found that I didn’t have to use WiFi to get this issue . For me it seems to be a product of the new mcuboot based bootloader which accesses the static qspi instance during the boot . As far as I can tell none of the examples have been updated to reflect this.
Found the same issue today in the debugger trying to work out why my qspi code failed after a bootloader update.