-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathScheduler2.h
161 lines (149 loc) · 4.51 KB
/
Scheduler2.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#ifndef __SCHEDULER_H__
#define __SCHEDULER_H__
#include <string.h>
#include <Arduino.h>
#define DISABLED 128
#define NEVENTS 20 // must be NEVENTS < DISABLED!!!
#define NTIMES 20
#define PERIODIC 0
#define ASYNC_A 1
#define ASYNC_B 2
// https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Mediator
//per disaccoppiare Scheduler e gli eventi è necessario far derivare entrambi
//da genitori che non hanno riferimenti incrociati (pattern mediatore).
//Inoltre, per poter invocare doEvent() su eventi diversi è necessario
//realizzare un late binding con un metodo virtuale
using PEventCallback = void (*)(); //type aliasing
class Sched{
public:
uint8_t id;
};
class Evnt{
public:
Sched *sch;
unsigned order;
bool enabled;
bool tochange;
uint8_t type;
uint8_t id;
//uint8_t pos;
unsigned long time;
unsigned long counter;
PEventCallback pevent;
Evnt(Sched *s, unsigned long every, PEventCallback x, uint8_t priority, bool enable, uint8_t etype){
time = every;
sch = s;
pevent = x;
id = priority;
order = priority;
enabled = enable;
type = etype;
counter = 0;
};
virtual void doEvent(unsigned long step); //late binding
};
//late binding
class PeriodicEvnt: public Evnt{
public:
void doEvent(unsigned long step){
if(pevent != NULL)
(*pevent)();
};
PeriodicEvnt(Sched *x, unsigned long y, PEventCallback z, uint8_t u, bool v, uint8_t t):Evnt(x,y,z,u,v,t){};
};
/*
class AsyncEvntA: public Evnt{
public:
unsigned long slaveTime;
uint8_t slaveId;
unsigned long duration;
unsigned long interval;
bool periodic;
void doEvent(unsigned long step);
AsyncEvntA(Sched *x, unsigned long y, unsigned long z, uint8_t m, PEventCallback n, uint8_t k, bool u, uint8_t v, unsigned long howlong, unsigned long every, bool repeat):Evnt(x,y,n,k,u,v){
duration = howlong;
interval = every;
periodic = repeat;
slaveTime = z;
slaveId = m;
};
};
*/
class AsyncEvntB: public Evnt{
public:
unsigned long slaveTime;
uint8_t slaveId;
unsigned long duration;
unsigned long interval;
bool periodic;
void doEvent(unsigned long step);
AsyncEvntB(Sched *x, unsigned long y, unsigned long z, uint8_t m, PEventCallback n, uint8_t k, bool u, uint8_t v, unsigned long howlong, unsigned long every, bool repeat):Evnt(x,y,n,k,u,v){
duration = howlong;
interval = every;
periodic = repeat;
slaveTime = z;
slaveId = m;
};
};
class TCB{
public:
Evnt *events[NEVENTS];
//uint8_t pos;
uint8_t fe=0;// first empty
uint8_t enabled;
unsigned long step=0;
unsigned long prec=0;
unsigned long elapsed=0;
unsigned long time=-1;
TCB(){};
bool addEvent(Evnt *);
bool delEvent(uint8_t, bool);
void sort(Evnt **);
void scambia(Evnt **, Evnt **);
int cerca(uint8_t, Evnt **);
bool getEventState(uint8_t order);
bool enableEvent(uint8_t);
bool disableEvent(uint8_t);
int getNEvents();
//bool disableEventPos(uint8_t pos);
//bool enableEventPos(uint8_t pos);
};
class Scheduler: public Sched{
private:
int nt = 0;
TCB tasks[NTIMES];
unsigned long tbase;
unsigned long prec=0;
//volatile unsigned long step;
unsigned long gcd(unsigned long, unsigned long);
unsigned long nsteps;
unsigned long findGCD();
void timeSort(TCB*);
int timeSearch(unsigned long, TCB*);
void maxstepCalc();
unsigned long lcm(unsigned long m, unsigned long n, unsigned long g);
void setTimes();
int addTime( unsigned long);
bool delTime(unsigned long);
bool delTimeByPos(int);
unsigned long mcm;
volatile bool timerFlag;
public:
Scheduler();
void init();
bool addPeriodicEvent(PEventCallback pevnt, uint8_t priority, unsigned long every, bool enabled = true);
bool addAsyncEvent(PEventCallback pevnt, uint8_t priority, unsigned long when, unsigned long howlong, unsigned long every, bool repeat);
bool deletePeriodicEvent(uint8_t, unsigned long, bool test = false);
void scheduleAll();
void scheduleAllISRFlagged(bool noflag=false);
unsigned getTimebase();
//unsigned long getNsteps();
long getTime(unsigned long when);
bool getEventState(uint8_t priority, unsigned long every);
bool setEventState(uint8_t priority, bool state, unsigned long every);
bool enableEvent(uint8_t priority, unsigned long every);
bool disableEvent(uint8_t priority, unsigned long every);
bool toggleEvent(uint8_t priority, unsigned long every);
void timerISR(void);
};
#endif