forked from mikaelpatel/Arduino-Scheduler
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Scheduler.h
164 lines (137 loc) · 4.66 KB
/
Scheduler.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
162
163
164
/**
* @file Scheduler.h
* @version 1.2
*
* @section License
* Copyright (C) 2015-2016, Mikael Patel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef SCHEDULER_H
#define SCHEDULER_H
#include <setjmp.h>
#include <stddef.h>
#include <stdint.h>
//#define DEBUG_SCHEDULER 1
#if defined(ARDUINO_ARCH_ESP8266)
extern "C" unsigned int get_clock();
extern "C" void delay_until(uint32_t clock_ms);
#endif
class SchedulerClass {
public:
/**
* Function prototype (task setup and loop functions).
*/
typedef void (*func_t)();
/**
* Initiate scheduler and main task with given stack size. Should
* be called before start of any tasks if the main task requires a
* stack size other than the default size. Returns true if
* successful otherwise false.
* @param[in] stackSize in bytes.
* @return bool.
*/
static bool begin(size_t stackSize);
/**
* Start a task with given functions and stack size. Should be
* called from main task (in setup). The functions are executed by
* the task. The taskSetup function (if provided) is run once.
* The taskLoop function is repeatedly called. The taskSetup may be
* omitted (NULL). Returns true if successful otherwise false.
* @param[in] taskSetup function (may be NULL).
* @param[in] taskLoop function (may not be NULL).
* @param[in] stackSize in bytes.
* @return bool.
*/
static bool start(func_t taskSetup,
func_t taskLoop,
size_t stackSize = DEFAULT_STACK_SIZE);
/**
* Context switch to next task in run queue.
*/
static void yield();
/**
* Return stack length of the current task.
* @return bytes
*/
static size_t stack();
/**
* Return stack size
* @return size_t
*/
static size_t * stackSize() { return (size_t *) s_top; };
/**
* Return number of tasks
* @return size_t
*/
static size_t numberOfTasks() { return s_count; };
protected:
/**
* Initiate a task with the given functions and stack. When control
* is yield to the task the setup function is first called and then
* the loop function is repeatedly called.
* @param[in] setup task function (may be NULL).
* @param[in] loop task function (may not be NULL).
* @param[in] stack top reference.
*/
static void init(func_t setup, func_t loop, const uint8_t* stack);
/**
* Task run-time structure.
*/
struct task_t {
task_t* next; //!< Next task.
task_t* prev; //!< Previous task.
jmp_buf context; //!< Task context.
const uint8_t* stack; //!< Task stack.
};
#if defined(TEENSYDUINO) && defined(__MK20DX256__)
/** Default stack size and stack max. */
static const size_t DEFAULT_STACK_SIZE = 512;
static const size_t STACK_MAX = 16384;
#elif defined(ARDUINO_ARCH_AVR)
/** Default stack size. */
static const size_t DEFAULT_STACK_SIZE = 128;
#elif defined(ARDUINO_ARCH_SAM)
/** Default stack size and stack max. */
static const size_t DEFAULT_STACK_SIZE = 512;
static const size_t STACK_MAX = 32768;
#elif defined(ARDUINO_ARCH_SAMD)
/** Default stack size and stack max. */
static const size_t DEFAULT_STACK_SIZE = 512;
static const size_t STACK_MAX = 16384;
#elif defined(ARDUINO_ARCH_ESP8266)
/** Default stack size and stack max. */
static const size_t DEFAULT_STACK_SIZE = 512;
static const size_t STACK_MAX = 0x2000 + 0x4000 + 0x2000; // esp8266 Arduino reserves 4096bytes for the stack (heap starts 0x3FFF after the stack begin address)
#else
#error "Scheduler.h: board not supported"
#endif
/** Main task. */
static task_t s_main;
/** Running task. */
static task_t* s_running;
/** Task stack allocation top. */
static size_t s_top;
/** Number of registered tasks. */
static size_t s_count;
};
/** Scheduler single-ton. */
//extern SchedulerClass Scheduler;
#define Scheduler sched()
extern SchedulerClass& sched(void);
/**
* Syntactic sugar for scheduler based busy-wait for condition;
* yield until condition is valid. May require volatile condition
* variable(s).
* @param[in] cond condition to await.
*/
#define await(cond) while (!(cond)) yield()
#endif