2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
22 #include "scheduler/scheduler.h"
25 #include "unittest_macros.h"
26 #include "gtest/gtest.h"
28 const int TEST_GYRO_SAMPLE_HZ
= 8000;
29 const int TEST_GYRO_SAMPLE_TIME
= 10;
30 const int TEST_FILTERING_TIME
= 40;
31 const int TEST_PID_LOOP_TIME
= 58;
32 const int TEST_UPDATE_ACCEL_TIME
= 32;
33 const int TEST_UPDATE_ATTITUDE_TIME
= 28;
34 const int TEST_HANDLE_SERIAL_TIME
= 30;
35 const int TEST_UPDATE_BATTERY_TIME
= 1;
36 const int TEST_UPDATE_RX_CHECK_TIME
= 34;
37 const int TEST_UPDATE_RX_MAIN_TIME
= 1;
38 const int TEST_IMU_UPDATE_TIME
= 5;
39 const int TEST_DISPATCH_TIME
= 1;
41 #define TASK_COUNT_UNITTEST (TASK_BATTERY_VOLTAGE + 1)
42 #define TASK_PERIOD_HZ(hz) (1000000 / (hz))
45 task_t
* unittest_scheduler_selectedTask
;
46 uint8_t unittest_scheduler_selectedTaskDynPrio
;
47 timeDelta_t unittest_scheduler_taskRequiredTimeUs
;
48 bool taskGyroRan
= false;
49 bool taskFilterRan
= false;
50 bool taskPidRan
= false;
51 bool taskFilterReady
= false;
52 bool taskPidReady
= false;
53 uint8_t activePidLoopDenom
= 1;
56 uint8_t debugMode
= 0;
58 // set up micros() to simulate time
59 uint32_t simulatedTime
= 0;
60 uint32_t micros(void) { return simulatedTime
; }
61 uint32_t clockCyclesToMicros(uint32_t x
) { return x
/10;}
62 int32_t clockCyclesTo10thMicros(int32_t x
) { return x
;}
63 uint32_t clockMicrosToCycles(uint32_t x
) { return x
*10;}
64 uint32_t getCycleCounter(void) {return simulatedTime
* 10;}
66 // set up tasks to take a simulated representative time to execute
67 bool gyroFilterReady(void) { return taskFilterReady
; }
68 bool pidLoopReady(void) { return taskPidReady
; }
69 void taskGyroSample(timeUs_t
) { simulatedTime
+= TEST_GYRO_SAMPLE_TIME
; taskGyroRan
= true; }
70 void taskFiltering(timeUs_t
) { simulatedTime
+= TEST_FILTERING_TIME
; taskFilterRan
= true; }
71 void taskMainPidLoop(timeUs_t
) { simulatedTime
+= TEST_PID_LOOP_TIME
; taskPidRan
= true; }
72 void taskUpdateAccelerometer(timeUs_t
) { simulatedTime
+= TEST_UPDATE_ACCEL_TIME
; }
73 void taskHandleSerial(timeUs_t
) { simulatedTime
+= TEST_HANDLE_SERIAL_TIME
; }
74 void taskUpdateBatteryVoltage(timeUs_t
) { simulatedTime
+= TEST_UPDATE_BATTERY_TIME
; }
75 bool rxUpdateCheck(timeUs_t
, timeDelta_t
) { simulatedTime
+= TEST_UPDATE_RX_CHECK_TIME
; return false; }
76 void taskUpdateRxMain(timeUs_t
) { simulatedTime
+= TEST_UPDATE_RX_MAIN_TIME
; }
77 void imuUpdateAttitude(timeUs_t
) { simulatedTime
+= TEST_IMU_UPDATE_TIME
; }
78 void dispatchProcess(timeUs_t
) { simulatedTime
+= TEST_DISPATCH_TIME
; }
80 void resetGyroTaskTestFlags(void) {
82 taskFilterRan
= false;
84 taskFilterReady
= false;
88 extern int taskQueueSize
;
89 extern task_t
* taskQueueArray
[];
91 extern void queueClear(void);
92 extern bool queueContains(task_t
*task
);
93 extern bool queueAdd(task_t
*task
);
94 extern bool queueRemove(task_t
*task
);
95 extern task_t
*queueFirst(void);
96 extern task_t
*queueNext(void);
98 task_id_t task_ids
[TASK_COUNT
] = {
100 .taskName
= "SYSTEM",
101 .taskFunc
= taskSystemLoad
,
102 .desiredPeriodUs
= TASK_PERIOD_HZ(10),
103 .staticPriority
= TASK_PRIORITY_MEDIUM_HIGH
,
107 .taskFunc
= taskGyroSample
,
108 .desiredPeriodUs
= TASK_PERIOD_HZ(TEST_GYRO_SAMPLE_HZ
),
109 .staticPriority
= TASK_PRIORITY_REALTIME
,
112 .taskName
= "FILTER",
113 .taskFunc
= taskFiltering
,
114 .desiredPeriodUs
= TASK_PERIOD_HZ(4000),
115 .staticPriority
= TASK_PRIORITY_REALTIME
,
119 .taskFunc
= taskMainPidLoop
,
120 .desiredPeriodUs
= TASK_PERIOD_HZ(4000),
121 .staticPriority
= TASK_PRIORITY_REALTIME
,
125 .taskFunc
= taskUpdateAccelerometer
,
126 .desiredPeriodUs
= TASK_PERIOD_HZ(1000),
127 .staticPriority
= TASK_PRIORITY_MEDIUM
,
130 .taskName
= "ATTITUDE",
131 .taskFunc
= imuUpdateAttitude
,
132 .desiredPeriodUs
= TASK_PERIOD_HZ(100),
133 .staticPriority
= TASK_PRIORITY_MEDIUM
,
137 .checkFunc
= rxUpdateCheck
,
138 .taskFunc
= taskUpdateRxMain
,
139 .desiredPeriodUs
= TASK_PERIOD_HZ(50),
140 .staticPriority
= TASK_PRIORITY_HIGH
,
143 .taskName
= "SERIAL",
144 .taskFunc
= taskHandleSerial
,
145 .desiredPeriodUs
= TASK_PERIOD_HZ(100),
146 .staticPriority
= TASK_PRIORITY_LOW
,
149 .taskName
= "DISPATCH",
150 .taskFunc
= dispatchProcess
,
151 .desiredPeriodUs
= TASK_PERIOD_HZ(1000),
152 .staticPriority
= TASK_PRIORITY_HIGH
,
154 [TASK_BATTERY_VOLTAGE
] = {
155 .taskName
= "BATTERY_VOLTAGE",
156 .taskFunc
= taskUpdateBatteryVoltage
,
157 .desiredPeriodUs
= TASK_PERIOD_HZ(50),
158 .staticPriority
= TASK_PRIORITY_MEDIUM
,
162 task_t tasks
[TASK_COUNT
];
164 task_t
*getTask(unsigned taskId
)
166 return &tasks
[taskId
];
170 TEST(SchedulerUnittest
, SetupTasks
)
172 for (int i
= 0; i
< TASK_COUNT
; ++i
) {
173 tasks
[i
].id
= &task_ids
[i
];
178 TEST(SchedulerUnittest
, TestPriorites
)
180 EXPECT_EQ(TASK_PRIORITY_MEDIUM_HIGH
, tasks
[TASK_SYSTEM
].id
->staticPriority
);
181 EXPECT_EQ(TASK_PRIORITY_REALTIME
, tasks
[TASK_GYRO
].id
->staticPriority
);
182 EXPECT_EQ(TASK_PRIORITY_MEDIUM
, tasks
[TASK_ACCEL
].id
->staticPriority
);
183 EXPECT_EQ(TASK_PRIORITY_LOW
, tasks
[TASK_SERIAL
].id
->staticPriority
);
184 EXPECT_EQ(TASK_PRIORITY_MEDIUM
, tasks
[TASK_BATTERY_VOLTAGE
].id
->staticPriority
);
187 TEST(SchedulerUnittest
, TestQueueInit
)
190 EXPECT_EQ(0, taskQueueSize
);
191 EXPECT_EQ(0, queueFirst());
192 EXPECT_EQ(0, queueNext());
193 for (int ii
= 0; ii
<= TASK_COUNT
; ++ii
) {
194 EXPECT_EQ(0, taskQueueArray
[ii
]);
198 task_t
*deadBeefPtr
= reinterpret_cast<task_t
*>(0xDEADBEEF);
200 TEST(SchedulerUnittest
, TestQueue
)
203 taskQueueArray
[TASK_COUNT
+ 1] = deadBeefPtr
;
205 queueAdd(&tasks
[TASK_SYSTEM
]); // TASK_PRIORITY_MEDIUM_HIGH
206 EXPECT_EQ(1, taskQueueSize
);
207 EXPECT_EQ(&tasks
[TASK_SYSTEM
], queueFirst());
208 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT
+ 1]);
210 queueAdd(&tasks
[TASK_SERIAL
]); // TASK_PRIORITY_LOW
211 EXPECT_EQ(2, taskQueueSize
);
212 EXPECT_EQ(&tasks
[TASK_SYSTEM
], queueFirst());
213 EXPECT_EQ(&tasks
[TASK_SERIAL
], queueNext());
214 EXPECT_EQ(NULL
, queueNext());
215 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT
+ 1]);
217 queueAdd(&tasks
[TASK_BATTERY_VOLTAGE
]); // TASK_PRIORITY_MEDIUM
218 EXPECT_EQ(3, taskQueueSize
);
219 EXPECT_EQ(&tasks
[TASK_SYSTEM
], queueFirst());
220 EXPECT_EQ(&tasks
[TASK_BATTERY_VOLTAGE
], queueNext());
221 EXPECT_EQ(&tasks
[TASK_SERIAL
], queueNext());
222 EXPECT_EQ(NULL
, queueNext());
223 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT
+ 1]);
225 queueAdd(&tasks
[TASK_RX
]); // TASK_PRIORITY_HIGH
226 EXPECT_EQ(4, taskQueueSize
);
227 EXPECT_EQ(&tasks
[TASK_RX
], queueFirst());
228 EXPECT_EQ(&tasks
[TASK_SYSTEM
], queueNext());
229 EXPECT_EQ(&tasks
[TASK_BATTERY_VOLTAGE
], queueNext());
230 EXPECT_EQ(&tasks
[TASK_SERIAL
], queueNext());
231 EXPECT_EQ(NULL
, queueNext());
232 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT
+ 1]);
234 queueRemove(&tasks
[TASK_SYSTEM
]); // TASK_PRIORITY_HIGH
235 EXPECT_EQ(3, taskQueueSize
);
236 EXPECT_EQ(&tasks
[TASK_RX
], queueFirst());
237 EXPECT_EQ(&tasks
[TASK_BATTERY_VOLTAGE
], queueNext());
238 EXPECT_EQ(&tasks
[TASK_SERIAL
], queueNext());
239 EXPECT_EQ(NULL
, queueNext());
240 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT
+ 1]);
243 TEST(SchedulerUnittest
, TestQueueAddAndRemove
)
246 taskQueueArray
[TASK_COUNT
+ 1] = deadBeefPtr
;
249 for (int taskId
= 0; taskId
< TASK_COUNT
; ++taskId
) {
250 const bool added
= queueAdd(&tasks
[taskId
]);
252 EXPECT_EQ(taskId
+ 1, taskQueueSize
);
253 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT
+ 1]);
255 // double check end of queue
256 EXPECT_EQ(TASK_COUNT
, taskQueueSize
);
257 EXPECT_NE(static_cast<task_t
*>(0), taskQueueArray
[TASK_COUNT
- 1]); // last item was indeed added to queue
258 EXPECT_EQ(NULL
, taskQueueArray
[TASK_COUNT
]); // null pointer at end of queue is preserved
259 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT
+ 1]); // there hasn't been an out by one error
261 // and empty it again
262 for (int taskId
= 0; taskId
< TASK_COUNT
; ++taskId
) {
263 const bool removed
= queueRemove(&tasks
[taskId
]);
264 EXPECT_TRUE(removed
);
265 EXPECT_EQ(TASK_COUNT
- taskId
- 1, taskQueueSize
);
266 EXPECT_EQ(NULL
, taskQueueArray
[TASK_COUNT
- taskId
]);
267 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT
+ 1]);
270 // double check size and end of queue
271 EXPECT_EQ(0, taskQueueSize
); // queue is indeed empty
272 EXPECT_EQ(NULL
, taskQueueArray
[0]); // there is a null pointer at the end of the queueu
273 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT
+ 1]); // no accidental overwrites past end of queue
276 TEST(SchedulerUnittest
, TestQueueArray
)
278 // test there are no "out by one" errors or buffer overruns when items are added and removed
280 taskQueueArray
[TASK_COUNT_UNITTEST
+ 1] = deadBeefPtr
; // note, must set deadBeefPtr after queueClear
282 unsigned enqueuedTasks
= 0;
283 EXPECT_EQ(enqueuedTasks
, taskQueueSize
);
285 for (int taskId
= 0; taskId
< TASK_COUNT_UNITTEST
- 1; ++taskId
) {
286 if (tasks
[taskId
].id
->taskFunc
) {
287 setTaskEnabled(static_cast<taskId_e
>(taskId
), true);
289 EXPECT_EQ(enqueuedTasks
, taskQueueSize
);
290 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT_UNITTEST
+ 1]);
294 EXPECT_NE(static_cast<task_t
*>(0), taskQueueArray
[enqueuedTasks
- 1]);
295 const task_t
*lastTaskPrev
= taskQueueArray
[enqueuedTasks
- 1];
296 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
]);
297 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
+ 1]);
298 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT_UNITTEST
+ 1]);
300 setTaskEnabled(TASK_SYSTEM
, false);
301 EXPECT_EQ(enqueuedTasks
- 1, taskQueueSize
);
302 EXPECT_EQ(lastTaskPrev
, taskQueueArray
[enqueuedTasks
- 2]);
303 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
- 1]); // NULL at end of queue
304 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
]);
305 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
+ 1]);
306 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT_UNITTEST
+ 1]);
308 taskQueueArray
[enqueuedTasks
- 1] = 0;
309 setTaskEnabled(TASK_SYSTEM
, true);
310 EXPECT_EQ(enqueuedTasks
, taskQueueSize
);
311 EXPECT_EQ(lastTaskPrev
, taskQueueArray
[enqueuedTasks
- 1]);
312 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
]);
313 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
+ 1]);
314 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT_UNITTEST
+ 1]);
317 getTaskInfo(static_cast<taskId_e
>(enqueuedTasks
+ 1), &taskInfo
);
318 EXPECT_FALSE(taskInfo
.isEnabled
);
319 setTaskEnabled(static_cast<taskId_e
>(enqueuedTasks
), true);
320 EXPECT_EQ(enqueuedTasks
, taskQueueSize
);
321 EXPECT_EQ(lastTaskPrev
, taskQueueArray
[enqueuedTasks
- 1]);
322 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
+ 1]); // check no buffer overrun
323 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT_UNITTEST
+ 1]);
325 setTaskEnabled(TASK_SYSTEM
, false);
326 EXPECT_EQ(enqueuedTasks
- 1, taskQueueSize
);
327 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
]);
328 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
+ 1]);
329 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT_UNITTEST
+ 1]);
331 setTaskEnabled(TASK_ACCEL
, false);
332 EXPECT_EQ(enqueuedTasks
- 2, taskQueueSize
);
333 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
- 1]);
334 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
]);
335 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
+ 1]);
336 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT_UNITTEST
+ 1]);
338 setTaskEnabled(TASK_BATTERY_VOLTAGE
, false);
339 EXPECT_EQ(enqueuedTasks
- 2, taskQueueSize
);
340 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
- 2]);
341 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
- 1]);
342 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
]);
343 EXPECT_EQ(NULL
, taskQueueArray
[enqueuedTasks
+ 1]);
344 EXPECT_EQ(deadBeefPtr
, taskQueueArray
[TASK_COUNT_UNITTEST
+ 1]);
347 TEST(SchedulerUnittest
, TestSchedulerInit
)
350 EXPECT_EQ(1, taskQueueSize
);
351 EXPECT_EQ(&tasks
[TASK_SYSTEM
], queueFirst());
354 TEST(SchedulerUnittest
, TestScheduleEmptyQueue
)
357 simulatedTime
= 4000;
358 // run the with an empty queue
360 EXPECT_EQ(NULL
, unittest_scheduler_selectedTask
);
363 TEST(SchedulerUnittest
, TestSingleTask
)
366 // disable all tasks except TASK_ACCEL
367 for (int taskId
= 0; taskId
< TASK_COUNT
; ++taskId
) {
368 setTaskEnabled(static_cast<taskId_e
>(taskId
), false);
370 setTaskEnabled(TASK_ACCEL
, true);
371 tasks
[TASK_ACCEL
].lastExecutedAtUs
= 1000;
372 tasks
[TASK_ACCEL
].lastStatsAtUs
= 1000;
373 simulatedTime
= 2050;
374 // run the scheduler and check the task has executed
376 EXPECT_NE(unittest_scheduler_selectedTask
, static_cast<task_t
*>(0));
377 EXPECT_EQ(unittest_scheduler_selectedTask
, &tasks
[TASK_ACCEL
]);
378 EXPECT_EQ(1050, tasks
[TASK_ACCEL
].taskLatestDeltaTimeUs
);
379 EXPECT_EQ(2050, tasks
[TASK_ACCEL
].lastExecutedAtUs
);
380 EXPECT_EQ(TEST_UPDATE_ACCEL_TIME
, tasks
[TASK_ACCEL
].totalExecutionTimeUs
);
381 // task has run, so its dynamic priority should have been set to zero
382 EXPECT_EQ(0, tasks
[TASK_GYRO
].dynamicPriority
);
385 TEST(SchedulerUnittest
, TestTwoTasks
)
387 // disable all tasks except TASK_ACCEL and TASK_ATTITUDE
388 for (int taskId
= 0; taskId
< TASK_COUNT
; ++taskId
) {
389 setTaskEnabled(static_cast<taskId_e
>(taskId
), false);
391 setTaskEnabled(TASK_ACCEL
, true);
392 setTaskEnabled(TASK_ATTITUDE
, true);
394 // set it up so that TASK_ACCEL ran just before TASK_ATTITUDE
395 static const uint32_t startTime
= 4000;
396 simulatedTime
= startTime
;
397 tasks
[TASK_ACCEL
].lastExecutedAtUs
= simulatedTime
;
398 tasks
[TASK_ATTITUDE
].lastExecutedAtUs
= tasks
[TASK_ACCEL
].lastExecutedAtUs
- TEST_UPDATE_ATTITUDE_TIME
;
399 EXPECT_EQ(0, tasks
[TASK_ATTITUDE
].taskAgeCycles
);
402 // no tasks should have run, since neither task's desired time has elapsed
403 EXPECT_EQ(static_cast<task_t
*>(0), unittest_scheduler_selectedTask
);
406 // TASK_ACCEL desiredPeriodUs is 1000 microseconds
407 // TASK_ATTITUDE desiredPeriodUs is 10000 microseconds
408 // 500 microseconds later
409 simulatedTime
+= 500;
410 // no tasks should run, since neither task's desired time has elapsed
412 EXPECT_EQ(static_cast<task_t
*>(0), unittest_scheduler_selectedTask
);
414 // 500 microseconds later, TASK_ACCEL desiredPeriodUs has elapsed
415 simulatedTime
+= 500;
416 // TASK_ACCEL should now run
418 EXPECT_EQ(&tasks
[TASK_ACCEL
], unittest_scheduler_selectedTask
);
419 EXPECT_EQ(5000 + TEST_UPDATE_ACCEL_TIME
, simulatedTime
);
421 simulatedTime
+= 1000 - TEST_UPDATE_ACCEL_TIME
;
423 // TASK_ACCEL should run again
424 EXPECT_EQ(&tasks
[TASK_ACCEL
], unittest_scheduler_selectedTask
);
427 // No task should have run
428 EXPECT_EQ(static_cast<task_t
*>(0), unittest_scheduler_selectedTask
);
430 simulatedTime
= startTime
+ 10500; // TASK_ACCEL and TASK_ATTITUDE desiredPeriodUss have elapsed
431 // of the two TASK_ACCEL should run first
433 EXPECT_EQ(&tasks
[TASK_ACCEL
], unittest_scheduler_selectedTask
);
434 // and finally TASK_ATTITUDE should now run
436 EXPECT_EQ(&tasks
[TASK_ATTITUDE
], unittest_scheduler_selectedTask
);
439 TEST(SchedulerUnittest
, TestGyroTask
)
441 static const uint32_t startTime
= 4000;
444 schedulerEnableGyro();
446 // disable all tasks except TASK_GYRO, TASK_FILTER and TASK_PID
447 for (int taskId
= 0; taskId
< TASK_COUNT
; ++taskId
) {
448 setTaskEnabled(static_cast<taskId_e
>(taskId
), false);
450 setTaskEnabled(TASK_GYRO
, true);
451 setTaskEnabled(TASK_FILTER
, true);
452 setTaskEnabled(TASK_PID
, true);
454 // First set it up so TASK_GYRO just ran
455 simulatedTime
= startTime
;
456 tasks
[TASK_GYRO
].lastExecutedAtUs
= simulatedTime
;
458 resetGyroTaskTestFlags();
462 // no tasks should have run
463 EXPECT_EQ(static_cast<task_t
*>(0), unittest_scheduler_selectedTask
);
464 // also the gyro, filter and PID task indicators should be false
465 EXPECT_FALSE(taskGyroRan
);
466 EXPECT_FALSE(taskFilterRan
);
467 EXPECT_FALSE(taskPidRan
);
469 /* Test the gyro task running but not triggering the filtering or PID */
470 // set the TASK_GYRO last executed time to be one period earlier
471 simulatedTime
= startTime
;
472 tasks
[TASK_GYRO
].lastExecutedAtUs
= simulatedTime
- TASK_PERIOD_HZ(TEST_GYRO_SAMPLE_HZ
);
475 resetGyroTaskTestFlags();
480 // the gyro task indicator should be true and the TASK_FILTER and TASK_PID indicators should be false
481 EXPECT_TRUE(taskGyroRan
);
482 EXPECT_FALSE(taskFilterRan
);
483 EXPECT_FALSE(taskPidRan
);
484 // expect that no other tasks other than TASK_GYRO should have run
485 EXPECT_EQ(static_cast<task_t
*>(0), unittest_scheduler_selectedTask
);
487 /* Test the gyro task running and triggering the filtering task */
488 // set the TASK_GYRO last executed time to be one period earlier
489 simulatedTime
= startTime
;
490 tasks
[TASK_GYRO
].lastExecutedAtUs
= simulatedTime
- TASK_PERIOD_HZ(TEST_GYRO_SAMPLE_HZ
);
493 resetGyroTaskTestFlags();
494 taskFilterReady
= true;
498 // the gyro and filter task indicators should be true and TASK_PID indicator should be false
499 EXPECT_TRUE(taskGyroRan
);
500 EXPECT_TRUE(taskFilterRan
);
501 EXPECT_FALSE(taskPidRan
);
502 // expect that no other tasks other tasks should have run
503 EXPECT_EQ(static_cast<task_t
*>(0), unittest_scheduler_selectedTask
);
505 /* Test the gyro task running and triggering the PID task */
506 // set the TASK_GYRO last executed time to be one period earlier
507 simulatedTime
= startTime
;
508 tasks
[TASK_GYRO
].lastExecutedAtUs
= simulatedTime
- TASK_PERIOD_HZ(TEST_GYRO_SAMPLE_HZ
);
511 resetGyroTaskTestFlags();
516 // the gyro and PID task indicators should be true and TASK_FILTER indicator should be false
517 EXPECT_TRUE(taskGyroRan
);
518 EXPECT_FALSE(taskFilterRan
);
519 EXPECT_TRUE(taskPidRan
);
520 // expect that no other tasks other tasks should have run
521 EXPECT_EQ(static_cast<task_t
*>(0), unittest_scheduler_selectedTask
);