Skip to content

Commit d39be67

Browse files
committed
Add Schedule.(h|cpp) from ESP8266 to run off loopTask.
1 parent ce898df commit d39be67

File tree

5 files changed

+108
-0
lines changed

5 files changed

+108
-0
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ set(CORE_SRCS
2828
cores/esp32/MD5Builder.cpp
2929
cores/esp32/Print.cpp
3030
cores/esp32/stdlib_noniso.c
31+
cores/esp32/Schedule.cpp
3132
cores/esp32/Stream.cpp
3233
cores/esp32/StreamString.cpp
3334
cores/esp32/wiring_pulse.c

cores/esp32/Arduino.h

+1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
159159
#include "Udp.h"
160160
#include "HardwareSerial.h"
161161
#include "Esp.h"
162+
#include "Schedule.h"
162163

163164
using std::isinf;
164165
using std::isnan;

cores/esp32/Schedule.cpp

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include "Schedule.h"
2+
3+
struct scheduled_fn_t
4+
{
5+
scheduled_fn_t* mNext;
6+
std::function<void(void)> mFunc;
7+
};
8+
9+
static scheduled_fn_t* sFirst = 0;
10+
static scheduled_fn_t* sLast = 0;
11+
12+
static scheduled_fn_t* sFirstUnused = 0;
13+
static scheduled_fn_t* sLastUnused = 0;
14+
15+
static int sCount = 0;
16+
17+
static scheduled_fn_t* get_fn() {
18+
scheduled_fn_t* result = NULL;
19+
// try to get an item from unused items list
20+
if (sFirstUnused) {
21+
result = sFirstUnused;
22+
sFirstUnused = result->mNext;
23+
if (sFirstUnused == NULL) {
24+
sLastUnused = NULL;
25+
}
26+
}
27+
// if no unused items, and count not too high, allocate a new one
28+
else if (sCount != SCHEDULED_FN_MAX_COUNT) {
29+
result = new scheduled_fn_t;
30+
result->mNext = NULL;
31+
++sCount;
32+
}
33+
return result;
34+
}
35+
36+
static void recycle_fn(scheduled_fn_t* fn)
37+
{
38+
if (!sLastUnused) {
39+
sFirstUnused = fn;
40+
}
41+
else {
42+
sLastUnused->mNext = fn;
43+
}
44+
fn->mNext = NULL;
45+
sLastUnused = fn;
46+
}
47+
48+
bool schedule_function(std::function<void(void)> fn)
49+
{
50+
scheduled_fn_t* item = get_fn();
51+
if (!item) {
52+
return false;
53+
}
54+
item->mFunc = fn;
55+
item->mNext = NULL;
56+
if (!sFirst) {
57+
sFirst = item;
58+
}
59+
else {
60+
sLast->mNext = item;
61+
}
62+
sLast = item;
63+
return true;
64+
}
65+
66+
void run_scheduled_functions()
67+
{
68+
scheduled_fn_t* rFirst = sFirst;
69+
sFirst = NULL;
70+
sLast = NULL;
71+
while (rFirst) {
72+
scheduled_fn_t* item = rFirst;
73+
rFirst = item->mNext;
74+
item->mFunc();
75+
item->mFunc = std::function<void(void)>();
76+
recycle_fn(item);
77+
}
78+
}

cores/esp32/Schedule.h

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef ESP_SCHEDULE_H
2+
#define ESP_SCHEDULE_H
3+
4+
#include <functional>
5+
6+
#define SCHEDULED_FN_MAX_COUNT 32
7+
#define SCHEDULED_FN_INITIAL_COUNT 4
8+
9+
// Warning
10+
// This API is not considered stable.
11+
// Function signatures will change.
12+
// You have been warned.
13+
14+
// Run given function next time `loop` function returns,
15+
// or `run_scheduled_functions` is called.
16+
// Use std::bind to pass arguments to a function, or call a class member function.
17+
// Note: there is no mechanism for cancelling scheduled functions.
18+
// Keep that in mind when binding functions to objects which may have short lifetime.
19+
// Returns false if the number of scheduled functions exceeds SCHEDULED_FN_MAX_COUNT.
20+
bool schedule_function(std::function<void(void)> fn);
21+
22+
// Run all scheduled functions.
23+
// Use this function if your are not using `loop`, or `loop` does not return
24+
// on a regular basis.
25+
void run_scheduled_functions();
26+
27+
#endif //ESP_SCHEDULE_H

cores/esp32/main.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ void loopTask(void *pvParameters)
1717
esp_task_wdt_reset();
1818
}
1919
loop();
20+
run_scheduled_functions();
2021
}
2122
}
2223

0 commit comments

Comments
 (0)