mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-10 11:57:25 +00:00
* add more locking for shared SPI devices (#5595) * add more locking for shared SPI devices * call initSPI before the lock is used * remove old one * don't double lock * Add missing unlock * More missing unlocks * Add locks to SafeFile, remove from `readcb`, introduce some LockGuards * fix lock in setupSDCard() * pull radiolib trunk with SPI-CS fixes * change ContentHandler to Constructor type locks, where applicable --------- Co-authored-by: mverch67 <manuel.verch@gmx.de> Co-authored-by: GUVWAF <thijs@havinga.eu> Co-authored-by: Manuel <71137295+mverch67@users.noreply.github.com> * mesh-tab: lower I2C touch frequency --------- Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com> Co-authored-by: mverch67 <manuel.verch@gmx.de> Co-authored-by: GUVWAF <thijs@havinga.eu> Co-authored-by: Manuel <71137295+mverch67@users.noreply.github.com>
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include "PowerFSM.h"
|
||||
#include "RTC.h"
|
||||
#include "Router.h"
|
||||
#include "SPILock.h"
|
||||
#include "SafeFile.h"
|
||||
#include "TypeConversions.h"
|
||||
#include "error.h"
|
||||
@@ -423,12 +424,15 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
|
||||
{
|
||||
LOG_INFO("Perform factory reset!");
|
||||
// first, remove the "/prefs" (this removes most prefs)
|
||||
rmDir("/prefs");
|
||||
spiLock->lock();
|
||||
rmDir("/prefs"); // this uses spilock internally...
|
||||
|
||||
#ifdef FSCom
|
||||
if (FSCom.exists("/static/rangetest.csv") && !FSCom.remove("/static/rangetest.csv")) {
|
||||
LOG_ERROR("Could not remove rangetest.csv file");
|
||||
}
|
||||
#endif
|
||||
spiLock->unlock();
|
||||
// second, install default state (this will deal with the duplicate mac address issue)
|
||||
installDefaultDeviceState();
|
||||
installDefaultConfig(!eraseBleBonds); // Also preserve the private key if we're not erasing BLE bonds
|
||||
@@ -913,6 +917,7 @@ LoadFileResult NodeDB::loadProto(const char *filename, size_t protoSize, size_t
|
||||
{
|
||||
LoadFileResult state = LoadFileResult::OTHER_FAILURE;
|
||||
#ifdef FSCom
|
||||
concurrency::LockGuard g(spiLock);
|
||||
|
||||
auto f = FSCom.open(filename, FILE_O_READ);
|
||||
|
||||
@@ -946,8 +951,10 @@ void NodeDB::loadFromDisk()
|
||||
// disk we will still factoryReset to restore things.
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
spiLock->lock();
|
||||
if (FSCom.exists("/static/static"))
|
||||
rmDir("/static/static"); // Remove bad static web files bundle from initial 2.5.13 release
|
||||
spiLock->unlock();
|
||||
#endif
|
||||
|
||||
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
|
||||
@@ -1097,9 +1104,6 @@ void NodeDB::loadFromDisk()
|
||||
bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_t *fields, const void *dest_struct,
|
||||
bool fullAtomic)
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
concurrency::LockGuard g(spiLock);
|
||||
#endif
|
||||
bool okay = false;
|
||||
#ifdef FSCom
|
||||
auto f = SafeFile(filename, fullAtomic);
|
||||
@@ -1127,7 +1131,9 @@ bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_
|
||||
bool NodeDB::saveChannelsToDisk()
|
||||
{
|
||||
#ifdef FSCom
|
||||
spiLock->lock();
|
||||
FSCom.mkdir("/prefs");
|
||||
spiLock->unlock();
|
||||
#endif
|
||||
return saveProto(channelFileName, meshtastic_ChannelFile_size, &meshtastic_ChannelFile_msg, &channelFile);
|
||||
}
|
||||
@@ -1135,7 +1141,9 @@ bool NodeDB::saveChannelsToDisk()
|
||||
bool NodeDB::saveDeviceStateToDisk()
|
||||
{
|
||||
#ifdef FSCom
|
||||
spiLock->lock();
|
||||
FSCom.mkdir("/prefs");
|
||||
spiLock->unlock();
|
||||
#endif
|
||||
// Note: if MAX_NUM_NODES=100 and meshtastic_NodeInfoLite_size=166, so will be approximately 17KB
|
||||
// Because so huge we _must_ not use fullAtomic, because the filesystem is probably too small to hold two copies of this
|
||||
@@ -1148,7 +1156,9 @@ bool NodeDB::saveToDiskNoRetry(int saveWhat)
|
||||
bool success = true;
|
||||
|
||||
#ifdef FSCom
|
||||
spiLock->lock();
|
||||
FSCom.mkdir("/prefs");
|
||||
spiLock->unlock();
|
||||
#endif
|
||||
if (saveWhat & SEGMENT_CONFIG) {
|
||||
config.has_device = true;
|
||||
@@ -1199,7 +1209,9 @@ bool NodeDB::saveToDisk(int saveWhat)
|
||||
if (!success) {
|
||||
LOG_ERROR("Failed to save to disk, retrying");
|
||||
#ifdef ARCH_NRF52 // @geeksville is not ready yet to say we should do this on other platforms. See bug #4184 discussion
|
||||
spiLock->lock();
|
||||
FSCom.format();
|
||||
spiLock->unlock();
|
||||
|
||||
#endif
|
||||
success = saveToDiskNoRetry(saveWhat);
|
||||
@@ -1518,4 +1530,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
|
||||
LOG_ERROR("A critical failure occurred, portduino is exiting");
|
||||
exit(2);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "PhoneAPI.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "RadioInterface.h"
|
||||
#include "SPILock.h"
|
||||
#include "TypeConversions.h"
|
||||
#include "main.h"
|
||||
#include "xmodem.h"
|
||||
@@ -54,7 +55,9 @@ void PhoneAPI::handleStartConfig()
|
||||
// even if we were already connected - restart our state machine
|
||||
state = STATE_SEND_MY_INFO;
|
||||
pauseBluetoothLogging = true;
|
||||
spiLock->lock();
|
||||
filesManifest = getFiles("/", 10);
|
||||
spiLock->unlock();
|
||||
LOG_DEBUG("Got %d files in manifest", filesManifest.size());
|
||||
|
||||
LOG_INFO("Start API client config");
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "mesh/wifi/WiFiAPClient.h"
|
||||
#endif
|
||||
#include "Led.h"
|
||||
#include "SPILock.h"
|
||||
#include "power.h"
|
||||
#include "serialization/JSON.h"
|
||||
#include <FSCommon.h>
|
||||
@@ -236,6 +237,7 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
|
||||
|
||||
void htmlDeleteDir(const char *dirname)
|
||||
{
|
||||
|
||||
File root = FSCom.open(dirname);
|
||||
if (!root) {
|
||||
return;
|
||||
@@ -318,6 +320,7 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
|
||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||
res->setHeader("Access-Control-Allow-Methods", "GET");
|
||||
|
||||
concurrency::LockGuard g(spiLock);
|
||||
auto fileList = htmlListDir("/static", 10);
|
||||
|
||||
// create json output structure
|
||||
@@ -349,9 +352,12 @@ void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
||||
res->setHeader("Content-Type", "application/json");
|
||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||
res->setHeader("Access-Control-Allow-Methods", "DELETE");
|
||||
|
||||
if (params->getQueryParameter("delete", paramValDelete)) {
|
||||
std::string pathDelete = "/" + paramValDelete;
|
||||
concurrency::LockGuard g(spiLock);
|
||||
if (FSCom.remove(pathDelete.c_str())) {
|
||||
|
||||
LOG_INFO("%s", pathDelete.c_str());
|
||||
JSONObject jsonObjOuter;
|
||||
jsonObjOuter["status"] = new JSONValue("ok");
|
||||
@@ -360,6 +366,7 @@ void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
||||
delete value;
|
||||
return;
|
||||
} else {
|
||||
|
||||
LOG_INFO("%s", pathDelete.c_str());
|
||||
JSONObject jsonObjOuter;
|
||||
jsonObjOuter["status"] = new JSONValue("Error");
|
||||
@@ -393,6 +400,8 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
|
||||
filenameGzip = "/static/index.html.gz";
|
||||
}
|
||||
|
||||
concurrency::LockGuard g(spiLock);
|
||||
|
||||
if (FSCom.exists(filename.c_str())) {
|
||||
file = FSCom.open(filename.c_str());
|
||||
if (!file.available()) {
|
||||
@@ -410,6 +419,7 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
|
||||
file = FSCom.open(filenameGzip.c_str());
|
||||
res->setHeader("Content-Type", "text/html");
|
||||
if (!file.available()) {
|
||||
|
||||
LOG_WARN("File not available - %s", filenameGzip.c_str());
|
||||
res->println("Web server is running.<br><br>The content you are looking for can't be found. Please see: <a "
|
||||
"href=https://meshtastic.org/docs/software/web-client/>FAQ</a>.<br><br><a "
|
||||
@@ -535,6 +545,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
||||
// concepts of the body parser functionality easier to understand.
|
||||
std::string pathname = "/static/" + filename;
|
||||
|
||||
concurrency::LockGuard g(spiLock);
|
||||
// Create a new file to stream the data into
|
||||
File file = FSCom.open(pathname.c_str(), FILE_O_WRITE);
|
||||
size_t fileLength = 0;
|
||||
@@ -571,6 +582,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
||||
|
||||
file.flush();
|
||||
file.close();
|
||||
|
||||
res->printf("<p>Saved %d bytes to %s</p>", (int)fileLength, pathname.c_str());
|
||||
}
|
||||
if (!didwrite) {
|
||||
@@ -642,9 +654,11 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
|
||||
jsonObjMemory["heap_free"] = new JSONValue((int)memGet.getFreeHeap());
|
||||
jsonObjMemory["psram_total"] = new JSONValue((int)memGet.getPsramSize());
|
||||
jsonObjMemory["psram_free"] = new JSONValue((int)memGet.getFreePsram());
|
||||
spiLock->lock();
|
||||
jsonObjMemory["fs_total"] = new JSONValue((int)FSCom.totalBytes());
|
||||
jsonObjMemory["fs_used"] = new JSONValue((int)FSCom.usedBytes());
|
||||
jsonObjMemory["fs_free"] = new JSONValue(int(FSCom.totalBytes() - FSCom.usedBytes()));
|
||||
spiLock->unlock();
|
||||
|
||||
// data->power
|
||||
JSONObject jsonObjPower;
|
||||
@@ -786,6 +800,7 @@ void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res)
|
||||
|
||||
LOG_INFO("Delete files from /static/* : ");
|
||||
|
||||
concurrency::LockGuard g(spiLock);
|
||||
htmlDeleteDir("/static");
|
||||
|
||||
res->println("<p><hr><p><a href=/admin>Back to admin</a>");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#include "FSCommon.h"
|
||||
#include "SPILock.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include <Arduino.h>
|
||||
#include <pb_decode.h>
|
||||
@@ -55,9 +56,12 @@ bool readcb(pb_istream_t *stream, uint8_t *buf, size_t count)
|
||||
/// Write to an arduino file
|
||||
bool writecb(pb_ostream_t *stream, const uint8_t *buf, size_t count)
|
||||
{
|
||||
spiLock->lock();
|
||||
auto file = (Print *)stream->state;
|
||||
// LOG_DEBUG("writing %d bytes to protobuf file", count);
|
||||
return file->write(buf, count) == count;
|
||||
bool status = file->write(buf, count) == count;
|
||||
spiLock->unlock();
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -68,4 +72,4 @@ bool is_in_helper(uint32_t n, const uint32_t *array, pb_size_t count)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user