Skip to content

Commit 9e70760

Browse files
committed
port back from main libraries project
1 parent 011c691 commit 9e70760

File tree

3 files changed

+127
-38
lines changed

3 files changed

+127
-38
lines changed

src/TaskManagerIO.cpp

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,63 @@
77
#include "TaskManagerIO.h"
88
#include "ExecWithParameter.h"
99

10+
#ifdef BUILD_FOR_PICO_CMAKE
11+
critical_section_t* tm_internal::tmLock;
12+
13+
void tm_internal::initPicoTmLock() {
14+
tmLock = new critical_section_t;
15+
critical_section_init(tmLock);
16+
}
17+
18+
#include <cctype>
19+
20+
void yield() {
21+
sleep_us(1);
22+
}
23+
24+
unsigned long millis() {
25+
return to_ms_since_boot(get_absolute_time());
26+
}
27+
28+
unsigned long micros() {
29+
return to_us_since_boot(get_absolute_time());
30+
}
31+
32+
#endif
33+
34+
#ifdef IOA_USE_MBED
35+
36+
volatile bool timingStarted = false;
37+
Timer ioaTimer;
38+
39+
void yield() {
40+
41+
# if !defined(PIO_NEEDS_RTOS_WORKAROUND)
42+
ThisThread::yield();
43+
#else
44+
wait(0.0000001);
45+
#endif
46+
}
47+
48+
unsigned long millis() {
49+
if(!timingStarted) {
50+
timingStarted = true;
51+
ioaTimer.start();
52+
}
53+
return ioaTimer.read_ms();
54+
}
55+
56+
unsigned long micros() {
57+
if(!timingStarted) {
58+
timingStarted = true;
59+
ioaTimer.start();
60+
}
61+
return (unsigned long) ioaTimer.read_high_resolution_us();
62+
}
63+
64+
#endif
65+
66+
1067
TaskManager taskManager;
1168

