mirror of
https://github.com/JonasunderscoreJones/PI-server-rack.git
synced 2025-10-22 17:29:17 +02:00
Added protothread arduino library
This commit is contained in:
parent
9ee12e423d
commit
f74472f62b
5 changed files with 383 additions and 0 deletions
75
arduino/libs/ArduinoThread/StaticThreadController.h
Normal file
75
arduino/libs/ArduinoThread/StaticThreadController.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
StaticThreadController.h - Controlls a list of Threads with different timings
|
||||
|
||||
Basicaly, what it does is to keep track of current Threads and run when
|
||||
necessary.
|
||||
|
||||
StaticThreadController is an extended class of Thread, because of that,
|
||||
it allows you to add a StaticThreadController inside another kind of ThreadController...
|
||||
|
||||
It works exact as ThreadController except you can't add or remove treads dynamically.
|
||||
|
||||
Created by Alex Eremin, September, 2016.
|
||||
Released into the public domain.
|
||||
*/
|
||||
|
||||
#ifndef StaticThreadController_h
|
||||
#define StaticThreadController_h
|
||||
|
||||
#include "Thread.h"
|
||||
|
||||
template <int N>
|
||||
class StaticThreadController: public Thread{
|
||||
protected:
|
||||
//since this is a static controller, the pointers themselves can be const
|
||||
//it should be distinguished from 'const Thread* thread[N]'
|
||||
Thread * const thread[N];
|
||||
public:
|
||||
template <typename... T>
|
||||
StaticThreadController(T... params) :
|
||||
Thread(),
|
||||
thread{params...}
|
||||
{
|
||||
#ifdef USE_THREAD_NAMES
|
||||
// Overrides name
|
||||
ThreadName = "StaticThreadController ";
|
||||
ThreadName = ThreadName + ThreadID;
|
||||
#endif
|
||||
};
|
||||
|
||||
// run() Method is overrided
|
||||
void run() override
|
||||
{
|
||||
// Run this thread before
|
||||
if(_onRun != nullptr && shouldRun())
|
||||
_onRun();
|
||||
|
||||
for(int i = 0; i < N; i++){
|
||||
// Is enabled? Timeout exceeded?
|
||||
if(thread[i]->shouldRun()){
|
||||
thread[i]->run();
|
||||
}
|
||||
}
|
||||
|
||||
// StaticThreadController extends Thread, so we should flag as runned thread
|
||||
runned();
|
||||
}
|
||||
|
||||
// Return the quantity of Threads
|
||||
static constexpr int size() { return N; };
|
||||
|
||||
// Return the I Thread on the array
|
||||
// Returns nullptr if index is out of bounds
|
||||
Thread* get(int index) {
|
||||
return (index >= 0 && index < N) ? thread[index] : nullptr;
|
||||
};
|
||||
|
||||
// Return the I Thread on the array
|
||||
// Doesn't perform any bounds checks and behaviour is
|
||||
// unpredictable in case of index > N
|
||||
Thread& operator[](int index) {
|
||||
return *thread[index];
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
52
arduino/libs/ArduinoThread/Thread.cpp
Normal file
52
arduino/libs/ArduinoThread/Thread.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
#include "Thread.h"
|
||||
|
||||
Thread::Thread(void (*callback)(void), unsigned long _interval){
|
||||
enabled = true;
|
||||
onRun(callback);
|
||||
_cached_next_run = 0;
|
||||
last_run = millis();
|
||||
|
||||
ThreadID = (int)this;
|
||||
#ifdef USE_THREAD_NAMES
|
||||
ThreadName = "Thread ";
|
||||
ThreadName = ThreadName + ThreadID;
|
||||
#endif
|
||||
|
||||
setInterval(_interval);
|
||||
};
|
||||
|
||||
void Thread::runned(unsigned long time){
|
||||
// Saves last_run
|
||||
last_run = time;
|
||||
|
||||
// Cache next run
|
||||
_cached_next_run = last_run + interval;
|
||||
}
|
||||
|
||||
void Thread::setInterval(unsigned long _interval){
|
||||
// Save interval
|
||||
interval = _interval;
|
||||
|
||||
// Cache the next run based on the last_run
|
||||
_cached_next_run = last_run + interval;
|
||||
}
|
||||
|
||||
bool Thread::shouldRun(unsigned long time){
|
||||
// If the "sign" bit is set the signed difference would be negative
|
||||
bool time_remaining = (time - _cached_next_run) & 0x80000000;
|
||||
|
||||
// Exceeded the time limit, AND is enabled? Then should run...
|
||||
return !time_remaining && enabled;
|
||||
}
|
||||
|
||||
void Thread::onRun(void (*callback)(void)){
|
||||
_onRun = callback;
|
||||
}
|
||||
|
||||
void Thread::run(){
|
||||
if(_onRun != NULL)
|
||||
_onRun();
|
||||
|
||||
// Update last_run and _cached_next_run
|
||||
runned();
|
||||
}
|
89
arduino/libs/ArduinoThread/Thread.h
Normal file
89
arduino/libs/ArduinoThread/Thread.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Thread.h - An runnable object
|
||||
|
||||
Thread is responsable for holding the "action" for something,
|
||||
also, it responds if it "should" or "should not" run, based on
|
||||
the current time;
|
||||
|
||||
For instructions, go to https://github.com/ivanseidel/ArduinoThread
|
||||
|
||||
Created by Ivan Seidel Gomes, March, 2013.
|
||||
Released into the public domain.
|
||||
*/
|
||||
|
||||
#ifndef Thread_h
|
||||
#define Thread_h
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
Uncomment this line to enable ThreadName Strings.
|
||||
|
||||
It might be usefull if you are loging thread with Serial,
|
||||
or displaying a list of threads...
|
||||
*/
|
||||
// #define USE_THREAD_NAMES 1
|
||||
|
||||
class Thread{
|
||||
protected:
|
||||
// Desired interval between runs
|
||||
unsigned long interval;
|
||||
|
||||
// Last runned time in Ms
|
||||
unsigned long last_run;
|
||||
|
||||
// Scheduled run in Ms (MUST BE CACHED)
|
||||
unsigned long _cached_next_run;
|
||||
|
||||
/*
|
||||
IMPORTANT! Run after all calls to run()
|
||||
Updates last_run and cache next run.
|
||||
NOTE: This MUST be called if extending
|
||||
this class and implementing run() method
|
||||
*/
|
||||
void runned(unsigned long time);
|
||||
|
||||
// Default is to mark it runned "now"
|
||||
void runned() { runned(millis()); }
|
||||
|
||||
// Callback for run() if not implemented
|
||||
void (*_onRun)(void);
|
||||
|
||||
public:
|
||||
|
||||
// If the current Thread is enabled or not
|
||||
bool enabled;
|
||||
|
||||
// ID of the Thread (initialized from memory adr.)
|
||||
int ThreadID;
|
||||
|
||||
#ifdef USE_THREAD_NAMES
|
||||
// Thread Name (used for better UI).
|
||||
String ThreadName;
|
||||
#endif
|
||||
|
||||
Thread(void (*callback)(void) = NULL, unsigned long _interval = 0);
|
||||
|
||||
// Set the desired interval for calls, and update _cached_next_run
|
||||
virtual void setInterval(unsigned long _interval);
|
||||
|
||||
// Return if the Thread should be runned or not
|
||||
virtual bool shouldRun(unsigned long time);
|
||||
|
||||
// Default is to check whether it should run "now"
|
||||
bool shouldRun() { return shouldRun(millis()); }
|
||||
|
||||
// Callback set
|
||||
void onRun(void (*callback)(void));
|
||||
|
||||
// Runs Thread
|
||||
virtual void run();
|
||||
};
|
||||
|
||||
#endif
|
114
arduino/libs/ArduinoThread/ThreadController.cpp
Normal file
114
arduino/libs/ArduinoThread/ThreadController.cpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
#include "Thread.h"
|
||||
#include "ThreadController.h"
|
||||
|
||||
ThreadController::ThreadController(unsigned long _interval): Thread(){
|
||||
cached_size = 0;
|
||||
|
||||
clear();
|
||||
setInterval(_interval);
|
||||
|
||||
#ifdef USE_THREAD_NAMES
|
||||
// Overrides name
|
||||
ThreadName = "ThreadController ";
|
||||
ThreadName = ThreadName + ThreadID;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
ThreadController run() (cool stuf)
|
||||
*/
|
||||
void ThreadController::run(){
|
||||
// Run this thread before
|
||||
if(_onRun != NULL)
|
||||
_onRun();
|
||||
|
||||
unsigned long time = millis();
|
||||
int checks = 0;
|
||||
for(int i = 0; i < MAX_THREADS && checks < cached_size; i++){
|
||||
// Object exists? Is enabled? Timeout exceeded?
|
||||
if(thread[i]){
|
||||
checks++;
|
||||
if(thread[i]->shouldRun(time)){
|
||||
thread[i]->run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ThreadController extends Thread, so we should flag as runned thread
|
||||
runned();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
List controller (boring part)
|
||||
*/
|
||||
bool ThreadController::add(Thread* _thread){
|
||||
// Check if the Thread already exists on the array
|
||||
for(int i = 0; i < MAX_THREADS; i++){
|
||||
if(thread[i] != NULL && thread[i]->ThreadID == _thread->ThreadID)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find an empty slot
|
||||
for(int i = 0; i < MAX_THREADS; i++){
|
||||
if(!thread[i]){
|
||||
// Found a empty slot, now add Thread
|
||||
thread[i] = _thread;
|
||||
cached_size++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Array is full
|
||||
return false;
|
||||
}
|
||||
|
||||
void ThreadController::remove(int id){
|
||||
// Find Threads with the id, and removes
|
||||
for(int i = 0; i < MAX_THREADS; i++){
|
||||
if(thread[i]->ThreadID == id){
|
||||
thread[i] = NULL;
|
||||
cached_size--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadController::remove(Thread* _thread){
|
||||
remove(_thread->ThreadID);
|
||||
}
|
||||
|
||||
void ThreadController::clear(){
|
||||
for(int i = 0; i < MAX_THREADS; i++){
|
||||
thread[i] = NULL;
|
||||
}
|
||||
cached_size = 0;
|
||||
}
|
||||
|
||||
int ThreadController::size(bool cached){
|
||||
if(cached)
|
||||
return cached_size;
|
||||
|
||||
int size = 0;
|
||||
for(int i = 0; i < MAX_THREADS; i++){
|
||||
if(thread[i])
|
||||
size++;
|
||||
}
|
||||
cached_size = size;
|
||||
|
||||
return cached_size;
|
||||
}
|
||||
|
||||
Thread* ThreadController::get(int index){
|
||||
int pos = -1;
|
||||
for(int i = 0; i < MAX_THREADS; i++){
|
||||
if(thread[i] != NULL){
|
||||
pos++;
|
||||
|
||||
if(pos == index)
|
||||
return thread[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
53
arduino/libs/ArduinoThread/ThreadController.h
Normal file
53
arduino/libs/ArduinoThread/ThreadController.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
ThreadController.h - Controlls a list of Threads with different timings
|
||||
|
||||
Basicaly, what it does is to keep track of current Threads and run when
|
||||
necessary.
|
||||
|
||||
ThreadController is an extended class of Thread, because of that,
|
||||
it allows you to add a ThreadController inside another ThreadController...
|
||||
|
||||
For instructions, go to https://github.com/ivanseidel/ArduinoThread
|
||||
|
||||
Created by Ivan Seidel Gomes, March, 2013.
|
||||
Released into the public domain.
|
||||
*/
|
||||
|
||||
#ifndef ThreadController_h
|
||||
#define ThreadController_h
|
||||
|
||||
#include "Thread.h"
|
||||
#include "inttypes.h"
|
||||
|
||||
#define MAX_THREADS 15
|
||||
|
||||
class ThreadController: public Thread{
|
||||
protected:
|
||||
Thread* thread[MAX_THREADS];
|
||||
int cached_size;
|
||||
public:
|
||||
ThreadController(unsigned long _interval = 0);
|
||||
|
||||
// run() Method is overrided
|
||||
void run();
|
||||
|
||||
// Adds a thread in the first available slot (remove first)
|
||||
// Returns if the Thread could be added or not
|
||||
bool add(Thread* _thread);
|
||||
|
||||
// remove the thread (given the Thread* or ThreadID)
|
||||
void remove(int _id);
|
||||
void remove(Thread* _thread);
|
||||
|
||||
// Removes all threads
|
||||
void clear();
|
||||
|
||||
// Return the quantity of Threads
|
||||
int size(bool cached = true);
|
||||
|
||||
// Return the I Thread on the array
|
||||
// Returns NULL if none found
|
||||
Thread* get(int index);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue