mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-27 04:02:05 +00:00
add a .clang-format file (#9154)
This commit is contained in:
@@ -4,35 +4,21 @@
|
||||
|
||||
#ifdef HAS_FREE_RTOS
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
BinarySemaphoreFreeRTOS::BinarySemaphoreFreeRTOS() : semaphore(xSemaphoreCreateBinary())
|
||||
{
|
||||
assert(semaphore);
|
||||
}
|
||||
BinarySemaphoreFreeRTOS::BinarySemaphoreFreeRTOS() : semaphore(xSemaphoreCreateBinary()) { assert(semaphore); }
|
||||
|
||||
BinarySemaphoreFreeRTOS::~BinarySemaphoreFreeRTOS()
|
||||
{
|
||||
vSemaphoreDelete(semaphore);
|
||||
}
|
||||
BinarySemaphoreFreeRTOS::~BinarySemaphoreFreeRTOS() { vSemaphoreDelete(semaphore); }
|
||||
|
||||
/**
|
||||
* Returns false if we were interrupted
|
||||
*/
|
||||
bool BinarySemaphoreFreeRTOS::take(uint32_t msec)
|
||||
{
|
||||
return xSemaphoreTake(semaphore, pdMS_TO_TICKS(msec));
|
||||
}
|
||||
bool BinarySemaphoreFreeRTOS::take(uint32_t msec) { return xSemaphoreTake(semaphore, pdMS_TO_TICKS(msec)); }
|
||||
|
||||
void BinarySemaphoreFreeRTOS::give()
|
||||
{
|
||||
xSemaphoreGive(semaphore);
|
||||
}
|
||||
void BinarySemaphoreFreeRTOS::give() { xSemaphoreGive(semaphore); }
|
||||
|
||||
IRAM_ATTR void BinarySemaphoreFreeRTOS::giveFromISR(BaseType_t *pxHigherPriorityTaskWoken)
|
||||
{
|
||||
xSemaphoreGiveFromISR(semaphore, pxHigherPriorityTaskWoken);
|
||||
IRAM_ATTR void BinarySemaphoreFreeRTOS::giveFromISR(BaseType_t *pxHigherPriorityTaskWoken) {
|
||||
xSemaphoreGiveFromISR(semaphore, pxHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
} // namespace concurrency
|
||||
|
||||
@@ -2,27 +2,25 @@
|
||||
|
||||
#include "../freertosinc.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
#ifdef HAS_FREE_RTOS
|
||||
|
||||
class BinarySemaphoreFreeRTOS
|
||||
{
|
||||
SemaphoreHandle_t semaphore;
|
||||
class BinarySemaphoreFreeRTOS {
|
||||
SemaphoreHandle_t semaphore;
|
||||
|
||||
public:
|
||||
BinarySemaphoreFreeRTOS();
|
||||
~BinarySemaphoreFreeRTOS();
|
||||
public:
|
||||
BinarySemaphoreFreeRTOS();
|
||||
~BinarySemaphoreFreeRTOS();
|
||||
|
||||
/**
|
||||
* Returns false if we timed out
|
||||
*/
|
||||
bool take(uint32_t msec);
|
||||
/**
|
||||
* Returns false if we timed out
|
||||
*/
|
||||
bool take(uint32_t msec);
|
||||
|
||||
void give();
|
||||
void give();
|
||||
|
||||
void giveFromISR(BaseType_t *pxHigherPriorityTaskWoken);
|
||||
void giveFromISR(BaseType_t *pxHigherPriorityTaskWoken);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
#ifndef HAS_FREE_RTOS
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
BinarySemaphorePosix::BinarySemaphorePosix() {}
|
||||
|
||||
@@ -13,10 +12,9 @@ BinarySemaphorePosix::~BinarySemaphorePosix() {}
|
||||
/**
|
||||
* Returns false if we timed out
|
||||
*/
|
||||
bool BinarySemaphorePosix::take(uint32_t msec)
|
||||
{
|
||||
delay(msec); // FIXME
|
||||
return false;
|
||||
bool BinarySemaphorePosix::take(uint32_t msec) {
|
||||
delay(msec); // FIXME
|
||||
return false;
|
||||
}
|
||||
|
||||
void BinarySemaphorePosix::give() {}
|
||||
|
||||
@@ -2,27 +2,25 @@
|
||||
|
||||
#include "../freertosinc.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
#ifndef HAS_FREE_RTOS
|
||||
|
||||
class BinarySemaphorePosix
|
||||
{
|
||||
// SemaphoreHandle_t semaphore;
|
||||
class BinarySemaphorePosix {
|
||||
// SemaphoreHandle_t semaphore;
|
||||
|
||||
public:
|
||||
BinarySemaphorePosix();
|
||||
~BinarySemaphorePosix();
|
||||
public:
|
||||
BinarySemaphorePosix();
|
||||
~BinarySemaphorePosix();
|
||||
|
||||
/**
|
||||
* Returns false if we timed out
|
||||
*/
|
||||
bool take(uint32_t msec);
|
||||
/**
|
||||
* Returns false if we timed out
|
||||
*/
|
||||
bool take(uint32_t msec);
|
||||
|
||||
void give();
|
||||
void give();
|
||||
|
||||
void giveFromISR(BaseType_t *pxHigherPriorityTaskWoken);
|
||||
void giveFromISR(BaseType_t *pxHigherPriorityTaskWoken);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "concurrency/InterruptableDelay.h"
|
||||
#include "configuration.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
InterruptableDelay::InterruptableDelay() {}
|
||||
|
||||
@@ -11,25 +10,18 @@ InterruptableDelay::~InterruptableDelay() {}
|
||||
/**
|
||||
* Returns false if we were interrupted
|
||||
*/
|
||||
bool InterruptableDelay::delay(uint32_t msec)
|
||||
{
|
||||
// LOG_DEBUG("delay %u ", msec);
|
||||
bool InterruptableDelay::delay(uint32_t msec) {
|
||||
// LOG_DEBUG("delay %u ", msec);
|
||||
|
||||
// sem take will return false if we timed out (i.e. were not interrupted)
|
||||
bool r = semaphore.take(msec);
|
||||
// sem take will return false if we timed out (i.e. were not interrupted)
|
||||
bool r = semaphore.take(msec);
|
||||
|
||||
// LOG_DEBUG("interrupt=%d", r);
|
||||
return !r;
|
||||
// LOG_DEBUG("interrupt=%d", r);
|
||||
return !r;
|
||||
}
|
||||
|
||||
void InterruptableDelay::interrupt()
|
||||
{
|
||||
semaphore.give();
|
||||
}
|
||||
void InterruptableDelay::interrupt() { semaphore.give(); }
|
||||
|
||||
IRAM_ATTR void InterruptableDelay::interruptFromISR(BaseType_t *pxHigherPriorityTaskWoken)
|
||||
{
|
||||
semaphore.giveFromISR(pxHigherPriorityTaskWoken);
|
||||
}
|
||||
IRAM_ATTR void InterruptableDelay::interruptFromISR(BaseType_t *pxHigherPriorityTaskWoken) { semaphore.giveFromISR(pxHigherPriorityTaskWoken); }
|
||||
|
||||
} // namespace concurrency
|
||||
@@ -10,32 +10,31 @@
|
||||
#define BinarySemaphore BinarySemaphorePosix
|
||||
#endif
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* An object that provides delay(msec) like functionality, but can be interrupted by calling interrupt().
|
||||
*
|
||||
* Useful for they top level loop() delay call to keep the CPU powered down until our next scheduled event or some external event.
|
||||
* Useful for they top level loop() delay call to keep the CPU powered down until our next scheduled event or some
|
||||
* external event.
|
||||
*
|
||||
* This is implemented for FreeRTOS but should be easy to port to other operating systems.
|
||||
*/
|
||||
class InterruptableDelay
|
||||
{
|
||||
BinarySemaphore semaphore;
|
||||
class InterruptableDelay {
|
||||
BinarySemaphore semaphore;
|
||||
|
||||
public:
|
||||
InterruptableDelay();
|
||||
~InterruptableDelay();
|
||||
public:
|
||||
InterruptableDelay();
|
||||
~InterruptableDelay();
|
||||
|
||||
/**
|
||||
* Returns false if we were interrupted
|
||||
*/
|
||||
bool delay(uint32_t msec);
|
||||
/**
|
||||
* Returns false if we were interrupted
|
||||
*/
|
||||
bool delay(uint32_t msec);
|
||||
|
||||
void interrupt();
|
||||
void interrupt();
|
||||
|
||||
void interruptFromISR(BaseType_t *pxHigherPriorityTaskWoken);
|
||||
void interruptFromISR(BaseType_t *pxHigherPriorityTaskWoken);
|
||||
};
|
||||
|
||||
} // namespace concurrency
|
||||
@@ -2,30 +2,26 @@
|
||||
#include "configuration.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
#ifdef HAS_FREE_RTOS
|
||||
Lock::Lock() : handle(xSemaphoreCreateBinary())
|
||||
{
|
||||
assert(handle);
|
||||
if (xSemaphoreGive(handle) == false) {
|
||||
abort();
|
||||
}
|
||||
Lock::Lock() : handle(xSemaphoreCreateBinary()) {
|
||||
assert(handle);
|
||||
if (xSemaphoreGive(handle) == false) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void Lock::lock()
|
||||
{
|
||||
if (xSemaphoreTake(handle, portMAX_DELAY) == false) {
|
||||
abort();
|
||||
}
|
||||
void Lock::lock() {
|
||||
if (xSemaphoreTake(handle, portMAX_DELAY) == false) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void Lock::unlock()
|
||||
{
|
||||
if (xSemaphoreGive(handle) == false) {
|
||||
abort();
|
||||
}
|
||||
void Lock::unlock() {
|
||||
if (xSemaphoreGive(handle) == false) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#else
|
||||
Lock::Lock() {}
|
||||
|
||||
@@ -2,33 +2,31 @@
|
||||
|
||||
#include "../freertosinc.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* @brief Simple wrapper around FreeRTOS API for implementing a mutex lock
|
||||
*/
|
||||
class Lock
|
||||
{
|
||||
public:
|
||||
Lock();
|
||||
class Lock {
|
||||
public:
|
||||
Lock();
|
||||
|
||||
Lock(const Lock &) = delete;
|
||||
Lock &operator=(const Lock &) = delete;
|
||||
Lock(const Lock &) = delete;
|
||||
Lock &operator=(const Lock &) = delete;
|
||||
|
||||
/// Locks the lock.
|
||||
//
|
||||
// Must not be called from an ISR.
|
||||
void lock();
|
||||
/// Locks the lock.
|
||||
//
|
||||
// Must not be called from an ISR.
|
||||
void lock();
|
||||
|
||||
// Unlocks the lock.
|
||||
//
|
||||
// Must not be called from an ISR.
|
||||
void unlock();
|
||||
// Unlocks the lock.
|
||||
//
|
||||
// Must not be called from an ISR.
|
||||
void unlock();
|
||||
|
||||
private:
|
||||
private:
|
||||
#ifdef HAS_FREE_RTOS
|
||||
SemaphoreHandle_t handle;
|
||||
SemaphoreHandle_t handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
#include "LockGuard.h"
|
||||
#include "configuration.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
LockGuard::LockGuard(Lock *lock) : lock(lock)
|
||||
{
|
||||
lock->lock();
|
||||
}
|
||||
LockGuard::LockGuard(Lock *lock) : lock(lock) { lock->lock(); }
|
||||
|
||||
LockGuard::~LockGuard()
|
||||
{
|
||||
lock->unlock();
|
||||
}
|
||||
LockGuard::~LockGuard() { lock->unlock(); }
|
||||
|
||||
} // namespace concurrency
|
||||
|
||||
@@ -2,23 +2,21 @@
|
||||
|
||||
#include "Lock.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* @brief RAII lock guard
|
||||
*/
|
||||
class LockGuard
|
||||
{
|
||||
public:
|
||||
explicit LockGuard(Lock *lock);
|
||||
~LockGuard();
|
||||
class LockGuard {
|
||||
public:
|
||||
explicit LockGuard(Lock *lock);
|
||||
~LockGuard();
|
||||
|
||||
LockGuard(const LockGuard &) = delete;
|
||||
LockGuard &operator=(const LockGuard &) = delete;
|
||||
LockGuard(const LockGuard &) = delete;
|
||||
LockGuard &operator=(const LockGuard &) = delete;
|
||||
|
||||
private:
|
||||
Lock *lock;
|
||||
private:
|
||||
Lock *lock;
|
||||
};
|
||||
|
||||
} // namespace concurrency
|
||||
|
||||
@@ -2,45 +2,42 @@
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
static bool debugNotification;
|
||||
|
||||
/**
|
||||
* Notify this thread so it can run
|
||||
*/
|
||||
bool NotifiedWorkerThread::notify(uint32_t v, bool overwrite)
|
||||
{
|
||||
bool r = notifyCommon(v, overwrite);
|
||||
bool NotifiedWorkerThread::notify(uint32_t v, bool overwrite) {
|
||||
bool r = notifyCommon(v, overwrite);
|
||||
|
||||
if (r)
|
||||
mainDelay.interrupt();
|
||||
if (r)
|
||||
mainDelay.interrupt();
|
||||
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify this thread so it can run
|
||||
*/
|
||||
IRAM_ATTR bool NotifiedWorkerThread::notifyCommon(uint32_t v, bool overwrite)
|
||||
{
|
||||
if (overwrite || notification == 0) {
|
||||
enabled = true;
|
||||
setInterval(0); // Run ASAP
|
||||
runASAP = true;
|
||||
IRAM_ATTR bool NotifiedWorkerThread::notifyCommon(uint32_t v, bool overwrite) {
|
||||
if (overwrite || notification == 0) {
|
||||
enabled = true;
|
||||
setInterval(0); // Run ASAP
|
||||
runASAP = true;
|
||||
|
||||
notification = v;
|
||||
if (debugNotification) {
|
||||
LOG_DEBUG("Set notification %d", v);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (debugNotification) {
|
||||
LOG_DEBUG("Drop notification %d", v);
|
||||
}
|
||||
return false;
|
||||
notification = v;
|
||||
if (debugNotification) {
|
||||
LOG_DEBUG("Set notification %d", v);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (debugNotification) {
|
||||
LOG_DEBUG("Drop notification %d", v);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,47 +45,43 @@ IRAM_ATTR bool NotifiedWorkerThread::notifyCommon(uint32_t v, bool overwrite)
|
||||
*
|
||||
* This must be inline or IRAM_ATTR on ESP32
|
||||
*/
|
||||
IRAM_ATTR bool NotifiedWorkerThread::notifyFromISR(BaseType_t *highPriWoken, uint32_t v, bool overwrite)
|
||||
{
|
||||
bool r = notifyCommon(v, overwrite);
|
||||
if (r)
|
||||
mainDelay.interruptFromISR(highPriWoken);
|
||||
IRAM_ATTR bool NotifiedWorkerThread::notifyFromISR(BaseType_t *highPriWoken, uint32_t v, bool overwrite) {
|
||||
bool r = notifyCommon(v, overwrite);
|
||||
if (r)
|
||||
mainDelay.interruptFromISR(highPriWoken);
|
||||
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a notification to fire in delay msecs
|
||||
*/
|
||||
bool NotifiedWorkerThread::notifyLater(uint32_t delay, uint32_t v, bool overwrite)
|
||||
{
|
||||
bool didIt = notify(v, overwrite);
|
||||
bool NotifiedWorkerThread::notifyLater(uint32_t delay, uint32_t v, bool overwrite) {
|
||||
bool didIt = notify(v, overwrite);
|
||||
|
||||
if (didIt) { // If we didn't already have something queued, override the delay to be larger
|
||||
setIntervalFromNow(delay); // a new version of setInterval relative to the current time
|
||||
if (debugNotification) {
|
||||
LOG_DEBUG("Delay notification %u", delay);
|
||||
}
|
||||
if (didIt) { // If we didn't already have something queued, override the delay to be larger
|
||||
setIntervalFromNow(delay); // a new version of setInterval relative to the current time
|
||||
if (debugNotification) {
|
||||
LOG_DEBUG("Delay notification %u", delay);
|
||||
}
|
||||
}
|
||||
|
||||
return didIt;
|
||||
return didIt;
|
||||
}
|
||||
|
||||
void NotifiedWorkerThread::checkNotification()
|
||||
{
|
||||
auto n = notification;
|
||||
notification = 0; // clear notification
|
||||
if (n) {
|
||||
onNotify(n);
|
||||
}
|
||||
void NotifiedWorkerThread::checkNotification() {
|
||||
auto n = notification;
|
||||
notification = 0; // clear notification
|
||||
if (n) {
|
||||
onNotify(n);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t NotifiedWorkerThread::runOnce()
|
||||
{
|
||||
enabled = false; // Only run once per notification
|
||||
checkNotification();
|
||||
int32_t NotifiedWorkerThread::runOnce() {
|
||||
enabled = false; // Only run once per notification
|
||||
checkNotification();
|
||||
|
||||
return RUN_SAME;
|
||||
return RUN_SAME;
|
||||
}
|
||||
|
||||
} // namespace concurrency
|
||||
@@ -2,55 +2,53 @@
|
||||
|
||||
#include "OSThread.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* @brief A worker thread that waits on a freertos notification
|
||||
*/
|
||||
class NotifiedWorkerThread : public OSThread
|
||||
{
|
||||
/**
|
||||
* The notification that was most recently used to wake the thread. Read from runOnce()
|
||||
*/
|
||||
uint32_t notification = 0;
|
||||
class NotifiedWorkerThread : public OSThread {
|
||||
/**
|
||||
* The notification that was most recently used to wake the thread. Read from runOnce()
|
||||
*/
|
||||
uint32_t notification = 0;
|
||||
|
||||
public:
|
||||
NotifiedWorkerThread(const char *name) : OSThread(name) {}
|
||||
public:
|
||||
NotifiedWorkerThread(const char *name) : OSThread(name) {}
|
||||
|
||||
/**
|
||||
* Notify this thread so it can run
|
||||
*/
|
||||
bool notify(uint32_t v, bool overwrite);
|
||||
/**
|
||||
* Notify this thread so it can run
|
||||
*/
|
||||
bool notify(uint32_t v, bool overwrite);
|
||||
|
||||
/**
|
||||
* Notify from an ISR
|
||||
*
|
||||
* This must be inline or IRAM_ATTR on ESP32
|
||||
*/
|
||||
bool notifyFromISR(BaseType_t *highPriWoken, uint32_t v, bool overwrite);
|
||||
/**
|
||||
* Notify from an ISR
|
||||
*
|
||||
* This must be inline or IRAM_ATTR on ESP32
|
||||
*/
|
||||
bool notifyFromISR(BaseType_t *highPriWoken, uint32_t v, bool overwrite);
|
||||
|
||||
/**
|
||||
* Schedule a notification to fire in delay msecs
|
||||
*/
|
||||
bool notifyLater(uint32_t delay, uint32_t v, bool overwrite);
|
||||
/**
|
||||
* Schedule a notification to fire in delay msecs
|
||||
*/
|
||||
bool notifyLater(uint32_t delay, uint32_t v, bool overwrite);
|
||||
|
||||
protected:
|
||||
virtual void onNotify(uint32_t notification) = 0;
|
||||
protected:
|
||||
virtual void onNotify(uint32_t notification) = 0;
|
||||
|
||||
/// just calls checkNotification()
|
||||
virtual int32_t runOnce() override;
|
||||
/// just calls checkNotification()
|
||||
virtual int32_t runOnce() override;
|
||||
|
||||
/// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about
|
||||
/// to change radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if
|
||||
/// any notifications are currently pending they will be handled immediately.
|
||||
void checkNotification();
|
||||
/// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we
|
||||
/// are about to change radio transmit/receive modes we want to handle any pending interrupts first). You can call
|
||||
/// this method and if any notifications are currently pending they will be handled immediately.
|
||||
void checkNotification();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Notify this thread so it can run
|
||||
*/
|
||||
bool notifyCommon(uint32_t v, bool overwrite);
|
||||
private:
|
||||
/**
|
||||
* Notify this thread so it can run
|
||||
*/
|
||||
bool notifyCommon(uint32_t v, bool overwrite);
|
||||
};
|
||||
|
||||
} // namespace concurrency
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include "memGet.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
/// Show debugging info for disabled threads
|
||||
bool OSThread::showDisabled;
|
||||
@@ -20,93 +19,85 @@ const OSThread *OSThread::currentThread;
|
||||
ThreadController mainController, timerController;
|
||||
InterruptableDelay mainDelay;
|
||||
|
||||
void OSThread::setup()
|
||||
{
|
||||
mainController.ThreadName = "mainController";
|
||||
timerController.ThreadName = "timerController";
|
||||
void OSThread::setup() {
|
||||
mainController.ThreadName = "mainController";
|
||||
timerController.ThreadName = "timerController";
|
||||
}
|
||||
|
||||
OSThread::OSThread(const char *_name, uint32_t period, ThreadController *_controller)
|
||||
: Thread(NULL, period), controller(_controller)
|
||||
{
|
||||
assertIsSetup();
|
||||
OSThread::OSThread(const char *_name, uint32_t period, ThreadController *_controller) : Thread(NULL, period), controller(_controller) {
|
||||
assertIsSetup();
|
||||
|
||||
ThreadName = _name;
|
||||
ThreadName = _name;
|
||||
|
||||
if (controller) {
|
||||
bool added = controller->add(this);
|
||||
assert(added);
|
||||
}
|
||||
if (controller) {
|
||||
bool added = controller->add(this);
|
||||
assert(added);
|
||||
}
|
||||
}
|
||||
|
||||
OSThread::~OSThread()
|
||||
{
|
||||
if (controller)
|
||||
controller->remove(this);
|
||||
OSThread::~OSThread() {
|
||||
if (controller)
|
||||
controller->remove(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait a specified number msecs starting from the current time (rather than the last time we were run)
|
||||
*/
|
||||
void OSThread::setIntervalFromNow(unsigned long _interval)
|
||||
{
|
||||
// Save interval
|
||||
interval = _interval;
|
||||
void OSThread::setIntervalFromNow(unsigned long _interval) {
|
||||
// Save interval
|
||||
interval = _interval;
|
||||
|
||||
// Cache the next run based on the last_run
|
||||
_cached_next_run = millis() + interval;
|
||||
// Cache the next run based on the last_run
|
||||
_cached_next_run = millis() + interval;
|
||||
}
|
||||
|
||||
bool OSThread::shouldRun(unsigned long time)
|
||||
{
|
||||
bool r = Thread::shouldRun(time);
|
||||
bool OSThread::shouldRun(unsigned long time) {
|
||||
bool r = Thread::shouldRun(time);
|
||||
|
||||
if (showRun && r) {
|
||||
LOG_DEBUG("Thread %s: run", ThreadName.c_str());
|
||||
}
|
||||
if (showRun && r) {
|
||||
LOG_DEBUG("Thread %s: run", ThreadName.c_str());
|
||||
}
|
||||
|
||||
if (showWaiting && enabled && !r) {
|
||||
LOG_DEBUG("Thread %s: wait %lu", ThreadName.c_str(), interval);
|
||||
}
|
||||
if (showWaiting && enabled && !r) {
|
||||
LOG_DEBUG("Thread %s: wait %lu", ThreadName.c_str(), interval);
|
||||
}
|
||||
|
||||
if (showDisabled && !enabled) {
|
||||
LOG_DEBUG("Thread %s: disabled", ThreadName.c_str());
|
||||
}
|
||||
if (showDisabled && !enabled) {
|
||||
LOG_DEBUG("Thread %s: disabled", ThreadName.c_str());
|
||||
}
|
||||
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
void OSThread::run()
|
||||
{
|
||||
void OSThread::run() {
|
||||
#ifdef DEBUG_HEAP
|
||||
auto heap = memGet.getFreeHeap();
|
||||
auto heap = memGet.getFreeHeap();
|
||||
#endif
|
||||
currentThread = this;
|
||||
auto newDelay = runOnce();
|
||||
currentThread = this;
|
||||
auto newDelay = runOnce();
|
||||
#ifdef DEBUG_HEAP
|
||||
auto newHeap = memGet.getFreeHeap();
|
||||
if (newHeap < heap)
|
||||
LOG_HEAP("------ Thread %s leaked heap %d -> %d (%d) ------", ThreadName.c_str(), heap, newHeap, newHeap - heap);
|
||||
if (heap < newHeap)
|
||||
LOG_HEAP("++++++ Thread %s freed heap %d -> %d (%d) ++++++", ThreadName.c_str(), heap, newHeap, newHeap - heap);
|
||||
auto newHeap = memGet.getFreeHeap();
|
||||
if (newHeap < heap)
|
||||
LOG_HEAP("------ Thread %s leaked heap %d -> %d (%d) ------", ThreadName.c_str(), heap, newHeap, newHeap - heap);
|
||||
if (heap < newHeap)
|
||||
LOG_HEAP("++++++ Thread %s freed heap %d -> %d (%d) ++++++", ThreadName.c_str(), heap, newHeap, newHeap - heap);
|
||||
#endif
|
||||
#ifdef DEBUG_LOOP_TIMING
|
||||
LOG_DEBUG("====== Thread next run in: %d", newDelay);
|
||||
LOG_DEBUG("====== Thread next run in: %d", newDelay);
|
||||
#endif
|
||||
runned();
|
||||
runned();
|
||||
|
||||
if (newDelay >= 0)
|
||||
setInterval(newDelay);
|
||||
if (newDelay >= 0)
|
||||
setInterval(newDelay);
|
||||
|
||||
currentThread = NULL;
|
||||
currentThread = NULL;
|
||||
}
|
||||
|
||||
int32_t OSThread::disable()
|
||||
{
|
||||
enabled = false;
|
||||
setInterval(INT32_MAX);
|
||||
int32_t OSThread::disable() {
|
||||
enabled = false;
|
||||
setInterval(INT32_MAX);
|
||||
|
||||
return INT32_MAX;
|
||||
return INT32_MAX;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,23 +113,22 @@ int32_t OSThread::disable()
|
||||
*/
|
||||
bool hasBeenSetup;
|
||||
|
||||
void assertIsSetup()
|
||||
{
|
||||
void assertIsSetup() {
|
||||
|
||||
/**
|
||||
* Dear developer comrade - If this assert fails() that means you need to fix the following:
|
||||
*
|
||||
* This flag is set **only** when setup() starts, to provide a way for us to check for sloppy static constructor calls.
|
||||
* Call assertIsSetup() to force a crash if someone tries to create an instance too early.
|
||||
*
|
||||
* it is super important to never allocate those object statically. instead, you should explicitly
|
||||
* new them at a point where you are guaranteed that other objects that this instance
|
||||
* depends on have already been created.
|
||||
*
|
||||
* in particular, for OSThread that means "all instances must be declared via new() in setup() or later" -
|
||||
* this makes it guaranteed that the global mainController is fully constructed first.
|
||||
*/
|
||||
assert(hasBeenSetup);
|
||||
/**
|
||||
* Dear developer comrade - If this assert fails() that means you need to fix the following:
|
||||
*
|
||||
* This flag is set **only** when setup() starts, to provide a way for us to check for sloppy static constructor
|
||||
* calls. Call assertIsSetup() to force a crash if someone tries to create an instance too early.
|
||||
*
|
||||
* it is super important to never allocate those object statically. instead, you should explicitly
|
||||
* new them at a point where you are guaranteed that other objects that this instance
|
||||
* depends on have already been created.
|
||||
*
|
||||
* in particular, for OSThread that means "all instances must be declared via new() in setup() or later" -
|
||||
* this makes it guaranteed that the global mainController is fully constructed first.
|
||||
*/
|
||||
assert(hasBeenSetup);
|
||||
}
|
||||
|
||||
} // namespace concurrency
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
#include "ThreadController.h"
|
||||
#include "concurrency/InterruptableDelay.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
extern ThreadController mainController, timerController;
|
||||
extern InterruptableDelay mainDelay;
|
||||
@@ -18,7 +17,8 @@ extern InterruptableDelay mainDelay;
|
||||
/**
|
||||
* @brief Base threading
|
||||
*
|
||||
* This is a pseudo threading layer that is super easy to port, well suited to our slow network and very ram & power efficient.
|
||||
* This is a pseudo threading layer that is super easy to port, well suited to our slow network and very ram & power
|
||||
* efficient.
|
||||
*
|
||||
* TODO FIXME @geeksville
|
||||
*
|
||||
@@ -28,49 +28,48 @@ extern InterruptableDelay mainDelay;
|
||||
* move typedQueue into concurrency
|
||||
* remove freertos from typedqueue
|
||||
*/
|
||||
class OSThread : public Thread
|
||||
{
|
||||
ThreadController *controller;
|
||||
class OSThread : public Thread {
|
||||
ThreadController *controller;
|
||||
|
||||
/// Show debugging info for disabled threads
|
||||
static bool showDisabled;
|
||||
/// Show debugging info for disabled threads
|
||||
static bool showDisabled;
|
||||
|
||||
/// Show debugging info for threads when we run them
|
||||
static bool showRun;
|
||||
/// Show debugging info for threads when we run them
|
||||
static bool showRun;
|
||||
|
||||
/// Show debugging info for threads we decide not to run;
|
||||
static bool showWaiting;
|
||||
/// Show debugging info for threads we decide not to run;
|
||||
static bool showWaiting;
|
||||
|
||||
public:
|
||||
/// For debug printing only (might be null)
|
||||
static const OSThread *currentThread;
|
||||
public:
|
||||
/// For debug printing only (might be null)
|
||||
static const OSThread *currentThread;
|
||||
|
||||
OSThread(const char *name, uint32_t period = 0, ThreadController *controller = &mainController);
|
||||
OSThread(const char *name, uint32_t period = 0, ThreadController *controller = &mainController);
|
||||
|
||||
virtual ~OSThread();
|
||||
virtual ~OSThread();
|
||||
|
||||
virtual bool shouldRun(unsigned long time);
|
||||
virtual bool shouldRun(unsigned long time);
|
||||
|
||||
static void setup();
|
||||
static void setup();
|
||||
|
||||
virtual int32_t disable();
|
||||
virtual int32_t disable();
|
||||
|
||||
/**
|
||||
* Wait a specified number msecs starting from the current time (rather than the last time we were run)
|
||||
*/
|
||||
void setIntervalFromNow(unsigned long _interval);
|
||||
/**
|
||||
* Wait a specified number msecs starting from the current time (rather than the last time we were run)
|
||||
*/
|
||||
void setIntervalFromNow(unsigned long _interval);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The method that will be called each time our thread gets a chance to run
|
||||
*
|
||||
* Returns desired period for next invocation (or RUN_SAME for no change)
|
||||
*/
|
||||
virtual int32_t runOnce() = 0;
|
||||
bool sleepOnNextExecution = false;
|
||||
protected:
|
||||
/**
|
||||
* The method that will be called each time our thread gets a chance to run
|
||||
*
|
||||
* Returns desired period for next invocation (or RUN_SAME for no change)
|
||||
*/
|
||||
virtual int32_t runOnce() = 0;
|
||||
bool sleepOnNextExecution = false;
|
||||
|
||||
// Do not override this
|
||||
virtual void run();
|
||||
// Do not override this
|
||||
virtual void run();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,23 +2,21 @@
|
||||
|
||||
#include "concurrency/OSThread.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* @brief Periodically invoke a callback. This just provides C-style callback conventions
|
||||
* rather than a virtual function - FIXME, remove?
|
||||
*/
|
||||
class Periodic : public OSThread
|
||||
{
|
||||
int32_t (*callback)();
|
||||
class Periodic : public OSThread {
|
||||
int32_t (*callback)();
|
||||
|
||||
public:
|
||||
// callback returns the period for the next callback invocation (or 0 if we should no longer be called)
|
||||
Periodic(const char *name, int32_t (*_callback)()) : OSThread(name), callback(_callback) {}
|
||||
public:
|
||||
// callback returns the period for the next callback invocation (or 0 if we should no longer be called)
|
||||
Periodic(const char *name, int32_t (*_callback)()) : OSThread(name), callback(_callback) {}
|
||||
|
||||
protected:
|
||||
int32_t runOnce() override { return callback(); }
|
||||
protected:
|
||||
int32_t runOnce() override { return callback(); }
|
||||
};
|
||||
|
||||
} // namespace concurrency
|
||||
|
||||
Reference in New Issue
Block a user