From 0a6059ba13486d9ebb6b085536ead45d73046a60 Mon Sep 17 00:00:00 2001 From: grcasanova Date: Sun, 5 Jul 2020 23:11:40 +0200 Subject: [PATCH 1/3] refactored threading-related classes, code broken --- .gitignore | 11 ++- src/WorkerThread.cpp | 49 ------------ src/WorkerThread.h | 96 ------------------------ src/concurrency/Lock.cpp | 23 ++++++ src/{lock.h => concurrency/Lock.h} | 22 +----- src/concurrency/LockGuard.cpp | 15 ++++ src/concurrency/LockGuard.h | 21 ++++++ src/concurrency/NotifiedWorkerThread.cpp | 19 +++++ src/concurrency/NotifiedWorkerThread.h | 47 ++++++++++++ src/concurrency/Thread.cpp | 16 ++++ src/concurrency/Thread.h | 34 +++++++++ src/concurrency/WorkerThread.cpp | 25 ++++++ src/concurrency/WorkerThread.h | 30 ++++++++ src/debug.cpp | 20 ----- src/debug.h | 10 --- src/lock.cpp | 50 ------------ 16 files changed, 243 insertions(+), 245 deletions(-) delete mode 100644 src/WorkerThread.cpp delete mode 100644 src/WorkerThread.h create mode 100644 src/concurrency/Lock.cpp rename src/{lock.h => concurrency/Lock.h} (59%) create mode 100644 src/concurrency/LockGuard.cpp create mode 100644 src/concurrency/LockGuard.h create mode 100644 src/concurrency/NotifiedWorkerThread.cpp create mode 100644 src/concurrency/NotifiedWorkerThread.h create mode 100644 src/concurrency/Thread.cpp create mode 100644 src/concurrency/Thread.h create mode 100644 src/concurrency/WorkerThread.cpp create mode 100644 src/concurrency/WorkerThread.h delete mode 100644 src/debug.cpp delete mode 100644 src/debug.h delete mode 100644 src/lock.cpp diff --git a/.gitignore b/.gitignore index b26acad66..c6d44fad0 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,13 @@ main/credentials.h !.vscode/settings.json !.vscode/tasks.json !.vscode/extensions.json -*.code-workspace \ No newline at end of file +*.code-workspace + +.DS_Store +Thumbs.db +.autotools +.built +.context +.cproject +.idea/* +.vagrant diff --git a/src/WorkerThread.cpp b/src/WorkerThread.cpp deleted file mode 100644 index 3c7ea4c9a..000000000 --- a/src/WorkerThread.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "WorkerThread.h" -#include "debug.h" -#include - -#ifdef configUSE_PREEMPTION - -void Thread::start(const char *name, size_t stackSize, uint32_t priority) -{ - auto r = xTaskCreate(callRun, name, stackSize, this, priority, &taskHandle); - assert(r == pdPASS); -} - -void Thread::callRun(void *_this) -{ - ((Thread *)_this)->doRun(); -} - -void WorkerThread::doRun() -{ - while (!wantExit) { - block(); - -#ifdef DEBUG_STACK - static uint32_t lastPrint = 0; - if (millis() - lastPrint > 10 * 1000L) { - lastPrint = millis(); - meshtastic::printThreadInfo("net"); - } -#endif - - loop(); - } -} - -/** - * Notify this thread so it can run - */ -void NotifiedWorkerThread::notify(uint32_t v, eNotifyAction action) -{ - xTaskNotify(taskHandle, v, action); -} - -void NotifiedWorkerThread::block() -{ - xTaskNotifyWait(0, // don't clear notification on entry - clearOnRead, ¬ification, portMAX_DELAY); // Wait forever -} - -#endif \ No newline at end of file diff --git a/src/WorkerThread.h b/src/WorkerThread.h deleted file mode 100644 index ab1864869..000000000 --- a/src/WorkerThread.h +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include "freertosinc.h" - -#ifdef HAS_FREE_RTOS - -class Thread -{ - protected: - TaskHandle_t taskHandle = NULL; - - /** - * set this to true to ask thread to cleanly exit asap - */ - volatile bool wantExit = false; - - public: - void start(const char *name, size_t stackSize = 1024, uint32_t priority = tskIDLE_PRIORITY); - - virtual ~Thread() { vTaskDelete(taskHandle); } - - uint32_t getStackHighwaterMark() { return uxTaskGetStackHighWaterMark(taskHandle); } - - protected: - /** - * The method that will be called when start is called. - */ - virtual void doRun() = 0; - - private: - static void callRun(void *_this); -}; - -/** - * This wraps threading (FreeRTOS for now) with a blocking API intended for efficiently converting onlyschool arduino loop() code. - * - * Use as a mixin base class for the classes you want to convert. - * - * https://www.freertos.org/RTOS_Task_Notification_As_Mailbox.html - */ -class WorkerThread : public Thread -{ - protected: - /** - * A method that should block execution - either waiting ona queue/mutex or a "task notification" - */ - virtual void block() = 0; - - virtual void loop() = 0; - - /** - * The method that will be called when start is called. - */ - virtual void doRun(); -}; - -/** - * A worker thread that waits on a freertos notification - */ -class NotifiedWorkerThread : public WorkerThread -{ - public: - /** - * Notify this thread so it can run - */ - void notify(uint32_t v = 0, eNotifyAction action = eNoAction); - - /** - * Notify from an ISR - * - * This must be inline or IRAM_ATTR on ESP32 - */ - inline void notifyFromISR(BaseType_t *highPriWoken, uint32_t v = 0, eNotifyAction action = eNoAction) - { - xTaskNotifyFromISR(taskHandle, v, action, highPriWoken); - } - - protected: - /** - * The notification that was most recently used to wake the thread. Read from loop() - */ - uint32_t notification = 0; - - /** - * What notification bits should be cleared just after we read and return them in notification? - * - * Defaults to clear all of them. - */ - uint32_t clearOnRead = UINT32_MAX; - - /** - * A method that should block execution - either waiting ona queue/mutex or a "task notification" - */ - virtual void block(); -}; - -#endif \ No newline at end of file diff --git a/src/concurrency/Lock.cpp b/src/concurrency/Lock.cpp new file mode 100644 index 000000000..07f5a2ef5 --- /dev/null +++ b/src/concurrency/Lock.cpp @@ -0,0 +1,23 @@ +#include "Lock.h" +#include + +namespace concurrency { + +Lock::Lock() +{ + handle = xSemaphoreCreateBinary(); + assert(handle); + assert(xSemaphoreGive(handle)); +} + +void Lock::lock() +{ + assert(xSemaphoreTake(handle, portMAX_DELAY)); +} + +void Lock::unlock() +{ + assert(xSemaphoreGive(handle)); +} + +} // namespace concurrency diff --git a/src/lock.h b/src/concurrency/Lock.h similarity index 59% rename from src/lock.h rename to src/concurrency/Lock.h index 6a90c61b1..c52b629c0 100644 --- a/src/lock.h +++ b/src/concurrency/Lock.h @@ -2,8 +2,7 @@ #include "freertosinc.h" -namespace meshtastic -{ +namespace concurrency { // Simple wrapper around FreeRTOS API for implementing a mutex lock. class Lock @@ -25,23 +24,8 @@ class Lock void unlock(); private: -#ifdef configUSE_PREEMPTION SemaphoreHandle_t handle; -#endif + }; -// RAII lock guard. -class LockGuard -{ - public: - LockGuard(Lock *lock); - ~LockGuard(); - - LockGuard(const LockGuard &) = delete; - LockGuard &operator=(const LockGuard &) = delete; - - private: - Lock *lock; -}; - -} // namespace meshtastic +} // namespace concurrency diff --git a/src/concurrency/LockGuard.cpp b/src/concurrency/LockGuard.cpp new file mode 100644 index 000000000..56e8ac877 --- /dev/null +++ b/src/concurrency/LockGuard.cpp @@ -0,0 +1,15 @@ +#include "LockGuard.h" + +namespace concurrency { + +LockGuard::LockGuard(Lock *lock) : lock(lock) +{ + lock->lock(); +} + +LockGuard::~LockGuard() +{ + lock->unlock(); +} + +} // namespace concurrency diff --git a/src/concurrency/LockGuard.h b/src/concurrency/LockGuard.h new file mode 100644 index 000000000..6c35982ad --- /dev/null +++ b/src/concurrency/LockGuard.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Lock.h" + +namespace concurrency { + +// RAII lock guard. +class LockGuard +{ + public: + LockGuard(Lock *lock); + ~LockGuard(); + + LockGuard(const LockGuard &) = delete; + LockGuard &operator=(const LockGuard &) = delete; + + private: + Lock *lock; +}; + +} // namespace concurrency diff --git a/src/concurrency/NotifiedWorkerThread.cpp b/src/concurrency/NotifiedWorkerThread.cpp new file mode 100644 index 000000000..7785ecf8c --- /dev/null +++ b/src/concurrency/NotifiedWorkerThread.cpp @@ -0,0 +1,19 @@ +#include "NotifiedWorkerThread.h" + +namespace concurrency { + +/** + * Notify this thread so it can run + */ +void NotifiedWorkerThread::notify(uint32_t v, eNotifyAction action) +{ + xTaskNotify(taskHandle, v, action); +} + +void NotifiedWorkerThread::block() +{ + xTaskNotifyWait(0, // don't clear notification on entry + clearOnRead, ¬ification, portMAX_DELAY); // Wait forever +} + +} // namespace concurrency diff --git a/src/concurrency/NotifiedWorkerThread.h b/src/concurrency/NotifiedWorkerThread.h new file mode 100644 index 000000000..4fd053269 --- /dev/null +++ b/src/concurrency/NotifiedWorkerThread.h @@ -0,0 +1,47 @@ +#pragma once + +#include "WorkerThread.h" + +namespace concurrency { + +/** + * A worker thread that waits on a freertos notification + */ +class NotifiedWorkerThread : public WorkerThread +{ + public: + /** + * Notify this thread so it can run + */ + void notify(uint32_t v = 0, eNotifyAction action = eNoAction); + + /** + * Notify from an ISR + * + * This must be inline or IRAM_ATTR on ESP32 + */ + inline void notifyFromISR(BaseType_t *highPriWoken, uint32_t v = 0, eNotifyAction action = eNoAction) + { + xTaskNotifyFromISR(taskHandle, v, action, highPriWoken); + } + + protected: + /** + * The notification that was most recently used to wake the thread. Read from loop() + */ + uint32_t notification = 0; + + /** + * What notification bits should be cleared just after we read and return them in notification? + * + * Defaults to clear all of them. + */ + uint32_t clearOnRead = UINT32_MAX; + + /** + * A method that should block execution - either waiting ona queue/mutex or a "task notification" + */ + virtual void block(); +}; + +} // namespace concurrency diff --git a/src/concurrency/Thread.cpp b/src/concurrency/Thread.cpp new file mode 100644 index 000000000..39fd8f6ed --- /dev/null +++ b/src/concurrency/Thread.cpp @@ -0,0 +1,16 @@ +#include "Thread.h" + +namespace concurrency { + +void Thread::start(const char *name, size_t stackSize, uint32_t priority) +{ + auto r = xTaskCreate(callRun, name, stackSize, this, priority, &taskHandle); + assert(r == pdPASS); +} + +void Thread::callRun(void *_this) +{ + ((Thread *)_this)->doRun(); +} + +} // namespace concurrency diff --git a/src/concurrency/Thread.h b/src/concurrency/Thread.h new file mode 100644 index 000000000..e8a710ebf --- /dev/null +++ b/src/concurrency/Thread.h @@ -0,0 +1,34 @@ +#pragma once + +#include "freertosinc.h" + +namespace concurrency { + +class Thread +{ + protected: + TaskHandle_t taskHandle = NULL; + + /** + * set this to true to ask thread to cleanly exit asap + */ + volatile bool wantExit = false; + + public: + void start(const char *name, size_t stackSize = 1024, uint32_t priority = tskIDLE_PRIORITY); + + virtual ~Thread() { vTaskDelete(taskHandle); } + + uint32_t getStackHighwaterMark() { return uxTaskGetStackHighWaterMark(taskHandle); } + + protected: + /** + * The method that will be called when start is called. + */ + virtual void doRun() = 0; + + private: + static void callRun(void *_this); +}; + +} // namespace concurrency diff --git a/src/concurrency/WorkerThread.cpp b/src/concurrency/WorkerThread.cpp new file mode 100644 index 000000000..3287c44f6 --- /dev/null +++ b/src/concurrency/WorkerThread.cpp @@ -0,0 +1,25 @@ +#include "WorkerThread.h" +#include "debug.h" + +namespace concurrency { + +void WorkerThread::doRun() +{ + while (!wantExit) { + block(); + +#ifdef DEBUG_STACK + static uint32_t lastPrint = 0; + if (millis() - lastPrint > 10 * 1000L) { + lastPrint = millis(); + uint32_t taskHandle = reinterpret_cast(xTaskGetCurrentTaskHandle()); + DEBUG_MSG("printThreadInfo(%s) task: %" PRIx32 " core id: %u min free stack: %u\n", "thread", taskHandle, xPortGetCoreID(), + uxTaskGetStackHighWaterMark(nullptr)); + } +#endif + + loop(); + } +} + +} // namespace concurrency diff --git a/src/concurrency/WorkerThread.h b/src/concurrency/WorkerThread.h new file mode 100644 index 000000000..0ae3060a0 --- /dev/null +++ b/src/concurrency/WorkerThread.h @@ -0,0 +1,30 @@ +#pragma once + +#include "Thread.h" + +namespace concurrency { + +/** + * This wraps threading (FreeRTOS for now) with a blocking API intended for efficiently converting onlyschool arduino loop() code. + * + * Use as a mixin base class for the classes you want to convert. + * + * https://www.freertos.org/RTOS_Task_Notification_As_Mailbox.html + */ +class WorkerThread : public Thread +{ + protected: + /** + * A method that should block execution - either waiting ona queue/mutex or a "task notification" + */ + virtual void block() = 0; + + virtual void loop() = 0; + + /** + * The method that will be called when start is called. + */ + virtual void doRun(); +}; + +} // namespace concurrency diff --git a/src/debug.cpp b/src/debug.cpp deleted file mode 100644 index 9d8f19f09..000000000 --- a/src/debug.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "debug.h" - -#include - -#include "freertosinc.h" -#include "configuration.h" - -namespace meshtastic -{ - -void printThreadInfo(const char *extra) -{ -#ifndef NO_ESP32 - uint32_t taskHandle = reinterpret_cast(xTaskGetCurrentTaskHandle()); - DEBUG_MSG("printThreadInfo(%s) task: %" PRIx32 " core id: %u min free stack: %u\n", extra, taskHandle, xPortGetCoreID(), - uxTaskGetStackHighWaterMark(nullptr)); -#endif -} - -} // namespace meshtastic diff --git a/src/debug.h b/src/debug.h deleted file mode 100644 index 74a1875e4..000000000 --- a/src/debug.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace meshtastic -{ - -/// Dumps out which core we are running on, and min level of remaining stack -/// seen. -void printThreadInfo(const char *extra); - -} // namespace meshtastic diff --git a/src/lock.cpp b/src/lock.cpp deleted file mode 100644 index 4a8d28cf5..000000000 --- a/src/lock.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "lock.h" - -#include - -namespace meshtastic -{ - -#ifdef configUSE_PREEMPTION -Lock::Lock() -{ - handle = xSemaphoreCreateBinary(); - assert(handle); - assert(xSemaphoreGive(handle)); -} - -void Lock::lock() -{ - assert(xSemaphoreTake(handle, portMAX_DELAY)); -} - -void Lock::unlock() -{ - assert(xSemaphoreGive(handle)); -} -#else -Lock::Lock() -{ -} - -void Lock::lock() -{ -} - -void Lock::unlock() -{ -} -#endif - - -LockGuard::LockGuard(Lock *lock) : lock(lock) -{ - lock->lock(); -} - -LockGuard::~LockGuard() -{ - lock->unlock(); -} - -} // namespace meshtastic From d5b8038457cc179645cb63cce7c90b915eab2291 Mon Sep 17 00:00:00 2001 From: grcasanova Date: Mon, 6 Jul 2020 00:54:30 +0200 Subject: [PATCH 2/3] fixes --- src/PeriodicTask.cpp | 43 -------------------------- src/concurrency/Lock.h | 4 ++- src/concurrency/LockGuard.h | 4 ++- src/concurrency/NotifiedWorkerThread.h | 2 +- src/{ => concurrency}/Periodic.h | 15 ++++++--- src/concurrency/PeriodicScheduler.cpp | 35 +++++++++++++++++++++ src/concurrency/PeriodicScheduler.h | 40 ++++++++++++++++++++++++ src/concurrency/PeriodicTask.cpp | 16 ++++++++++ src/{ => concurrency}/PeriodicTask.h | 42 ++++--------------------- src/concurrency/Thread.h | 3 ++ src/concurrency/WorkerThread.h | 7 ++--- src/gps/GPS.h | 1 - src/main.cpp | 6 ++-- src/screen.cpp | 4 +-- src/screen.h | 16 +++++----- src/time.h | 11 +++++++ 16 files changed, 144 insertions(+), 105 deletions(-) delete mode 100644 src/PeriodicTask.cpp rename src/{ => concurrency}/Periodic.h (52%) create mode 100644 src/concurrency/PeriodicScheduler.cpp create mode 100644 src/concurrency/PeriodicScheduler.h create mode 100644 src/concurrency/PeriodicTask.cpp rename src/{ => concurrency}/PeriodicTask.h (55%) create mode 100644 src/time.h diff --git a/src/PeriodicTask.cpp b/src/PeriodicTask.cpp deleted file mode 100644 index 5a5d3621c..000000000 --- a/src/PeriodicTask.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "PeriodicTask.h" -#include "Periodic.h" -PeriodicScheduler periodicScheduler; - -PeriodicTask::PeriodicTask(uint32_t initialPeriod) : period(initialPeriod) {} - -void PeriodicTask::setup() -{ - periodicScheduler.schedule(this); -} - -/// call this from loop -void PeriodicScheduler::loop() -{ - meshtastic::LockGuard lg(&lock); - - uint32_t now = millis(); - for (auto t : tasks) { - if (t->period && (now - t->lastMsec) >= t->period) { - - t->doTask(); - t->lastMsec = now; - } - } -} - -void PeriodicScheduler::schedule(PeriodicTask *t) -{ - meshtastic::LockGuard lg(&lock); - tasks.insert(t); -} - -void PeriodicScheduler::unschedule(PeriodicTask *t) -{ - meshtastic::LockGuard lg(&lock); - tasks.erase(t); -} - -void Periodic::doTask() -{ - uint32_t p = callback(); - setPeriod(p); -} diff --git a/src/concurrency/Lock.h b/src/concurrency/Lock.h index c52b629c0..63dce7727 100644 --- a/src/concurrency/Lock.h +++ b/src/concurrency/Lock.h @@ -4,7 +4,9 @@ namespace concurrency { -// Simple wrapper around FreeRTOS API for implementing a mutex lock. +/** + * @brief Simple wrapper around FreeRTOS API for implementing a mutex lock + */ class Lock { public: diff --git a/src/concurrency/LockGuard.h b/src/concurrency/LockGuard.h index 6c35982ad..dc09f40fb 100644 --- a/src/concurrency/LockGuard.h +++ b/src/concurrency/LockGuard.h @@ -4,7 +4,9 @@ namespace concurrency { -// RAII lock guard. +/** + * @brief RAII lock guard + */ class LockGuard { public: diff --git a/src/concurrency/NotifiedWorkerThread.h b/src/concurrency/NotifiedWorkerThread.h index 4fd053269..5ab5a58e7 100644 --- a/src/concurrency/NotifiedWorkerThread.h +++ b/src/concurrency/NotifiedWorkerThread.h @@ -5,7 +5,7 @@ namespace concurrency { /** - * A worker thread that waits on a freertos notification + * @brief A worker thread that waits on a freertos notification */ class NotifiedWorkerThread : public WorkerThread { diff --git a/src/Periodic.h b/src/concurrency/Periodic.h similarity index 52% rename from src/Periodic.h rename to src/concurrency/Periodic.h index c717b5708..e380eb34f 100644 --- a/src/Periodic.h +++ b/src/concurrency/Periodic.h @@ -1,12 +1,12 @@ #pragma once #include "PeriodicTask.h" -#include + +namespace concurrency { /** - * Periodically invoke a callback. - * - * This just provides C style callback conventions rather than a virtual function - FIXME, remove? + * @brief Periodically invoke a callback. This just provides C-style callback conventions + * rather than a virtual function - FIXME, remove? */ class Periodic : public PeriodicTask { @@ -17,5 +17,10 @@ class Periodic : public PeriodicTask Periodic(uint32_t (*_callback)()) : callback(_callback) {} protected: - void doTask(); + void doTask() { + uint32_t p = callback(); + setPeriod(p); + } }; + +} // namespace concurrency diff --git a/src/concurrency/PeriodicScheduler.cpp b/src/concurrency/PeriodicScheduler.cpp new file mode 100644 index 000000000..a6a7518c7 --- /dev/null +++ b/src/concurrency/PeriodicScheduler.cpp @@ -0,0 +1,35 @@ +#include "PeriodicScheduler.h" +#include "PeriodicTask.h" +#include "LockGuard.h" +#include "../time.h" + +namespace concurrency { + +/// call this from loop +void PeriodicScheduler::loop() +{ + LockGuard lg(&lock); + + uint32_t now = time::millis(); + for (auto t : tasks) { + if (t->period && (now - t->lastMsec) >= t->period) { + + t->doTask(); + t->lastMsec = now; + } + } +} + +void PeriodicScheduler::schedule(PeriodicTask *t) +{ + LockGuard lg(&lock); + tasks.insert(t); +} + +void PeriodicScheduler::unschedule(PeriodicTask *t) +{ + LockGuard lg(&lock); + tasks.erase(t); +} + +} // namespace concurrency diff --git a/src/concurrency/PeriodicScheduler.h b/src/concurrency/PeriodicScheduler.h new file mode 100644 index 000000000..943da17cb --- /dev/null +++ b/src/concurrency/PeriodicScheduler.h @@ -0,0 +1,40 @@ +#pragma once + +#include "Lock.h" +#include +#include + +namespace concurrency { + +class PeriodicTask; + +/** + * @brief Runs all PeriodicTasks in the system. Currently called from main loop() + * but eventually should be its own thread blocked on a freertos timer. + */ +class PeriodicScheduler +{ + friend class PeriodicTask; + + /** + * This really should be some form of heap, and when the period gets changed on a task it should get + * rescheduled in that heap. Currently it is just a dumb array and everytime we run loop() we check + * _every_ tasks. If it was a heap we'd only have to check the first task. + */ + std::unordered_set tasks; + + // Protects the above variables. + Lock lock; + + public: + /// Run any next tasks which are due for execution + void loop(); + + private: + void schedule(PeriodicTask *t); + void unschedule(PeriodicTask *t); +}; + +extern PeriodicScheduler periodicScheduler; + +} // namespace concurrency diff --git a/src/concurrency/PeriodicTask.cpp b/src/concurrency/PeriodicTask.cpp new file mode 100644 index 000000000..40c6a4edd --- /dev/null +++ b/src/concurrency/PeriodicTask.cpp @@ -0,0 +1,16 @@ +#include "PeriodicTask.h" +#include "Periodic.h" +#include "LockGuard.h" + +namespace concurrency { + +PeriodicScheduler periodicScheduler; + +PeriodicTask::PeriodicTask(uint32_t initialPeriod) : period(initialPeriod) {} + +void PeriodicTask::setup() +{ + periodicScheduler.schedule(this); +} + +} // namespace concurrency diff --git a/src/PeriodicTask.h b/src/concurrency/PeriodicTask.h similarity index 55% rename from src/PeriodicTask.h rename to src/concurrency/PeriodicTask.h index 951b8cbbb..f5e107ef0 100644 --- a/src/PeriodicTask.h +++ b/src/concurrency/PeriodicTask.h @@ -1,41 +1,9 @@ #pragma once -#include "lock.h" -#include -#include -#include +#include "PeriodicScheduler.h" +#include "../time.h" -class PeriodicTask; - -/** - * Runs all PeriodicTasks in the system. - * - * Currently called from main loop() but eventually should be its own thread blocked on a freertos timer. - */ -class PeriodicScheduler -{ - friend class PeriodicTask; - - /** - * This really should be some form of heap, and when the period gets changed on a task it should get - * rescheduled in that heap. Currently it is just a dumb array and everytime we run loop() we check - * _every_ tasks. If it was a heap we'd only have to check the first task. - */ - std::unordered_set tasks; - - // Protects the above variables. - meshtastic::Lock lock; - - public: - /// Run any next tasks which are due for execution - void loop(); - - private: - void schedule(PeriodicTask *t); - void unschedule(PeriodicTask *t); -}; - -extern PeriodicScheduler periodicScheduler; +namespace concurrency { /** * A base class for tasks that want their doTask() method invoked periodically @@ -69,7 +37,7 @@ class PeriodicTask */ void setPeriod(uint32_t p) { - lastMsec = millis(); // reset starting from now + lastMsec = time::millis(); // reset starting from now period = p; } @@ -83,3 +51,5 @@ class PeriodicTask protected: virtual void doTask() = 0; }; + +} // namespace concurrency diff --git a/src/concurrency/Thread.h b/src/concurrency/Thread.h index e8a710ebf..b297e40d1 100644 --- a/src/concurrency/Thread.h +++ b/src/concurrency/Thread.h @@ -4,6 +4,9 @@ namespace concurrency { +/** + * @brief Base threading + */ class Thread { protected: diff --git a/src/concurrency/WorkerThread.h b/src/concurrency/WorkerThread.h index 0ae3060a0..66111e7d7 100644 --- a/src/concurrency/WorkerThread.h +++ b/src/concurrency/WorkerThread.h @@ -5,11 +5,10 @@ namespace concurrency { /** - * This wraps threading (FreeRTOS for now) with a blocking API intended for efficiently converting onlyschool arduino loop() code. + * @brief This wraps threading (FreeRTOS for now) with a blocking API intended for efficiently converting + * old-school arduino loop() code. Use as a mixin base class for the classes you want to convert. * - * Use as a mixin base class for the classes you want to convert. - * - * https://www.freertos.org/RTOS_Task_Notification_As_Mailbox.html + * @link https://www.freertos.org/RTOS_Task_Notification_As_Mailbox.html */ class WorkerThread : public Thread { diff --git a/src/gps/GPS.h b/src/gps/GPS.h index b2d1916d7..97d696986 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -1,7 +1,6 @@ #pragma once #include "Observer.h" -#include "PeriodicTask.h" #include "sys/time.h" /// If we haven't yet set our RTC this boot, set it from a GPS derived time diff --git a/src/main.cpp b/src/main.cpp index 667c10697..fe306906f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,7 +25,7 @@ #include "MeshService.h" #include "NEMAGPS.h" #include "NodeDB.h" -#include "Periodic.h" +#include "concurrency/Periodic.h" #include "PowerFSM.h" #include "UBloxGPS.h" #include "configuration.h" @@ -124,7 +124,7 @@ static uint32_t ledBlinker() return powerStatus.charging ? 1000 : (ledOn ? 2 : 1000); } -Periodic ledPeriodic(ledBlinker); +concurrency::Periodic ledPeriodic(ledBlinker); // Prepare for button presses #ifdef BUTTON_PIN @@ -316,7 +316,7 @@ uint32_t axpDebugRead() return 30 * 1000; } -Periodic axpDebugOutput(axpDebugRead); +concurrency::Periodic axpDebugOutput(axpDebugRead); axpDebugOutput.setup(); #endif diff --git a/src/screen.cpp b/src/screen.cpp index b98138fc0..6a210beb5 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -529,7 +529,7 @@ void Screen::handleSetOn(bool on) void Screen::setup() { - PeriodicTask::setup(); + concurrency::PeriodicTask::setup(); // We don't set useDisplay until setup() is called, because some boards have a declaration of this object but the device // is never found when probing i2c and therefore we don't call setup and never want to do (invalid) accesses to this device. @@ -746,7 +746,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 char channelStr[20]; { - LockGuard guard(&lock); + concurrency::LockGuard guard(&lock); snprintf(channelStr, sizeof(channelStr), "#%s", channelName.c_str()); // Display power status diff --git a/src/screen.h b/src/screen.h index 6d4d8b373..553995010 100644 --- a/src/screen.h +++ b/src/screen.h @@ -10,9 +10,9 @@ #include #endif -#include "PeriodicTask.h" +#include "concurrency/PeriodicTask.h" #include "TypedQueue.h" -#include "lock.h" +#include "concurrency/Lock.h" #include "power.h" #include @@ -32,7 +32,7 @@ class DebugInfo /// Sets user statistics. void setNodeNumbersStatus(int online, int total) { - LockGuard guard(&lock); + concurrency::LockGuard guard(&lock); nodesOnline = online; nodesTotal = total; } @@ -40,7 +40,7 @@ class DebugInfo /// Sets the name of the channel. void setChannelNameStatus(const char *name) { - LockGuard guard(&lock); + concurrency::LockGuard guard(&lock); channelName = name; } @@ -48,7 +48,7 @@ class DebugInfo // void setPowerStatus(const PowerStatus &status) { - LockGuard guard(&lock); + concurrency::LockGuard guard(&lock); powerStatus = status; } @@ -59,7 +59,7 @@ class DebugInfo // TODO(girts): figure out what the format should be. void setGPSStatus(const char *status) { - LockGuard guard(&lock); + concurrency::LockGuard guard(&lock); gpsStatus = status; } @@ -81,7 +81,7 @@ class DebugInfo std::string gpsStatus; /// Protects all of internal state. - Lock lock; + concurrency::Lock lock; }; /// Deals with showing things on the screen of the device. @@ -91,7 +91,7 @@ class DebugInfo // // This class is thread-safe (as long as drawFrame is not called multiple times // simultaneously). -class Screen : public PeriodicTask +class Screen : public concurrency::PeriodicTask { public: Screen(uint8_t address, int sda = -1, int scl = -1); diff --git a/src/time.h b/src/time.h new file mode 100644 index 000000000..9decfabe8 --- /dev/null +++ b/src/time.h @@ -0,0 +1,11 @@ +#pragma once + +#include "freertos.h" + +namespace time { + + uint32_t millis() { + return xTaskGetTickCount(); + } + +} // namespace time \ No newline at end of file From 92b30ebec6f34764e7e544d0a2d5a2e64380dcc8 Mon Sep 17 00:00:00 2001 From: grcasanova Date: Mon, 6 Jul 2020 10:45:55 +0200 Subject: [PATCH 3/3] fixes now compiles --- .vscode/settings.json | 3 ++- .vscode/tasks.json | 17 +++++++++++++++++ src/PowerFSM.cpp | 5 +++-- src/concurrency/Lock.h | 2 +- src/concurrency/PeriodicScheduler.cpp | 4 ++-- src/concurrency/PeriodicTask.h | 15 ++++++++------- src/concurrency/WorkerThread.cpp | 6 +++--- src/esp32/BluetoothSoftwareUpdate.cpp | 19 ++++++++++--------- src/gps/GPS.cpp | 10 ++++------ src/gps/NEMAGPS.cpp | 3 ++- src/gps/NEMAGPS.h | 2 +- src/gps/UBloxGPS.cpp | 4 ++-- src/gps/UBloxGPS.h | 4 ++-- src/main.cpp | 15 ++++++++------- src/mesh/FloodingRouter.h | 2 +- src/mesh/MeshService.cpp | 7 ++++--- src/mesh/PacketHistory.cpp | 3 ++- src/mesh/PhoneAPI.cpp | 5 +++-- src/mesh/RadioInterface.cpp | 3 ++- src/mesh/RadioInterface.h | 4 ++-- src/mesh/RadioLibInterface.cpp | 2 +- src/mesh/RadioLibInterface.h | 4 ++-- src/mesh/ReliableRouter.cpp | 3 ++- src/mesh/ReliableRouter.h | 5 +++-- src/screen.h | 4 ++-- src/sleep.cpp | 6 +++--- src/time.h | 11 ----------- src/timing.cpp | 10 ++++++++++ src/timing.h | 9 +++++++++ 29 files changed, 111 insertions(+), 76 deletions(-) create mode 100644 .vscode/tasks.json delete mode 100644 src/time.h create mode 100644 src/timing.cpp create mode 100644 src/timing.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 3aca04523..87c760c8c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -61,5 +61,6 @@ "ocrypto", "protobufs", "wifi" - ] + ], + "C_Cpp.dimInactiveRegions": true } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..b2340005e --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,17 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "PlatformIO", + "task": "Build", + "problemMatcher": [ + "$platformio" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "label": "PlatformIO: Build" + } + ] +} \ No newline at end of file diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index aa926abd3..a8ee0275a 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -8,6 +8,7 @@ #include "screen.h" #include "sleep.h" #include "target_specific.h" +#include "timing.h" static void sdsEnter() { @@ -15,7 +16,7 @@ static void sdsEnter() // Don't deepsleep if we have USB power or if the user as pressed a button recently // !isUSBPowered <- doesn't work yet because the axp192 isn't letting the battery fully charge when we are awake - FIXME - if (millis() - lastPressMs > radioConfig.preferences.mesh_sds_timeout_secs) + if (timing::millis() - lastPressMs > radioConfig.preferences.mesh_sds_timeout_secs) { doDeepSleep(radioConfig.preferences.sds_secs); } @@ -130,7 +131,7 @@ static void onEnter() static uint32_t lastPingMs; - uint32_t now = millis(); + uint32_t now = timing::millis(); if (now - lastPingMs > 30 * 1000) { // if more than a minute since our last press, ask other nodes to update their state if (displayedNodeNum) diff --git a/src/concurrency/Lock.h b/src/concurrency/Lock.h index 63dce7727..09877cc25 100644 --- a/src/concurrency/Lock.h +++ b/src/concurrency/Lock.h @@ -1,6 +1,6 @@ #pragma once -#include "freertosinc.h" +#include "../freertosinc.h" namespace concurrency { diff --git a/src/concurrency/PeriodicScheduler.cpp b/src/concurrency/PeriodicScheduler.cpp index a6a7518c7..d2fa77f9c 100644 --- a/src/concurrency/PeriodicScheduler.cpp +++ b/src/concurrency/PeriodicScheduler.cpp @@ -1,7 +1,7 @@ #include "PeriodicScheduler.h" #include "PeriodicTask.h" #include "LockGuard.h" -#include "../time.h" +#include "../timing.h" namespace concurrency { @@ -10,7 +10,7 @@ void PeriodicScheduler::loop() { LockGuard lg(&lock); - uint32_t now = time::millis(); + uint32_t now = timing::millis(); for (auto t : tasks) { if (t->period && (now - t->lastMsec) >= t->period) { diff --git a/src/concurrency/PeriodicTask.h b/src/concurrency/PeriodicTask.h index f5e107ef0..910c0dfde 100644 --- a/src/concurrency/PeriodicTask.h +++ b/src/concurrency/PeriodicTask.h @@ -1,16 +1,16 @@ #pragma once #include "PeriodicScheduler.h" -#include "../time.h" +#include "timing.h" namespace concurrency { /** - * A base class for tasks that want their doTask() method invoked periodically + * @brief A base class for tasks that want their doTask() method invoked periodically * - * FIXME: currently just syntatic sugar for polling in loop (you must call .loop), but eventually - * generalize with the freertos scheduler so we can save lots of power by having everything either in - * something like this or triggered off of an irq. + * @todo currently just syntatic sugar for polling in loop (you must call .loop), but eventually + * generalize with the freertos scheduler so we can save lots of power by having everything either in + * something like this or triggered off of an irq. */ class PeriodicTask { @@ -27,7 +27,8 @@ class PeriodicTask */ PeriodicTask(uint32_t initialPeriod = 1); - /** MUST be be called once at startup (but after threading is running - i.e. not from a constructor) + /** + * MUST be be called once at startup (but after threading is running - i.e. not from a constructor) */ void setup(); @@ -37,7 +38,7 @@ class PeriodicTask */ void setPeriod(uint32_t p) { - lastMsec = time::millis(); // reset starting from now + lastMsec = timing::millis(); // reset starting from now period = p; } diff --git a/src/concurrency/WorkerThread.cpp b/src/concurrency/WorkerThread.cpp index 3287c44f6..8650b7b82 100644 --- a/src/concurrency/WorkerThread.cpp +++ b/src/concurrency/WorkerThread.cpp @@ -1,5 +1,5 @@ #include "WorkerThread.h" -#include "debug.h" +#include "timing.h" namespace concurrency { @@ -10,8 +10,8 @@ void WorkerThread::doRun() #ifdef DEBUG_STACK static uint32_t lastPrint = 0; - if (millis() - lastPrint > 10 * 1000L) { - lastPrint = millis(); + if (timing::millis() - lastPrint > 10 * 1000L) { + lastPrint = timing::millis(); uint32_t taskHandle = reinterpret_cast(xTaskGetCurrentTaskHandle()); DEBUG_MSG("printThreadInfo(%s) task: %" PRIx32 " core id: %u min free stack: %u\n", "thread", taskHandle, xPortGetCoreID(), uxTaskGetStackHighWaterMark(nullptr)); diff --git a/src/esp32/BluetoothSoftwareUpdate.cpp b/src/esp32/BluetoothSoftwareUpdate.cpp index fd4c06155..3b455b56a 100644 --- a/src/esp32/BluetoothSoftwareUpdate.cpp +++ b/src/esp32/BluetoothSoftwareUpdate.cpp @@ -3,21 +3,22 @@ #include "CallbackCharacteristic.h" #include "RadioLibInterface.h" #include "configuration.h" -#include "lock.h" +#include "../concurrency/LockGuard.h" +#include "../timing.h" #include #include #include #include #include -using namespace meshtastic; +//using namespace meshtastic; CRC32 crc; uint32_t rebootAtMsec = 0; // If not zero we will reboot at this time (used to reboot shortly after the update completes) uint32_t updateExpectedSize, updateActualSize; -Lock *updateLock; +concurrency::Lock *updateLock; class TotalSizeCharacteristic : public CallbackCharacteristic { @@ -30,7 +31,7 @@ class TotalSizeCharacteristic : public CallbackCharacteristic void onWrite(BLECharacteristic *c) { - LockGuard g(updateLock); + concurrency::LockGuard g(updateLock); // Check if there is enough to OTA Update uint32_t len = getValue32(c, 0); updateExpectedSize = len; @@ -65,7 +66,7 @@ class DataCharacteristic : public CallbackCharacteristic void onWrite(BLECharacteristic *c) { - LockGuard g(updateLock); + concurrency::LockGuard g(updateLock); std::string value = c->getValue(); uint32_t len = value.length(); assert(len <= MAX_BLOCKSIZE); @@ -89,7 +90,7 @@ class CRC32Characteristic : public CallbackCharacteristic void onWrite(BLECharacteristic *c) { - LockGuard g(updateLock); + concurrency::LockGuard g(updateLock); uint32_t expectedCRC = getValue32(c, 0); uint32_t actualCRC = crc.finalize(); DEBUG_MSG("expected CRC %u\n", expectedCRC); @@ -106,7 +107,7 @@ class CRC32Characteristic : public CallbackCharacteristic } else { if (Update.end()) { DEBUG_MSG("OTA done, rebooting in 5 seconds!\n"); - rebootAtMsec = millis() + 5000; + rebootAtMsec = timing::millis() + 5000; } else { DEBUG_MSG("Error Occurred. Error #: %d\n", Update.getError()); } @@ -124,7 +125,7 @@ class CRC32Characteristic : public CallbackCharacteristic void bluetoothRebootCheck() { - if (rebootAtMsec && millis() > rebootAtMsec) { + if (rebootAtMsec && timing::millis() > rebootAtMsec) { DEBUG_MSG("Rebooting for update\n"); ESP.restart(); } @@ -137,7 +138,7 @@ See bluetooth-api.md BLEService *createUpdateService(BLEServer *server, std::string hwVendor, std::string swVersion, std::string hwVersion) { if (!updateLock) - updateLock = new Lock(); + updateLock = new concurrency::Lock(); // Create the BLE Service BLEService *service = server->createService(BLEUUID("cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30"), 25, 0); diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index bb2d30b54..e4f187c05 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1,9 +1,9 @@ #include "GPS.h" #include "configuration.h" -#include "time.h" +#include "timing.h" #include -#include +#include #ifdef GPS_RX_PIN HardwareSerial _serial_gps_real(GPS_SERIAL_NUM); @@ -27,7 +27,7 @@ void readFromRTC() struct timeval tv; /* btw settimeofday() is helpfull here too*/ if (!gettimeofday(&tv, NULL)) { - uint32_t now = millis(); + uint32_t now = timing::millis(); DEBUG_MSG("Read RTC time as %ld (cur millis %u) valid=%d\n", tv.tv_sec, now, timeSetFromGPS); timeStartMsec = now; @@ -68,11 +68,9 @@ void perhapsSetRTC(struct tm &t) perhapsSetRTC(&tv); } -#include - uint32_t getTime() { - return ((millis() - timeStartMsec) / 1000) + zeroOffsetSecs; + return ((timing::millis() - timeStartMsec) / 1000) + zeroOffsetSecs; } uint32_t getValidTime() diff --git a/src/gps/NEMAGPS.cpp b/src/gps/NEMAGPS.cpp index baba0424f..c4453c910 100644 --- a/src/gps/NEMAGPS.cpp +++ b/src/gps/NEMAGPS.cpp @@ -1,5 +1,6 @@ #include "NEMAGPS.h" #include "configuration.h" +#include "timing.h" static int32_t toDegInt(RawDegrees d) { @@ -19,7 +20,7 @@ void NEMAGPS::loop() reader.encode(c); } - uint32_t now = millis(); + uint32_t now = timing::millis(); if ((now - lastUpdateMsec) > 20 * 1000) { // Ugly hack for now - limit update checks to once every 20 secs (but still consume // serial chars at whatever rate) lastUpdateMsec = now; diff --git a/src/gps/NEMAGPS.h b/src/gps/NEMAGPS.h index 5bea0d41f..2640bcef1 100644 --- a/src/gps/NEMAGPS.h +++ b/src/gps/NEMAGPS.h @@ -2,7 +2,7 @@ #include "GPS.h" #include "Observer.h" -#include "PeriodicTask.h" +#include "../concurrency/PeriodicTask.h" #include "TinyGPS++.h" /** diff --git a/src/gps/UBloxGPS.cpp b/src/gps/UBloxGPS.cpp index 012211299..5ba7da307 100644 --- a/src/gps/UBloxGPS.cpp +++ b/src/gps/UBloxGPS.cpp @@ -2,7 +2,7 @@ #include "sleep.h" #include -UBloxGPS::UBloxGPS() : PeriodicTask() +UBloxGPS::UBloxGPS() : concurrency::PeriodicTask() { notifySleepObserver.observe(¬ifySleep); } @@ -55,7 +55,7 @@ bool UBloxGPS::setup() ok = ublox.saveConfiguration(3000); assert(ok); - PeriodicTask::setup(); // We don't start our periodic task unless we actually found the device + concurrency::PeriodicTask::setup(); // We don't start our periodic task unless we actually found the device return true; } else { diff --git a/src/gps/UBloxGPS.h b/src/gps/UBloxGPS.h index 39b125981..2bbecd61a 100644 --- a/src/gps/UBloxGPS.h +++ b/src/gps/UBloxGPS.h @@ -2,7 +2,7 @@ #include "GPS.h" #include "Observer.h" -#include "PeriodicTask.h" +#include "../concurrency/PeriodicTask.h" #include "SparkFun_Ublox_Arduino_Library.h" /** @@ -10,7 +10,7 @@ * * When new data is available it will notify observers. */ -class UBloxGPS : public GPS, public PeriodicTask +class UBloxGPS : public GPS, public concurrency::PeriodicTask { SFE_UBLOX_GPS ublox; diff --git a/src/main.cpp b/src/main.cpp index fe306906f..8ef075953 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,6 +37,7 @@ #include "main.h" #include "screen.h" #include "sleep.h" +#include "timing.h" #include #include // #include @@ -329,7 +330,7 @@ void loop() powerFSM.run_machine(); service.loop(); - periodicScheduler.loop(); + concurrency::periodicScheduler.loop(); // axpDebugOutput.loop(); #ifdef DEBUG_PORT @@ -351,23 +352,23 @@ void loop() // Show boot screen for first 3 seconds, then switch to normal operation. static bool showingBootScreen = true; - if (showingBootScreen && (millis() > 3000)) { + if (showingBootScreen && (timing::millis() > 3000)) { screen.stopBootScreen(); showingBootScreen = false; } #ifdef DEBUG_STACK static uint32_t lastPrint = 0; - if (millis() - lastPrint > 10 * 1000L) { - lastPrint = millis(); + if (timing::millis() - lastPrint > 10 * 1000L) { + lastPrint = timing::millis(); meshtastic::printThreadInfo("main"); } #endif // Update the screen last, after we've figured out what to show. - screen.debug()->setNodeNumbersStatus(nodeDB.getNumOnlineNodes(), nodeDB.getNumNodes()); - screen.debug()->setChannelNameStatus(channelSettings.name); - screen.debug()->setPowerStatus(powerStatus); + screen.debug_info()->setNodeNumbersStatus(nodeDB.getNumOnlineNodes(), nodeDB.getNumNodes()); + screen.debug_info()->setChannelNameStatus(channelSettings.name); + screen.debug_info()->setPowerStatus(powerStatus); // No GPS lock yet, let the OS put the main CPU in low power mode for 100ms (or until another interrupt comes in) // i.e. don't just keep spinning in loop as fast as we can. diff --git a/src/mesh/FloodingRouter.h b/src/mesh/FloodingRouter.h index 699508d23..b35c3a484 100644 --- a/src/mesh/FloodingRouter.h +++ b/src/mesh/FloodingRouter.h @@ -1,7 +1,7 @@ #pragma once #include "PacketHistory.h" -#include "PeriodicTask.h" +#include "../concurrency/PeriodicTask.h" #include "Router.h" /** diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 70e20f803..21d30bcd0 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -7,12 +7,13 @@ //#include "MeshBluetoothService.h" #include "MeshService.h" #include "NodeDB.h" -#include "Periodic.h" +#include "../concurrency/Periodic.h" #include "PowerFSM.h" #include "main.h" #include "mesh-pb-constants.h" #include "power.h" #include "BluetoothUtil.h" // needed for updateBatteryLevel, FIXME, eventually when we pull mesh out into a lib we shouldn't be whacking bluetooth from here +#include "timing.h" /* receivedPacketQueue - this is a queue of messages we've received from the mesh, which we are keeping to deliver to the phone. @@ -55,7 +56,7 @@ static uint32_t sendOwnerCb() return radioConfig.preferences.send_owner_interval * radioConfig.preferences.position_broadcast_secs * 1000; } -static Periodic sendOwnerPeriod(sendOwnerCb); +static concurrency::Periodic sendOwnerPeriod(sendOwnerCb); MeshService::MeshService() : toPhoneQueue(MAX_RX_TOPHONE) { @@ -308,7 +309,7 @@ int MeshService::onGPSChanged(void *unused) // We limit our GPS broadcasts to a max rate static uint32_t lastGpsSend; - uint32_t now = millis(); + uint32_t now = timing::millis(); if (lastGpsSend == 0 || now - lastGpsSend > radioConfig.preferences.position_broadcast_secs * 1000) { lastGpsSend = now; DEBUG_MSG("Sending position to mesh\n"); diff --git a/src/mesh/PacketHistory.cpp b/src/mesh/PacketHistory.cpp index 3d1884ace..b83fab3c6 100644 --- a/src/mesh/PacketHistory.cpp +++ b/src/mesh/PacketHistory.cpp @@ -1,6 +1,7 @@ #include "PacketHistory.h" #include "configuration.h" #include "mesh-pb-constants.h" +#include "../timing.h" PacketHistory::PacketHistory() { @@ -18,7 +19,7 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate) return false; // Not a floodable message ID, so we don't care } - uint32_t now = millis(); + uint32_t now = timing::millis(); for (size_t i = 0; i < recentPackets.size();) { PacketRecord &r = recentPackets[i]; diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 8d705327b..5e25e9326 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -4,6 +4,7 @@ #include "PowerFSM.h" #include "RadioInterface.h" #include "GPS.h" +#include "timing.h" #include PhoneAPI::PhoneAPI() @@ -20,7 +21,7 @@ void PhoneAPI::init() void PhoneAPI::checkConnectionTimeout() { if (isConnected) { - bool newConnected = (millis() - lastContactMsec < radioConfig.preferences.phone_timeout_secs * 1000L); + bool newConnected = (timing::millis() - lastContactMsec < radioConfig.preferences.phone_timeout_secs * 1000L); if (!newConnected) { isConnected = false; onConnectionChanged(isConnected); @@ -34,7 +35,7 @@ void PhoneAPI::checkConnectionTimeout() void PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) { powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); // As long as the phone keeps talking to us, don't let the radio go to sleep - lastContactMsec = millis(); + lastContactMsec = timing::millis(); if (!isConnected) { isConnected = true; onConnectionChanged(isConnected); diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 4307b0a7d..ad255d621 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -6,6 +6,7 @@ #include "assert.h" #include "configuration.h" #include "sleep.h" +#include "timing.h" #include #include #include @@ -155,7 +156,7 @@ size_t RadioInterface::beginSending(MeshPacket *p) // DEBUG_MSG("sending queued packet on mesh (txGood=%d,rxGood=%d,rxBad=%d)\n", rf95.txGood(), rf95.rxGood(), rf95.rxBad()); assert(p->which_payload == MeshPacket_encrypted_tag); // It should have already been encoded by now - lastTxStart = millis(); + lastTxStart = timing::millis(); PacketHeader *h = (PacketHeader *)radiobuf; diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index 988034dbb..47838a7ea 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -4,7 +4,7 @@ #include "MeshTypes.h" #include "Observer.h" #include "PointerQueue.h" -#include "WorkerThread.h" +#include "../concurrency/NotifiedWorkerThread.h" #include "mesh.pb.h" #define MAX_TX_QUEUE 16 // max number of packets which can be waiting for transmission @@ -43,7 +43,7 @@ typedef enum { * * This defines the SOLE API for talking to radios (because soon we will have alternate radio implementations) */ -class RadioInterface : protected NotifiedWorkerThread +class RadioInterface : protected concurrency::NotifiedWorkerThread { friend class MeshRadio; // for debugging we let that class touch pool PointerQueue *rxDest = NULL; diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index f0451079e..4551edd2e 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -10,7 +10,7 @@ static SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0); RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi, PhysicalLayer *_iface) - : PeriodicTask(0), module(cs, irq, rst, busy, spi, spiSettings), iface(_iface) + : concurrency::PeriodicTask(0), module(cs, irq, rst, busy, spi, spiSettings), iface(_iface) { assert(!instance); // We assume only one for now instance = this; diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index cb6991d43..a19c47412 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -1,6 +1,6 @@ #pragma once -#include "PeriodicTask.h" +#include "../concurrency/PeriodicTask.h" #include "RadioInterface.h" #ifdef CubeCell_BoardPlus @@ -16,7 +16,7 @@ #define INTERRUPT_ATTR #endif -class RadioLibInterface : public RadioInterface, private PeriodicTask +class RadioLibInterface : public RadioInterface, private concurrency::PeriodicTask { /// Used as our notification from the ISR enum PendingISR { ISR_NONE = 0, ISR_RX, ISR_TX, TRANSMIT_DELAY_COMPLETED }; diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp index acec6b7f9..174c184a0 100644 --- a/src/mesh/ReliableRouter.cpp +++ b/src/mesh/ReliableRouter.cpp @@ -2,6 +2,7 @@ #include "MeshTypes.h" #include "configuration.h" #include "mesh-pb-constants.h" +#include "timing.h" // ReliableRouter::ReliableRouter() {} @@ -162,7 +163,7 @@ PendingPacket *ReliableRouter::startRetransmission(MeshPacket *p) */ void ReliableRouter::doRetransmissions() { - uint32_t now = millis(); + uint32_t now = timing::millis(); // FIXME, we should use a better datastructure rather than walking through this map. // for(auto el: pending) { diff --git a/src/mesh/ReliableRouter.h b/src/mesh/ReliableRouter.h index beb58a8ed..04974febb 100644 --- a/src/mesh/ReliableRouter.h +++ b/src/mesh/ReliableRouter.h @@ -1,7 +1,8 @@ #pragma once #include "FloodingRouter.h" -#include "PeriodicTask.h" +#include "../concurrency/PeriodicTask.h" +#include "../timing.h" #include /** @@ -48,7 +49,7 @@ struct PendingPacket { PendingPacket() {} PendingPacket(MeshPacket *p); - void setNextTx() { nextTxMsec = millis() + random(20 * 1000L, 22 * 1000L); } + void setNextTx() { nextTxMsec = timing::millis() + random(20 * 1000L, 22 * 1000L); } }; class GlobalPacketIdHashFunction diff --git a/src/screen.h b/src/screen.h index 553995010..fe09d68f0 100644 --- a/src/screen.h +++ b/src/screen.h @@ -12,7 +12,7 @@ #include "concurrency/PeriodicTask.h" #include "TypedQueue.h" -#include "concurrency/Lock.h" +#include "concurrency/LockGuard.h" #include "power.h" #include @@ -187,7 +187,7 @@ class Screen : public concurrency::PeriodicTask /// Returns a handle to the DebugInfo screen. // // Use this handle to set things like battery status, user count, GPS status, etc. - DebugInfo *debug() { return &debugInfo; } + DebugInfo* debug_info() { return &debugInfo; } protected: /// Updates the UI. diff --git a/src/sleep.cpp b/src/sleep.cpp index 2d3ad4d31..59106494c 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -5,7 +5,7 @@ #include "NodeDB.h" #include "configuration.h" #include "error.h" - +#include "timing.h" #include "main.h" #include "target_specific.h" @@ -123,11 +123,11 @@ bool doPreflightSleep() /// Tell devices we are going to sleep and wait for them to handle things static void waitEnterSleep() { - uint32_t now = millis(); + uint32_t now = timing::millis(); while (!doPreflightSleep()) { delay(100); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives) - if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep + if (timing::millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep recordCriticalError(ErrSleepEnterWait); assert(0); // FIXME - for now we just restart, need to fix bug #167 break; diff --git a/src/time.h b/src/time.h deleted file mode 100644 index 9decfabe8..000000000 --- a/src/time.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "freertos.h" - -namespace time { - - uint32_t millis() { - return xTaskGetTickCount(); - } - -} // namespace time \ No newline at end of file diff --git a/src/timing.cpp b/src/timing.cpp new file mode 100644 index 000000000..f7cffaa65 --- /dev/null +++ b/src/timing.cpp @@ -0,0 +1,10 @@ +#include "timing.h" +#include "freertosinc.h" + +namespace timing { + + uint32_t millis() { + return xTaskGetTickCount(); + } + +} // namespace timing diff --git a/src/timing.h b/src/timing.h new file mode 100644 index 000000000..7f741d45f --- /dev/null +++ b/src/timing.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace timing { + + uint32_t millis(); + +} // namespace timing \ No newline at end of file