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