mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-15 09:32:08 +00:00
fixes
This commit is contained in:
parent
0a6059ba13
commit
d5b8038457
@ -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);
|
|
||||||
}
|
|
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
namespace concurrency {
|
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
|
class Lock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
namespace concurrency {
|
namespace concurrency {
|
||||||
|
|
||||||
// RAII lock guard.
|
/**
|
||||||
|
* @brief RAII lock guard
|
||||||
|
*/
|
||||||
class LockGuard
|
class LockGuard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
namespace concurrency {
|
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
|
class NotifiedWorkerThread : public WorkerThread
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "PeriodicTask.h"
|
#include "PeriodicTask.h"
|
||||||
#include <Arduino.h>
|
|
||||||
|
namespace concurrency {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Periodically invoke a callback.
|
* @brief Periodically invoke a callback. This just provides C-style callback conventions
|
||||||
*
|
* rather than a virtual function - FIXME, remove?
|
||||||
* This just provides C style callback conventions rather than a virtual function - FIXME, remove?
|
|
||||||
*/
|
*/
|
||||||
class Periodic : public PeriodicTask
|
class Periodic : public PeriodicTask
|
||||||
{
|
{
|
||||||
@ -17,5 +17,10 @@ class Periodic : public PeriodicTask
|
|||||||
Periodic(uint32_t (*_callback)()) : callback(_callback) {}
|
Periodic(uint32_t (*_callback)()) : callback(_callback) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void doTask();
|
void doTask() {
|
||||||
|
uint32_t p = callback();
|
||||||
|
setPeriod(p);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace concurrency
|
35
src/concurrency/PeriodicScheduler.cpp
Normal file
35
src/concurrency/PeriodicScheduler.cpp
Normal file
@ -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
|
40
src/concurrency/PeriodicScheduler.h
Normal file
40
src/concurrency/PeriodicScheduler.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Lock.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
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<PeriodicTask *> 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
|
16
src/concurrency/PeriodicTask.cpp
Normal file
16
src/concurrency/PeriodicTask.cpp
Normal file
@ -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
|
@ -1,41 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "lock.h"
|
#include "PeriodicScheduler.h"
|
||||||
#include <Arduino.h>
|
#include "../time.h"
|
||||||
#include <cstdint>
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
class PeriodicTask;
|
namespace concurrency {
|
||||||
|
|
||||||
/**
|
|
||||||
* 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<PeriodicTask *> 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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for tasks that want their doTask() method invoked periodically
|
* A base class for tasks that want their doTask() method invoked periodically
|
||||||
@ -69,7 +37,7 @@ class PeriodicTask
|
|||||||
*/
|
*/
|
||||||
void setPeriod(uint32_t p)
|
void setPeriod(uint32_t p)
|
||||||
{
|
{
|
||||||
lastMsec = millis(); // reset starting from now
|
lastMsec = time::millis(); // reset starting from now
|
||||||
period = p;
|
period = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,3 +51,5 @@ class PeriodicTask
|
|||||||
protected:
|
protected:
|
||||||
virtual void doTask() = 0;
|
virtual void doTask() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace concurrency
|
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
namespace concurrency {
|
namespace concurrency {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Base threading
|
||||||
|
*/
|
||||||
class Thread
|
class Thread
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -5,11 +5,10 @@
|
|||||||
namespace concurrency {
|
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.
|
* @link https://www.freertos.org/RTOS_Task_Notification_As_Mailbox.html
|
||||||
*
|
|
||||||
* https://www.freertos.org/RTOS_Task_Notification_As_Mailbox.html
|
|
||||||
*/
|
*/
|
||||||
class WorkerThread : public Thread
|
class WorkerThread : public Thread
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Observer.h"
|
#include "Observer.h"
|
||||||
#include "PeriodicTask.h"
|
|
||||||
#include "sys/time.h"
|
#include "sys/time.h"
|
||||||
|
|
||||||
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
|
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NEMAGPS.h"
|
#include "NEMAGPS.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "Periodic.h"
|
#include "concurrency/Periodic.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "UBloxGPS.h"
|
#include "UBloxGPS.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
@ -124,7 +124,7 @@ static uint32_t ledBlinker()
|
|||||||
return powerStatus.charging ? 1000 : (ledOn ? 2 : 1000);
|
return powerStatus.charging ? 1000 : (ledOn ? 2 : 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
Periodic ledPeriodic(ledBlinker);
|
concurrency::Periodic ledPeriodic(ledBlinker);
|
||||||
|
|
||||||
// Prepare for button presses
|
// Prepare for button presses
|
||||||
#ifdef BUTTON_PIN
|
#ifdef BUTTON_PIN
|
||||||
@ -316,7 +316,7 @@ uint32_t axpDebugRead()
|
|||||||
return 30 * 1000;
|
return 30 * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Periodic axpDebugOutput(axpDebugRead);
|
concurrency::Periodic axpDebugOutput(axpDebugRead);
|
||||||
axpDebugOutput.setup();
|
axpDebugOutput.setup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -529,7 +529,7 @@ void Screen::handleSetOn(bool on)
|
|||||||
|
|
||||||
void Screen::setup()
|
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
|
// 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.
|
// 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];
|
char channelStr[20];
|
||||||
{
|
{
|
||||||
LockGuard guard(&lock);
|
concurrency::LockGuard guard(&lock);
|
||||||
snprintf(channelStr, sizeof(channelStr), "#%s", channelName.c_str());
|
snprintf(channelStr, sizeof(channelStr), "#%s", channelName.c_str());
|
||||||
|
|
||||||
// Display power status
|
// Display power status
|
||||||
|
16
src/screen.h
16
src/screen.h
@ -10,9 +10,9 @@
|
|||||||
#include <SSD1306Wire.h>
|
#include <SSD1306Wire.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "PeriodicTask.h"
|
#include "concurrency/PeriodicTask.h"
|
||||||
#include "TypedQueue.h"
|
#include "TypedQueue.h"
|
||||||
#include "lock.h"
|
#include "concurrency/Lock.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ class DebugInfo
|
|||||||
/// Sets user statistics.
|
/// Sets user statistics.
|
||||||
void setNodeNumbersStatus(int online, int total)
|
void setNodeNumbersStatus(int online, int total)
|
||||||
{
|
{
|
||||||
LockGuard guard(&lock);
|
concurrency::LockGuard guard(&lock);
|
||||||
nodesOnline = online;
|
nodesOnline = online;
|
||||||
nodesTotal = total;
|
nodesTotal = total;
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ class DebugInfo
|
|||||||
/// Sets the name of the channel.
|
/// Sets the name of the channel.
|
||||||
void setChannelNameStatus(const char *name)
|
void setChannelNameStatus(const char *name)
|
||||||
{
|
{
|
||||||
LockGuard guard(&lock);
|
concurrency::LockGuard guard(&lock);
|
||||||
channelName = name;
|
channelName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ class DebugInfo
|
|||||||
//
|
//
|
||||||
void setPowerStatus(const PowerStatus &status)
|
void setPowerStatus(const PowerStatus &status)
|
||||||
{
|
{
|
||||||
LockGuard guard(&lock);
|
concurrency::LockGuard guard(&lock);
|
||||||
powerStatus = status;
|
powerStatus = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ class DebugInfo
|
|||||||
// TODO(girts): figure out what the format should be.
|
// TODO(girts): figure out what the format should be.
|
||||||
void setGPSStatus(const char *status)
|
void setGPSStatus(const char *status)
|
||||||
{
|
{
|
||||||
LockGuard guard(&lock);
|
concurrency::LockGuard guard(&lock);
|
||||||
gpsStatus = status;
|
gpsStatus = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ class DebugInfo
|
|||||||
std::string gpsStatus;
|
std::string gpsStatus;
|
||||||
|
|
||||||
/// Protects all of internal state.
|
/// Protects all of internal state.
|
||||||
Lock lock;
|
concurrency::Lock lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Deals with showing things on the screen of the device.
|
/// 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
|
// This class is thread-safe (as long as drawFrame is not called multiple times
|
||||||
// simultaneously).
|
// simultaneously).
|
||||||
class Screen : public PeriodicTask
|
class Screen : public concurrency::PeriodicTask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Screen(uint8_t address, int sda = -1, int scl = -1);
|
Screen(uint8_t address, int sda = -1, int scl = -1);
|
||||||
|
11
src/time.h
Normal file
11
src/time.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "freertos.h"
|
||||||
|
|
||||||
|
namespace time {
|
||||||
|
|
||||||
|
uint32_t millis() {
|
||||||
|
return xTaskGetTickCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace time
|
Loading…
Reference in New Issue
Block a user