Dedicated task for GPS Rescue (#11972)
[betaflight.git] / src / main / scheduler / scheduler.h
blob037750ee43c0b2dd023591694b6db13c36f1603f
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #pragma once
23 #include "common/time.h"
24 #include "config/config.h"
25 #include "pg/scheduler.h"
27 #define TASK_PERIOD_HZ(hz) (1000000 / (hz))
28 #define TASK_PERIOD_MS(ms) ((ms) * 1000)
29 #define TASK_PERIOD_US(us) (us)
31 #define TASK_STATS_MOVING_SUM_COUNT 8
33 #define LOAD_PERCENTAGE_ONE 100
35 #define SCHED_TASK_DEFER_MASK 0x07 // Scheduler loop count is masked with this and when 0 long running tasks are processed
37 #define SCHED_START_LOOP_MIN_US 1 // Wait at start of scheduler loop if gyroTask is nearly due
38 #define SCHED_START_LOOP_MAX_US 12
39 #define SCHED_START_LOOP_DOWN_STEP 50 // Fraction of a us to reduce start loop wait
40 #define SCHED_START_LOOP_UP_STEP 1 // Fraction of a us to increase start loop wait
42 #define TASK_GUARD_MARGIN_MIN_US 3 // Add an amount to the estimate of a task duration
43 #define TASK_GUARD_MARGIN_MAX_US 6
44 #define TASK_GUARD_MARGIN_DOWN_STEP 50 // Fraction of a us to reduce task guard margin
45 #define TASK_GUARD_MARGIN_UP_STEP 1 // Fraction of a us to increase task guard margin
47 #define CHECK_GUARD_MARGIN_US 2 // Add a margin to the amount of time allowed for a check function to run
49 // Some tasks have occasional peaks in execution time so normal moving average duration estimation doesn't work
50 // Decay the estimated max task duration by 1/(1 << TASK_EXEC_TIME_SHIFT) on every invocation
51 #define TASK_EXEC_TIME_SHIFT 7
53 #define TASK_AGE_EXPEDITE_RX schedulerConfig()->rxRelaxDeterminism // Make RX tasks more schedulable if it's failed to be scheduled this many times
54 #define TASK_AGE_EXPEDITE_OSD schedulerConfig()->osdRelaxDeterminism // Make OSD tasks more schedulable if it's failed to be scheduled this many times
55 #define TASK_AGE_EXPEDITE_COUNT 1 // Make aged tasks more schedulable
56 #define TASK_AGE_EXPEDITE_SCALE 0.9 // By scaling their expected execution time
58 // Gyro interrupt counts over which to measure loop time and skew
59 #define GYRO_RATE_COUNT 25000
60 #define GYRO_LOCK_COUNT 50
62 typedef enum {
63 TASK_PRIORITY_REALTIME = -1, // Task will be run outside the scheduler logic
64 TASK_PRIORITY_LOWEST = 1,
65 TASK_PRIORITY_LOW = 2,
66 TASK_PRIORITY_MEDIUM = 3,
67 TASK_PRIORITY_MEDIUM_HIGH = 4,
68 TASK_PRIORITY_HIGH = 5,
69 TASK_PRIORITY_MAX = 255
70 } taskPriority_e;
72 typedef struct {
73 timeUs_t maxExecutionTimeUs;
74 timeUs_t totalExecutionTimeUs;
75 timeUs_t averageExecutionTimeUs;
76 timeUs_t averageDeltaTimeUs;
77 } cfCheckFuncInfo_t;
79 typedef struct {
80 const char * taskName;
81 const char * subTaskName;
82 bool isEnabled;
83 int8_t staticPriority;
84 timeDelta_t desiredPeriodUs;
85 timeDelta_t latestDeltaTimeUs;
86 timeUs_t maxExecutionTimeUs;
87 timeUs_t totalExecutionTimeUs;
88 timeUs_t averageExecutionTime10thUs;
89 timeUs_t averageDeltaTime10thUs;
90 float movingAverageCycleTimeUs;
91 #if defined(USE_LATE_TASK_STATISTICS)
92 uint32_t runCount;
93 uint32_t lateCount;
94 timeUs_t execTime;
95 #endif
96 } taskInfo_t;
98 typedef enum {
99 /* Actual tasks */
100 TASK_SYSTEM = 0,
101 TASK_MAIN,
102 TASK_GYRO,
103 TASK_FILTER,
104 TASK_PID,
105 TASK_ACCEL,
106 TASK_ATTITUDE,
107 TASK_RX,
108 TASK_SERIAL,
109 TASK_DISPATCH,
110 TASK_BATTERY_VOLTAGE,
111 TASK_BATTERY_CURRENT,
112 TASK_BATTERY_ALERTS,
113 #ifdef USE_BEEPER
114 TASK_BEEPER,
115 #endif
116 #ifdef USE_GPS
117 TASK_GPS,
118 #endif
119 #ifdef USE_GPS_RESCUE
120 TASK_GPS_RESCUE,
121 #endif
122 #ifdef USE_MAG
123 TASK_COMPASS,
124 #endif
125 #ifdef USE_BARO
126 TASK_BARO,
127 #endif
128 #ifdef USE_RANGEFINDER
129 TASK_RANGEFINDER,
130 #endif
131 #if defined(USE_BARO) || defined(USE_GPS)
132 TASK_ALTITUDE,
133 #endif
134 #ifdef USE_DASHBOARD
135 TASK_DASHBOARD,
136 #endif
137 #ifdef USE_TELEMETRY
138 TASK_TELEMETRY,
139 #endif
140 #ifdef USE_LED_STRIP
141 TASK_LEDSTRIP,
142 #endif
143 #ifdef USE_TRANSPONDER
144 TASK_TRANSPONDER,
145 #endif
146 #ifdef USE_STACK_CHECK
147 TASK_STACK_CHECK,
148 #endif
149 #ifdef USE_OSD
150 TASK_OSD,
151 #endif
152 #ifdef USE_BST
153 TASK_BST_MASTER_PROCESS,
154 #endif
155 #ifdef USE_ESC_SENSOR
156 TASK_ESC_SENSOR,
157 #endif
158 #ifdef USE_CMS
159 TASK_CMS,
160 #endif
161 #ifdef USE_VTX_CONTROL
162 TASK_VTXCTRL,
163 #endif
164 #ifdef USE_CAMERA_CONTROL
165 TASK_CAMCTRL,
166 #endif
167 #ifdef USE_RCDEVICE
168 TASK_RCDEVICE,
169 #endif
170 #ifdef USE_ADC_INTERNAL
171 TASK_ADC_INTERNAL,
172 #endif
173 #ifdef USE_PINIOBOX
174 TASK_PINIOBOX,
175 #endif
176 #ifdef USE_CRSF_V3
177 TASK_SPEED_NEGOTIATION,
178 #endif
180 /* Count of real tasks */
181 TASK_COUNT,
183 /* Service task IDs */
184 TASK_NONE = TASK_COUNT,
185 TASK_SELF
186 } taskId_e;
188 typedef struct {
189 // Configuration
190 const char * taskName;
191 const char * subTaskName;
192 bool (*checkFunc)(timeUs_t currentTimeUs, timeDelta_t currentDeltaTimeUs);
193 void (*taskFunc)(timeUs_t currentTimeUs);
194 timeDelta_t desiredPeriodUs; // target period of execution
195 const int8_t staticPriority; // dynamicPriority grows in steps of this size
196 } task_attribute_t;
198 typedef struct {
199 // Task static data
200 task_attribute_t *attribute;
202 // Scheduling
203 uint16_t dynamicPriority; // measurement of how old task was last executed, used to avoid task starvation
204 uint16_t taskAgePeriods;
205 timeDelta_t taskLatestDeltaTimeUs;
206 timeUs_t lastExecutedAtUs; // last time of invocation
207 timeUs_t lastSignaledAtUs; // time of invocation event for event-driven tasks
208 timeUs_t lastDesiredAt; // time of last desired execution
210 // Statistics
211 float movingAverageCycleTimeUs;
212 timeUs_t anticipatedExecutionTime; // Fixed point expectation of next execution time
213 timeUs_t movingSumDeltaTime10thUs; // moving sum over 64 samples
214 timeUs_t movingSumExecutionTime10thUs;
215 timeUs_t maxExecutionTimeUs;
216 timeUs_t totalExecutionTimeUs; // total time consumed by task since boot
217 timeUs_t lastStatsAtUs; // time of last stats gathering for rate calculation
218 #if defined(USE_LATE_TASK_STATISTICS)
219 uint32_t runCount;
220 uint32_t lateCount;
221 timeUs_t execTime;
222 #endif
223 } task_t;
225 void getCheckFuncInfo(cfCheckFuncInfo_t *checkFuncInfo);
226 void getTaskInfo(taskId_e taskId, taskInfo_t *taskInfo);
227 void rescheduleTask(taskId_e taskId, timeDelta_t newPeriodUs);
228 void setTaskEnabled(taskId_e taskId, bool newEnabledState);
229 timeDelta_t getTaskDeltaTimeUs(taskId_e taskId);
230 void schedulerIgnoreTaskStateTime();
231 void schedulerIgnoreTaskExecRate();
232 void schedulerIgnoreTaskExecTime();
233 bool schedulerGetIgnoreTaskExecTime();
234 void schedulerResetTaskStatistics(taskId_e taskId);
235 void schedulerResetTaskMaxExecutionTime(taskId_e taskId);
236 void schedulerResetCheckFunctionMaxExecutionTime(void);
237 void schedulerSetNextStateTime(timeDelta_t nextStateTime);
238 timeDelta_t schedulerGetNextStateTime(void);
239 void schedulerInit(void);
240 void scheduler(void);
241 timeUs_t schedulerExecuteTask(task_t *selectedTask, timeUs_t currentTimeUs);
242 void taskSystemLoad(timeUs_t currentTimeUs);
243 void schedulerEnableGyro(void);
244 uint16_t getAverageSystemLoadPercent(void);
245 float schedulerGetCycleTimeMultiplier(void);