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)
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/>.
23 #include "common/time.h"
24 #include "config/config.h"
26 #define TASK_PERIOD_HZ(hz) (1000000 / (hz))
27 #define TASK_PERIOD_MS(ms) ((ms) * 1000)
28 #define TASK_PERIOD_US(us) (us)
30 #define TASK_STATS_MOVING_SUM_COUNT 64
32 #define LOAD_PERCENTAGE_ONE 100
34 #define SCHED_START_LOOP_MIN_US 1 // Wait at start of scheduler loop if gyroTask is nearly due
35 #define SCHED_START_LOOP_MAX_US 12
36 #define SCHED_START_LOOP_DOWN_STEP 50 // Fraction of a us to reduce start loop wait
37 #define SCHED_START_LOOP_UP_STEP 1 // Fraction of a us to increase start loop wait
39 #define TASK_GUARD_MARGIN_MIN_US 3 // Add an amount to the estimate of a task duration
40 #define TASK_GUARD_MARGIN_MAX_US 6
41 #define TASK_GUARD_MARGIN_DOWN_STEP 50 // Fraction of a us to reduce task guard margin
42 #define TASK_GUARD_MARGIN_UP_STEP 1 // Fraction of a us to increase task guard margin
44 #define CHECK_GUARD_MARGIN_US 2 // Add a margin to the amount of time allowed for a check function to run
46 // Some tasks have occasional peaks in execution time so normal moving average duration estimation doesn't work
47 // Decay the estimated max task duration by 1/(1 << TASK_EXEC_TIME_SHIFT) on every invocation
48 #define TASK_EXEC_TIME_SHIFT 7
50 #define TASK_AGE_EXPEDITE_COUNT 1 // Make aged tasks more schedulable
51 #define TASK_AGE_EXPEDITE_SCALE 0.9 // By scaling their expected execution time
53 // Gyro interrupt counts over which to measure loop time and skew
54 #define GYRO_RATE_COUNT 25000
55 #define GYRO_LOCK_COUNT 50
58 TASK_PRIORITY_REALTIME
= -1, // Task will be run outside the scheduler logic
59 TASK_PRIORITY_LOWEST
= 1,
60 TASK_PRIORITY_LOW
= 2,
61 TASK_PRIORITY_MEDIUM
= 3,
62 TASK_PRIORITY_MEDIUM_HIGH
= 4,
63 TASK_PRIORITY_HIGH
= 5,
64 TASK_PRIORITY_MAX
= 255
68 timeUs_t maxExecutionTimeUs
;
69 timeUs_t totalExecutionTimeUs
;
70 timeUs_t averageExecutionTimeUs
;
71 timeUs_t averageDeltaTimeUs
;
75 const char * taskName
;
76 const char * subTaskName
;
78 int8_t staticPriority
;
79 timeDelta_t desiredPeriodUs
;
80 timeDelta_t latestDeltaTimeUs
;
81 timeUs_t maxExecutionTimeUs
;
82 timeUs_t totalExecutionTimeUs
;
83 timeUs_t averageExecutionTimeUs
;
84 timeUs_t averageDeltaTime10thUs
;
85 float movingAverageCycleTimeUs
;
86 #if defined(USE_LATE_TASK_STATISTICS)
105 TASK_BATTERY_VOLTAGE
,
106 TASK_BATTERY_CURRENT
,
120 #ifdef USE_RANGEFINDER
123 #if defined(USE_BARO) || defined(USE_GPS)
135 #ifdef USE_TRANSPONDER
138 #ifdef USE_STACK_CHECK
145 TASK_BST_MASTER_PROCESS
,
147 #ifdef USE_ESC_SENSOR
153 #ifdef USE_VTX_CONTROL
156 #ifdef USE_CAMERA_CONTROL
164 #ifdef USE_ADC_INTERNAL
173 TASK_SPEED_NEGOTIATION
,
176 /* Count of real tasks */
179 /* Service task IDs */
180 TASK_NONE
= TASK_COUNT
,
186 const char * taskName
;
187 const char * subTaskName
;
188 bool (*checkFunc
)(timeUs_t currentTimeUs
, timeDelta_t currentDeltaTimeUs
);
189 void (*taskFunc
)(timeUs_t currentTimeUs
);
190 timeDelta_t desiredPeriodUs
; // target period of execution
191 const int8_t staticPriority
; // dynamicPriority grows in steps of this size
199 uint16_t dynamicPriority
; // measurement of how old task was last executed, used to avoid task starvation
200 uint16_t taskAgeCycles
;
201 timeDelta_t taskLatestDeltaTimeUs
;
202 timeUs_t lastExecutedAtUs
; // last time of invocation
203 timeUs_t lastSignaledAtUs
; // time of invocation event for event-driven tasks
204 timeUs_t lastDesiredAt
; // time of last desired execution
207 float movingAverageCycleTimeUs
;
208 timeUs_t anticipatedExecutionTime
; // Fixed point expectation of next execution time
209 timeUs_t movingSumDeltaTime10thUs
; // moving sum over 64 samples
210 timeUs_t maxExecutionTimeUs
;
211 timeUs_t totalExecutionTimeUs
; // total time consumed by task since boot
212 timeUs_t lastStatsAtUs
; // time of last stats gathering for rate calculation
213 #if defined(USE_LATE_TASK_STATISTICS)
220 void getCheckFuncInfo(cfCheckFuncInfo_t
*checkFuncInfo
);
221 void getTaskInfo(taskId_e taskId
, taskInfo_t
*taskInfo
);
222 void rescheduleTask(taskId_e taskId
, timeDelta_t newPeriodUs
);
223 void setTaskEnabled(taskId_e taskId
, bool newEnabledState
);
224 timeDelta_t
getTaskDeltaTimeUs(taskId_e taskId
);
225 void schedulerIgnoreTaskStateTime();
226 void schedulerIgnoreTaskExecRate();
227 void schedulerIgnoreTaskExecTime();
228 bool schedulerGetIgnoreTaskExecTime();
229 void schedulerResetTaskStatistics(taskId_e taskId
);
230 void schedulerResetTaskMaxExecutionTime(taskId_e taskId
);
231 void schedulerResetCheckFunctionMaxExecutionTime(void);
232 void schedulerSetNextStateTime(timeDelta_t nextStateTime
);
233 void schedulerInit(void);
234 void scheduler(void);
235 timeUs_t
schedulerExecuteTask(task_t
*selectedTask
, timeUs_t currentTimeUs
);
236 void taskSystemLoad(timeUs_t currentTimeUs
);
237 void schedulerEnableGyro(void);
238 uint16_t getAverageSystemLoadPercent(void);
239 float schedulerGetCycleTimeMultiplier(void);