Line data Source code
1 : #pragma once
2 :
3 : #include <stdint.h>
4 :
5 : #include <AP_Common/AP_Common.h>
6 :
7 : #include "AP_HAL_Boards.h"
8 : #include "AP_HAL_Namespace.h"
9 :
10 :
11 : class AP_HAL::Scheduler {
12 : public:
13 2193 : Scheduler() {}
14 : virtual void init() = 0;
15 : virtual void delay(uint16_t ms) = 0;
16 :
17 : /*
18 : delay for the given number of microseconds. This needs to be as
19 : accurate as possible - preferably within 100 microseconds.
20 : */
21 : virtual void delay_microseconds(uint16_t us) = 0;
22 :
23 : /*
24 : delay for the given number of microseconds. On supported
25 : platforms this boosts the priority of the main thread for a
26 : short time when the time completes. The aim is to ensure the
27 : main thread runs at a higher priority than drivers for the start
28 : of each loop
29 : */
30 42194549 : virtual void delay_microseconds_boost(uint16_t us) { delay_microseconds(us); }
31 :
32 : /*
33 : inform the scheduler that we are calling an operation from the
34 : main thread that may take an extended amount of time. This can
35 : be used to prevent watchdog reset during expected long delays
36 : A value of zero cancels the previous expected delay
37 : */
38 3556776 : virtual void expect_delay_ms(uint32_t ms) { }
39 :
40 : /*
41 : return true if we are in a period of expected delay. This can be
42 : used to suppress error messages
43 : */
44 0 : virtual bool in_expected_delay(void) const { return false; }
45 :
46 : /*
47 : end the priority boost from delay_microseconds_boost()
48 : */
49 41686716 : virtual void boost_end(void) {}
50 :
51 : // register a function to be called by the scheduler if it needs
52 : // to sleep for more than min_time_ms
53 : virtual void register_delay_callback(AP_HAL::Proc,
54 : uint16_t min_time_ms);
55 : // returns true if the Scheduler has called the delay callback
56 : // function. If you are on the main thread that means your call
57 : // stack has the scheduler on it somewhere.
58 455779061 : virtual bool in_delay_callback() const { return _in_delay_callback; }
59 :
60 : // register a high priority timer task
61 : virtual void register_timer_process(AP_HAL::MemberProc) = 0;
62 :
63 : // register a low priority IO task
64 : virtual void register_io_process(AP_HAL::MemberProc) = 0;
65 :
66 : virtual void register_timer_failsafe(AP_HAL::Proc,
67 : uint32_t period_us) = 0;
68 :
69 : // check and set the startup state
70 : virtual void set_system_initialized() = 0;
71 : virtual bool is_system_initialized() = 0;
72 :
73 : virtual void reboot(bool hold_in_bootloader = false) = 0;
74 :
75 : /**
76 : optional function to stop clock at a given time, used by log replay
77 : */
78 0 : virtual void stop_clock(uint64_t time_usec) {}
79 :
80 : virtual bool in_main_thread() const = 0;
81 :
82 : /*
83 : disable interrupts and return a context that can be used to
84 : restore the interrupt state. This can be used to protect
85 : critical regions
86 :
87 : Warning: may not be implemented on all HALs
88 : */
89 0 : virtual void *disable_interrupts_save(void) { return nullptr; }
90 :
91 : /*
92 : restore interrupt state from disable_interrupts_save()
93 : */
94 0 : virtual void restore_interrupts(void *) {}
95 :
96 : // called by subclasses when they need to delay for some time
97 : virtual void call_delay_cb();
98 : uint16_t _min_delay_cb_ms;
99 :
100 : /*
101 : priority_base is used to select what the priority for a new
102 : thread is relative to
103 : */
104 : enum priority_base {
105 : PRIORITY_BOOST,
106 : PRIORITY_MAIN,
107 : PRIORITY_SPI,
108 : PRIORITY_I2C,
109 : PRIORITY_CAN,
110 : PRIORITY_TIMER,
111 : PRIORITY_RCOUT,
112 : PRIORITY_LED,
113 : PRIORITY_RCIN,
114 : PRIORITY_IO,
115 : PRIORITY_UART,
116 : PRIORITY_STORAGE,
117 : PRIORITY_SCRIPTING,
118 : PRIORITY_NET,
119 : };
120 :
121 : /*
122 : create a new thread
123 : */
124 0 : virtual bool thread_create(AP_HAL::MemberProc proc, const char *name,
125 : uint32_t stack_size, priority_base base, int8_t priority) {
126 0 : return false;
127 : }
128 :
129 : private:
130 :
131 : AP_HAL::Proc _delay_cb;
132 : bool _in_delay_callback;
133 :
134 : };
135 :
136 : /*
137 : helper macro and class to make using expect_delay_ms() safer and easier
138 : */
139 : class ExpectDelay {
140 : public:
141 : ExpectDelay(uint32_t ms);
142 : ~ExpectDelay();
143 : };
144 :
145 : #define EXPECT_DELAY_MS(ms) DELAY_JOIN( ms, __COUNTER__ )
146 : #define DELAY_JOIN( ms, counter) _DO_DELAY_JOIN( ms, counter )
147 : #define _DO_DELAY_JOIN( ms, counter ) ExpectDelay _getdelay ## counter(ms)
148 :
149 :
150 : /*
151 : TIME_CHECK() can be used to unexpected detect long delays. Scatter
152 : them in likely places and any long delays will be printed
153 : */
154 :
155 : class TimeCheck {
156 : public:
157 : TimeCheck(uint32_t limit_ms, const char *file, uint32_t line);
158 : ~TimeCheck();
159 : private:
160 : const uint32_t limit_ms;
161 : const uint32_t line;
162 : const char *file;
163 : uint32_t start_ms;
164 : };
165 :
166 : #define TIME_CHECK(limit_ms) JOIN_TC(limit_ms, __FILE__, __LINE__, __COUNTER__ )
167 : #define JOIN_TC(limit_ms, file, line, counter ) _DO_JOIN_TC( limit_ms, file, line, counter )
168 : #define _DO_JOIN_TC(limit_ms, file, line, counter ) TimeCheck _gettc ## counter(limit_ms, file, line)
|