I have run into a rather strange issue with LittleFS cause a ESP32 to hard crash whenever I try and post a file to a webserver hosted on the ESP32 after uploading a filesystem image via the Platform IO IDE.
I have confirmed this is something to do with the Uploaded file system as when I erase the flash and just run the code without providing the filesystem I’m able to upload the file happily without issue. I have also proven that I can still access the files on the filesystem if I do ‘Upload Filesystem Image’ and not upload any additional files, so I’m a bit lost as to why this would be the case.
I have a feeling it’s something to do with the partition table potentially but I don’t have much knowledge of that area. What I aim to do is upload the filesystem to the ESP initially but I ever need to update the CA certificate or other files I can connect to it’s network and provide the files via a POST to the webserver.
Any assistance or thoughts would be appreciated. I have attached the data I usually put in the file system, the platform.io file and code I’m currently testing with.
[env:esp32-s3-devkitm-1]
platform = espressif32
board = esp32-s3-devkitm-1
board_build.filesystem = littlefs
framework = arduino
upload_port = COM4
;monitor_port = COM5
monitor_speed = 115200
build_flags =
'-D ARDUINO_USB_MODE=0'
'-D ARDUINO_USB_CDC_ON_BOOT=0'
monitor_filters = esp32_exception_decoder
lib_deps =
pfeerick/elapsedMillis@^1.0.6
bblanchon/ArduinoJson@^7.0.4
256dpi/MQTT@^2.5.2
#include "Arduino.h"
#include <ESPmDNS.h>
#include <WebServer.h>
#include <ArduinoJson.h>
#include "elapsedMillis.h"
#include "Storage.h"
#include "LittleFS.h"
WebServer configNetwork(80);
IPAddress ip(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
elapsedMillis standbyTimer;
unsigned int standbyTimeout = 60000;
Storage* _storage;
bool useConfigNetwork = false;
void handleCACertPost() {
if (!configNetwork.hasArg("plain")) {
configNetwork.send(400, F("application/json"), "{\"message\": \"No file uploaded.\"}");
return;
}
Serial.println("Upload filename: /AmazonRootCA1.pem");
if (!LittleFS.begin()) {
Serial.println("An Error has occurred while mounting LittleFS");
configNetwork.send(500, F("application/json"), "{\"message\": \"An Error has occurred while mounting LittleFS.\"}");
return;
}
File uploadFile = LittleFS.open("/AmazonRootCA1.pem", FILE_WRITE);
if (!uploadFile) {
Serial.println("Failed to open file for writing");
configNetwork.send(500, F("application/json"), "{\"message\": \"Failed to open file for writing.\"}");
return;
}
int contentLength = configNetwork.arg("plain").length();
if (contentLength > 0) {
int written = uploadFile.write((uint8_t *)configNetwork.arg("plain").c_str(), contentLength);
if (written != contentLength) {
Serial.println("Write failed");
configNetwork.send(500, "text/plain", "Write failed");
uploadFile.close();
return;
}
uploadFile.close();
Serial.println("File Uploaded Successfully");
configNetwork.send(200, F("application/json"), "{\"message\": \"Saved CA certificate.\"}");
} else {
Serial.println("Content-Length was zero or invalid");
configNetwork.send(400, F("application/json"), "{\"message\": \"Content-Length was zero or invalid.\"}");
}
}
void handleWifiPost() {
String body = configNetwork.arg(F("plain"));
Serial.println(body);
JsonDocument doc;
deserializeJson(doc, body);
const char* ssid = doc["ssid"].as<const char*>();
const char* password = doc["password"].as<const char*>();
_storage->putWifiSSID(doc["ssid"]);
_storage->putWifiPassword(doc["password"]);
configNetwork.send(200, F("application/json"), "{\"message\": \"Saved wifi credentials.\"}");
}
void handleRebootPost() {
Serial.println(F("Hardware will restart in 5 seconds"));
configNetwork.send(200, "application/json", "{ \"message\": \"Hardware will restart in 5 seconds!\"}");
delay(5000);
ESP.restart();
}
void beginConfigNetwork() {
Serial.println(F("Configuring and starting config network."));
useConfigNetwork = true;
standbyTimer = 0;
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_AP);
WiFi.softAP(storage->getId().c_str(), NULL, 6);
WiFi.softAPConfig(ip, ip, subnet);
MDNS.begin("esp");
configNetwork.on(F("/security/key"), HTTP_POST, handleDeviceKeyPost);
configNetwork.on(F("/security/ca"), HTTP_POST, handleCACertPost);
configNetwork.on(F("/security/wifi"), HTTP_POST, handleWifiPost);
configNetwork.on(F("/reboot"), HTTP_POST, handleRebootPost);
configNetwork.begin();
}
void resetConfigNetwork() {
Serial.println(F("Resetting and restarting config network."));
configNetwork.stop();
delay(1000);
configNetwork.begin();
standbyTimer = 0;
}
void stopConfigNetwork() {
useConfigNetwork = false;
MDNS.end();
configNetwork.stop();
}
void loopConfigNetwork() {
configNetwork.handleClient();
if (WiFi.softAPgetStationNum() < 1) {
if (standbyTimer > standbyTimeout) {
standbyTimer = 0;
resetConfigNetwork();
}
} else {
standbyTimer = 0;
}
}
void setup() {
Serial.begin(115200);
btStop();
delay(2000);
beginConfigNetwork();
}
void loop() {
loopConfigNetwork();
}