Skip to content

Commit 413513b

Browse files
committed
Add Schedule and Functional/Scheduled Ticker
1 parent 1424b6d commit 413513b

File tree

5 files changed

+158
-9
lines changed

5 files changed

+158
-9
lines changed

cores/esp32/Schedule.cpp

Lines changed: 78 additions & 0 deletions
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

Lines changed: 27 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "freertos/FreeRTOS.h"
22
#include "freertos/task.h"
33
#include "Arduino.h"
4+
#include "Schedule.h"
45

56
#if CONFIG_AUTOSTART_ARDUINO
67

@@ -16,6 +17,7 @@ void loopTask(void *pvParameters)
1617
for(;;) {
1718
micros(); //update overflow
1819
loop();
20+
run_scheduled_functions();
1921
}
2022
}
2123

libraries/Ticker/src/Ticker.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,18 @@ void Ticker::detach() {
5454
esp_timer_stop(_timer);
5555
esp_timer_delete(_timer);
5656
_timer = nullptr;
57+
_callback_function = nullptr;
5758
}
5859
}
60+
61+
void Ticker::_static_callback(void* arg){
62+
Ticker* _this = (Ticker*)arg;
63+
if (_this == nullptr)
64+
{
65+
return;
66+
}
67+
if (_this->_callback_function)
68+
{
69+
_this->_callback_function();
70+
}
71+
}

libraries/Ticker/src/Ticker.h

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
#ifndef TICKER_H
2626
#define TICKER_H
2727

28+
#include <functional>
29+
#include "Schedule.h"
30+
2831
extern "C" {
2932
#include "esp_timer.h"
3033
}
@@ -36,15 +39,28 @@ class Ticker
3639
~Ticker();
3740
typedef void (*callback_t)(void);
3841
typedef void (*callback_with_arg_t)(void*);
42+
typedef std::function<void(void)> callback_function_t;
43+
44+
void attach_scheduled(float seconds, callback_function_t callback)
45+
{
46+
attach(seconds,std::bind(schedule_function, callback));
47+
}
48+
49+
void attach(float seconds, callback_function_t callback)
50+
{
51+
_callback_function = callback;
52+
attach(seconds, _static_callback, (void*)this);
53+
}
3954

40-
void attach(float seconds, callback_t callback)
55+
void attach_ms_scheduled(uint32_t milliseconds, callback_function_t callback)
4156
{
42-
_attach_ms(seconds * 1000, true, reinterpret_cast<callback_with_arg_t>(callback), 0);
57+
attach_ms(milliseconds, std::bind(schedule_function, callback));
4358
}
4459

45-
void attach_ms(uint32_t milliseconds, callback_t callback)
60+
void attach_ms(uint32_t milliseconds, callback_function_t callback)
4661
{
47-
_attach_ms(milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), 0);
62+
_callback_function = callback;
63+
attach_ms(milliseconds, _static_callback, (void*)this);
4864
}
4965

5066
template<typename TArg>
@@ -66,14 +82,26 @@ class Ticker
6682
_attach_ms(milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), arg32);
6783
}
6884

69-
void once(float seconds, callback_t callback)
85+
void once_scheduled(float seconds, callback_function_t callback)
7086
{
71-
_attach_ms(seconds * 1000, false, reinterpret_cast<callback_with_arg_t>(callback), 0);
87+
once(seconds, std::bind(schedule_function, callback));
7288
}
7389

74-
void once_ms(uint32_t milliseconds, callback_t callback)
90+
void once(float seconds, callback_function_t callback)
7591
{
76-
_attach_ms(milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), 0);
92+
_callback_function = callback;
93+
once(seconds, _static_callback, (void*)this);
94+
}
95+
96+
void once_ms_scheduled(uint32_t milliseconds, callback_function_t callback)
97+
{
98+
once_ms(milliseconds, std::bind(schedule_function, callback));
99+
}
100+
101+
void once_ms(uint32_t milliseconds, callback_function_t callback)
102+
{
103+
_callback_function = callback;
104+
once_ms(milliseconds, _static_callback, (void*)this);
77105
}
78106

79107
template<typename TArg>
@@ -97,10 +125,11 @@ class Ticker
97125

98126
protected:
99127
void _attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, uint32_t arg);
100-
128+
static void _static_callback (void* arg);
101129

102130
protected:
103131
esp_timer_handle_t _timer;
132+
callback_function_t _callback_function = nullptr;
104133
};
105134

106135

0 commit comments

Comments
 (0)