From 75a708dd4dfa07a4586fa46b6f940ff7cc981ed7 Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Thu, 15 Jun 2023 14:58:41 +0200 Subject: [PATCH] fix FS: computeNewSpeed() out from interrupt, added locks for FS operations --- cli.cpp | 5 ---- fs.cpp | 47 ++++++++++++++++++++++---------------- fs.h | 2 +- motor.h | 20 +++++++++------- pousseseringue-arduino.cpp | 47 ++++++++++++++++++++++++++++---------- 5 files changed, 75 insertions(+), 46 deletions(-) diff --git a/cli.cpp b/cli.cpp index a8d0e90..5d76226 100644 --- a/cli.cpp +++ b/cli.cpp @@ -340,11 +340,6 @@ void Cli::loop (Stream& input) ls(&Serial); answer(true); } - else if (kw(F("FS-FORMAT"))) - { - format(&Serial); - answer(true); - } else if (kw(F("FS-CAT"))) { copyNextToTemp(); diff --git a/fs.cpp b/fs.cpp index 16592cd..a02b429 100644 --- a/fs.cpp +++ b/fs.cpp @@ -3,53 +3,58 @@ #include <ESPWebDAV.h> #include <LittleFS.h> #include <StreamString.h> +#include <interrupts.h> // InterruptLock #include "fs.h" +#include "syringe.h" + +using InterruptLock = esp8266::InterruptLock; + +extern Syringe syringe; ESPWebDAVCore* dav = nullptr; ESP8266WebServer* http = nullptr; FS* filesystem = nullptr; const char* fsMsgHeader = nullptr; -bool fs_init (const char* msgHeader) +bool fs_init (const char* msgHeader, Print* out) { fsMsgHeader = msgHeader; filesystem = &LittleFS; + if (!filesystem->begin() && (!filesystem->format() || !filesystem->begin())) + { + out->printf("%sFS: mount/format/mount: failed\n", fsMsgHeader); return false; + } + http = new (std::nothrow) ESP8266WebServer(HTTPORT); if (!http) + { + out->printf("#%sFS: http server start: failed\n", fsMsgHeader); return false; + } + dav = new (std::nothrow) ESPWebDAVCore; if (!dav) { + out->printf("%sFS: webdav allocation: failed\n", fsMsgHeader); delete http; return false; } + dav->begin(filesystem); http->addHook(hookWebDAVForWebserver(DAVROOT, *dav)); + return true; } - void ls (Print* out) { if (dav) { - out->printf("#%sLS:\n", fsMsgHeader); - dav->dir("/", out); - } -} - -void format (Print* out) -{ - if (filesystem) - { - out->printf("%sformatting\n", fsMsgHeader); - out->flush(); - filesystem->format(); - out->printf("%smkdir %s\n", fsMsgHeader, DAVROOT); - filesystem->mkdir(DAVROOT); + out->printf("%sLS:\n", fsMsgHeader); + { InterruptLock lock; dav->dir("/", out); } } } @@ -57,14 +62,15 @@ void cat (const char* filename, Stream* out) { if (filesystem) { - File f = filesystem->open(filename, "r"); + File f = ({ InterruptLock lock; filesystem->open(filename, "r"); }); if (!f) out->printf("%scat: '%s' not found\n", fsMsgHeader, filename); else { out->printf("%s>>>>FILE name:'%s' fullname:'%s' size=%zd\n", fsMsgHeader, f.name(), f.fullName(), f.size()); - f.sendSize(out, f.size()); + { InterruptLock lock; f.sendSize(out, f.size()); } out->printf("%s<<<<FILE\n", fsMsgHeader); + { InterruptLock lock; f.close(); } } } } @@ -73,13 +79,14 @@ void testw (const char* filename, Stream* out) { if (filesystem) { - File f = filesystem->open(filename, "w"); + File f = ({ InterruptLock lock; filesystem->open(filename, "w"); }); if (!f) out->printf("%stest: '%s' can't write\n", fsMsgHeader, filename); else { StreamString blah = "blah"; - blah.sendAll(f); + { InterruptLock lock; blah.sendAll(f); } + { InterruptLock lock; f.close(); } } } } diff --git a/fs.h b/fs.h index 1c690dc..958e722 100644 --- a/fs.h +++ b/fs.h @@ -12,7 +12,7 @@ #define HTTPORT 80 #endif -bool fs_init (const char* msgHeader); +bool fs_init (const char* msgHeader, Print* out); void ls (Print* out); void format (Print* out); void cat (const char* filename, Stream* out); diff --git a/motor.h b/motor.h index c7a8d48..9aaf403 100644 --- a/motor.h +++ b/motor.h @@ -13,22 +13,27 @@ class AccelStepper #include <AccelStepper.h> #endif +class isrStepper: public AccelStepper +{ + // usefulness: make computeNewSpeed() public to be called outside from interrupt +public: + isrStepper(uint8_t interface = AccelStepper::FULL4WIRE, uint8_t pin1 = 2, uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5, bool enable = true): + AccelStepper(interface, pin1, pin2, pin3, pin4, enable) { } + inline unsigned long computeNewSpeed () { return AccelStepper::computeNewSpeed(); } +}; + class Motor { public: - using MotorHardware_t = AccelStepper; + using MotorHardware_t = isrStepper; - Motor (AccelStepper& stepper): stepper(stepper) + Motor (isrStepper& stepper): stepper(stepper) { setSpeedMmPerSec(1); setAccelMmPerSecPerSec(0.5); // <----- this is not yet configured by user } - void setLock (bool locked) { _locked = locked; } - - bool locked () const { return _locked; } - void setMmPerRev (float mmPerRevolution) { _mmPerRevolution = mmPerRevolution; @@ -167,11 +172,10 @@ public: protected: - bool _locked = false; int _stepsPerRevolution = -1; float _mmPerRevolution = -1; float _retainAccel = -1; bool _forwardClockwise; - AccelStepper& stepper; + isrStepper& stepper; }; diff --git a/pousseseringue-arduino.cpp b/pousseseringue-arduino.cpp index 16b7547..14b00b6 100644 --- a/pousseseringue-arduino.cpp +++ b/pousseseringue-arduino.cpp @@ -41,6 +41,9 @@ #include <ESP8266WiFi.h> // internal, wifi library #include <DNSServer.h> // internal, access point mode #include <Schedule.h> +#include <interrupts.h> // InterruptLock + +using InterruptLock = esp8266::InterruptLock; #if !CORE_MOCK #include <SSD1306AsciiWire.h> // https://github.com/greiman/SSD1306Ascii @@ -50,9 +53,9 @@ SSD1306AsciiWire oled; #include "motor.h" #if CORE_MOCK -AccelStepper stepper; +isrStepper stepper; #else -AccelStepper stepper(AccelStepper::DRIVER, STEP, DIR); +isrStepper stepper(AccelStepper::DRIVER, STEP, DIR); #endif @@ -62,8 +65,6 @@ AccelStepper stepper(AccelStepper::DRIVER, STEP, DIR); #include "common.h" #include "fs.h" - - enum class Modes { TURN, TURNSetup, RPM, RPMSetup, INFO }; const char* msgHeader = MSGHEADER; @@ -245,16 +246,26 @@ void buttons (int shortp, int longp) #if !CORE_MOCK IRAM_ATTR -void stepperRun () +void stepperRunOLD () { - if (syringe.locked()) - return; - cli(); +// if (syringe.locked()) +// return; +// cli(); +#if 0 if (rpming) stepperMoving = stepper.runSpeed(); else stepperMoving = stepper.run(); - sei(); +#else + stepperMoving = stepper.runSpeed(); +#endif +// sei(); +} + +IRAM_ATTR +void stepperRun () +{ + stepperMoving = stepper.runSpeed(); } #endif // !CORE_MOCK @@ -263,6 +274,9 @@ void setup() { Serial.begin(BAUDRATE); Serial.setDebugOutput(true); + Serial.println(); + Serial.println("Booting"); + #if !CORE_MOCK Wire.begin(); Wire.setClock(400000L); @@ -285,6 +299,8 @@ void setup() digitalWrite(SLEEP, 0); #endif // !CORE_MOCK +#if 0 + uint8_t mac[6]; WiFi.macAddress(mac); sprintf(ssid, NAME "-%02x%02x%02x", mac[3], mac[4], mac[5]); @@ -311,6 +327,10 @@ void setup() webSetup(); + +#endif //0 + + pinMode(BTNA, INPUT_PULLUP); pinMode(BTNB, INPUT_PULLUP); pinMode(BTNC, INPUT_PULLUP); @@ -318,25 +338,29 @@ void setup() oledRedisplay(); +#if 1 + #if !CORE_MOCK #ifdef ISR_ATTR timer1_isr_init(); timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP); timer1_attachInterrupt(stepperRun); timer1_write(microsecondsToClockCycles(100)); + schedule_recurrent_function_us([](){ if (stepperMoving) { InterruptLock lock; stepper.computeNewSpeed(); } return true; }, 1); #else #warning =================================================================================================== #warning "Please use the ISR version of AccelStepper (git clone -b isr https://github.com/d-a-v/AccelStepper)" #warning =================================================================================================== schedule_recurrent_function_us([](){ stepperRun(); return true; }, 1); #endif +#endif + #endif // check if emergency button is pressed at boot time syringe.setEmergency(digitalRead(COURSE)); -#if 0 - if (fs_init(msgHeader)) + if (fs_init(msgHeader, &Serial)) { Serial.printf("FS initialized, dav http server started\n"); } @@ -344,7 +368,6 @@ void setup() { Serial.printf("FS: could not be started\n"); } -#endif } -- GitLab