1269
namespace tm_internal {
@@ -47,6 +104,9 @@ ISR_ATTR void TaskManager::markInterrupted(pintype_t interruptNo) {
47104
}
48105

49106
TaskManager::TaskManager() : taskBlocks {} {
107+
#ifdef BUILD_FOR_PICO_CMAKE
108+
tm_internal::initPicoTmLock();
109+
#endif
50110
interrupted = false;
51111
tm_internal::atomicWritePtr(&first, nullptr);
52112
interruptCallback = nullptr;
@@ -466,38 +526,6 @@ taskid_t TaskManager::schedule(const TimePeriod &when, Executable *execRef, bool
466526
}
467527
}
468528

469-
#ifdef IOA_USE_MBED
470-
471-
volatile bool timingStarted = false;
472-
Timer ioaTimer;
473-
474-
void yield() {
475-
476-
# if !defined(PIO_NEEDS_RTOS_WORKAROUND)
477-
ThisThread::yield();
478-
#else
479-
wait(0.0000001);
480-
#endif
481-
}
482-
483-
unsigned long millis() {
484-
if(!timingStarted) {
485-
timingStarted = true;
486-
ioaTimer.start();
487-
}
488-
return ioaTimer.read_ms();
489-
}
490-
491-
unsigned long micros() {
492-
if(!timingStarted) {
493-
timingStarted = true;
494-
ioaTimer.start();
495-
}
496-
return (unsigned long) ioaTimer.read_high_resolution_us();
497-
}
498-
499-
#endif
500-
501529
TimePeriod::TimePeriod() {
502530
amount = 0;
503531
unit = TIME_MILLIS;

src/TaskManagerIO.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,19 @@ enum InterruptMode;
2222
* outside of task manager can add, remove and manage tasks even while task manager is running.
2323
*/
2424

25-
#ifdef IOA_USE_MBED
25+
#if defined(IOA_USE_MBED) || defined(BUILD_FOR_PICO_CMAKE)
2626
#include <cstdint>
27-
/** MBED ONLY: This defines the yield function for mbed boards, as per framework on Arduino */
27+
/** This defines the yield function for environments that don't have the function, as per framework on Arduino */
2828
void yield();
29-
/** MBED ONLY: This defines the millis function for mbed boards by using a timer, as per framework on Arduino */
29+
/** MBED ONLY: This defines the millis function for environments that don't have the function, as per framework on Arduino */
3030
uint32_t millis();
31-
/** MBED ONLY: This defines the micros function to use the standard mbed us timer, as per framework on Arduino */
31+
/** MBED ONLY: This defines the micros function as per framework on Arduino on environments that don't have it */
3232
uint32_t micros();
33+
#ifdef IOA_USE_MBED
3334
#define delayMicroseconds(x) wait_us(x)
35+
#else
36+
#define delayMicroseconds(x) sleep_us(x)
37+
#endif // DELAY Microseconds code
3438
#endif // IOA_USE_MBED
3539

3640
/**
@@ -387,6 +391,13 @@ class TaskManager {
387391
*/
388392
TimerTask* getRunningTask() { return runningTask; }
389393

394+
#if defined(BUILD_FOR_PICO_CMAKE) || defined(ARDUINO_PICO_REVISION)
395+
void rpiSleepingRunLoop() {
396+
taskManager.runLoop();
397+
auto toNextTime = taskManager.microsToNextTask();
398+
sleep_us(toNextTime);
399+
}
400+
#endif
390401
friend class TaskExecutionRecorder;
391402
private:
392403
/**

src/TaskPlatformDeps.h

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ class TimerTask;
2424
#endif // has include "io_local_definitions"
2525

2626
// when not on mbed, we need to load Arduino.h to get the right defines for some boards.
27-
#ifndef __MBED__
27+
#if defined(BUILD_FOR_PICO_CMAKE)
28+
#include <pico/stdlib.h>
29+
#include <valarray>
30+
#ifndef min
31+
#define min(a, b) (((a) < (b)) ? (a) : (b))
32+
#define max(a, b) (((a) > (b)) ? (a) : (b))
33+
#endif
34+
#elif !defined(__MBED__)
2835
#include <Arduino.h>
2936
#endif
3037

@@ -116,7 +123,6 @@ namespace tm_internal {
116123
}
117124
}
118125
#elif defined(ESP8266) || defined(ESP32) || defined(ARDUINO_PICO_REVISION)
119-
#include "Arduino.h"
120126
typedef uint8_t pintype_t;
121127
# define IOA_USE_ARDUINO
122128
#if defined(TM_ENABLE_CAPTURED_LAMBDAS)
@@ -244,7 +250,51 @@ namespace tm_internal {
244250
}
245251
}
246252
#endif
253+
#elif defined(BUILD_FOR_PICO_CMAKE)
254+
#include <pico/critical_section.h>
255+
#if defined(TM_ENABLE_CAPTURED_LAMBDAS)
256+
#define TM_ALLOW_CAPTURED_LAMBDA
257+
#endif
258+
typedef uint8_t pintype_t;
259+
namespace tm_internal {
260+
typedef TimerTask *volatile TimerTaskAtomicPtr;
261+
typedef volatile bool TmAtomicBool;
262+
extern critical_section_t* tmLock;
263+
void initPicoTmLock();
264+
265+
static bool atomicSwapBool(volatile bool *ptr, bool expected, bool newValue) {
266+
bool ret = false;
267+
critical_section_enter_blocking(tmLock);
268+
if(*ptr == expected) {
269+
*ptr = newValue;
270+
ret = true;
271+
}
272+
critical_section_exit(tmLock);
273+
return ret;
274+
}
275+
276+
static void atomicWriteBool(volatile bool *ptr, bool val) {
277+
critical_section_enter_blocking(tmLock);
278+
*ptr = val;
279+
critical_section_exit(tmLock);
280+
}
281+
282+
inline bool atomicReadBool(volatile bool *ptr) {
283+
bool ret = false;
284+
critical_section_enter_blocking(tmLock);
285+
ret = *ptr;
286+
critical_section_exit(tmLock);
287+
return ret;
288+
}
289+
290+
inline void atomicWritePtr(TimerTaskAtomicPtr *ptr, TimerTask *newVal) {
291+
*ptr = newVal;
292+
}
247293

294+
inline TimerTask *atomicReadPtr(TimerTaskAtomicPtr *ptr) {
295+
return *ptr;
296+
}
297+
}
248298
#else
249299
// fall back to using Arduino regular logic, works for all single core boards. If we end up here for a multicore
250300
// board then there may be problems. Here we are in full arduino mode (AVR, MKR etc).

0 commit comments

Comments
 (0)