Move telemetry displayport init and cms device registering
[betaflight.git] / src / test / unit / scheduler_unittest.cc
blob1192c89bb3291e884714d3a49a37b25a94e9ddcd
1 /*
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/>.
18 #include <stdint.h>
20 extern "C" {
21 #include "platform.h"
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))
44 extern "C" {
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;
55 int16_t debug[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) {
81 taskGyroRan = false;
82 taskFilterRan = false;
83 taskPidRan = false;
84 taskFilterReady = false;
85 taskPidReady = 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_t tasks[TASK_COUNT] = {
99 [TASK_SYSTEM] = {
100 .taskName = "SYSTEM",
101 .taskFunc = taskSystemLoad,
102 .desiredPeriodUs = TASK_PERIOD_HZ(10),
103 .staticPriority = TASK_PRIORITY_MEDIUM_HIGH,
105 [TASK_GYRO] = {
106 .taskName = "GYRO",
107 .taskFunc = taskGyroSample,
108 .desiredPeriodUs = TASK_PERIOD_HZ(TEST_GYRO_SAMPLE_HZ),
109 .staticPriority = TASK_PRIORITY_REALTIME,
111 [TASK_FILTER] = {
112 .taskName = "FILTER",
113 .taskFunc = taskFiltering,
114 .desiredPeriodUs = TASK_PERIOD_HZ(4000),
115 .staticPriority = TASK_PRIORITY_REALTIME,
117 [TASK_PID] = {
118 .taskName = "PID",
119 .taskFunc = taskMainPidLoop,
120 .desiredPeriodUs = TASK_PERIOD_HZ(4000),
121 .staticPriority = TASK_PRIORITY_REALTIME,
123 [TASK_ACCEL] = {
124 .taskName = "ACCEL",
125 .taskFunc = taskUpdateAccelerometer,
126 .desiredPeriodUs = TASK_PERIOD_HZ(1000),
127 .staticPriority = TASK_PRIORITY_MEDIUM,
129 [TASK_ATTITUDE] = {
130 .taskName = "ATTITUDE",
131 .taskFunc = imuUpdateAttitude,
132 .desiredPeriodUs = TASK_PERIOD_HZ(100),
133 .staticPriority = TASK_PRIORITY_MEDIUM,
135 [TASK_RX] = {
136 .taskName = "RX",
137 .checkFunc = rxUpdateCheck,
138 .taskFunc = taskUpdateRxMain,
139 .desiredPeriodUs = TASK_PERIOD_HZ(50),
140 .staticPriority = TASK_PRIORITY_HIGH,
142 [TASK_SERIAL] = {
143 .taskName = "SERIAL",
144 .taskFunc = taskHandleSerial,
145 .desiredPeriodUs = TASK_PERIOD_HZ(100),
146 .staticPriority = TASK_PRIORITY_LOW,
148 [TASK_DISPATCH] = {
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 *getTask(unsigned taskId)
164 return &tasks[taskId];
168 TEST(SchedulerUnittest, TestPriorites)
170 EXPECT_EQ(TASK_PRIORITY_MEDIUM_HIGH, tasks[TASK_SYSTEM].staticPriority);
171 EXPECT_EQ(TASK_PRIORITY_REALTIME, tasks[TASK_GYRO].staticPriority);
172 EXPECT_EQ(TASK_PRIORITY_MEDIUM, tasks[TASK_ACCEL].staticPriority);
173 EXPECT_EQ(TASK_PRIORITY_LOW, tasks[TASK_SERIAL].staticPriority);
174 EXPECT_EQ(TASK_PRIORITY_MEDIUM, tasks[TASK_BATTERY_VOLTAGE].staticPriority);
177 TEST(SchedulerUnittest, TestQueueInit)
179 queueClear();
180 EXPECT_EQ(0, taskQueueSize);
181 EXPECT_EQ(0, queueFirst());
182 EXPECT_EQ(0, queueNext());
183 for (int ii = 0; ii <= TASK_COUNT; ++ii) {
184 EXPECT_EQ(0, taskQueueArray[ii]);
188 task_t *deadBeefPtr = reinterpret_cast<task_t*>(0xDEADBEEF);
190 TEST(SchedulerUnittest, TestQueue)
192 queueClear();
193 taskQueueArray[TASK_COUNT + 1] = deadBeefPtr;
195 queueAdd(&tasks[TASK_SYSTEM]); // TASK_PRIORITY_MEDIUM_HIGH
196 EXPECT_EQ(1, taskQueueSize);
197 EXPECT_EQ(&tasks[TASK_SYSTEM], queueFirst());
198 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
200 queueAdd(&tasks[TASK_SERIAL]); // TASK_PRIORITY_LOW
201 EXPECT_EQ(2, taskQueueSize);
202 EXPECT_EQ(&tasks[TASK_SYSTEM], queueFirst());
203 EXPECT_EQ(&tasks[TASK_SERIAL], queueNext());
204 EXPECT_EQ(NULL, queueNext());
205 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
207 queueAdd(&tasks[TASK_BATTERY_VOLTAGE]); // TASK_PRIORITY_MEDIUM
208 EXPECT_EQ(3, taskQueueSize);
209 EXPECT_EQ(&tasks[TASK_SYSTEM], queueFirst());
210 EXPECT_EQ(&tasks[TASK_BATTERY_VOLTAGE], queueNext());
211 EXPECT_EQ(&tasks[TASK_SERIAL], queueNext());
212 EXPECT_EQ(NULL, queueNext());
213 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
215 queueAdd(&tasks[TASK_RX]); // TASK_PRIORITY_HIGH
216 EXPECT_EQ(4, taskQueueSize);
217 EXPECT_EQ(&tasks[TASK_RX], queueFirst());
218 EXPECT_EQ(&tasks[TASK_SYSTEM], queueNext());
219 EXPECT_EQ(&tasks[TASK_BATTERY_VOLTAGE], queueNext());
220 EXPECT_EQ(&tasks[TASK_SERIAL], queueNext());
221 EXPECT_EQ(NULL, queueNext());
222 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
224 queueRemove(&tasks[TASK_SYSTEM]); // TASK_PRIORITY_HIGH
225 EXPECT_EQ(3, taskQueueSize);
226 EXPECT_EQ(&tasks[TASK_RX], queueFirst());
227 EXPECT_EQ(&tasks[TASK_BATTERY_VOLTAGE], queueNext());
228 EXPECT_EQ(&tasks[TASK_SERIAL], queueNext());
229 EXPECT_EQ(NULL, queueNext());
230 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
233 TEST(SchedulerUnittest, TestQueueAddAndRemove)
235 queueClear();
236 taskQueueArray[TASK_COUNT + 1] = deadBeefPtr;
238 // fill up the queue
239 for (int taskId = 0; taskId < TASK_COUNT; ++taskId) {
240 const bool added = queueAdd(&tasks[taskId]);
241 EXPECT_TRUE(added);
242 EXPECT_EQ(taskId + 1, taskQueueSize);
243 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
246 // double check end of queue
247 EXPECT_EQ(TASK_COUNT, taskQueueSize);
248 EXPECT_NE(static_cast<task_t*>(0), taskQueueArray[TASK_COUNT - 1]); // last item was indeed added to queue
249 EXPECT_EQ(NULL, taskQueueArray[TASK_COUNT]); // null pointer at end of queue is preserved
250 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]); // there hasn't been an out by one error
252 // and empty it again
253 for (int taskId = 0; taskId < TASK_COUNT; ++taskId) {
254 const bool removed = queueRemove(&tasks[taskId]);
255 EXPECT_TRUE(removed);
256 EXPECT_EQ(TASK_COUNT - taskId - 1, taskQueueSize);
257 EXPECT_EQ(NULL, taskQueueArray[TASK_COUNT - taskId]);
258 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]);
261 // double check size and end of queue
262 EXPECT_EQ(0, taskQueueSize); // queue is indeed empty
263 EXPECT_EQ(NULL, taskQueueArray[0]); // there is a null pointer at the end of the queueu
264 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT + 1]); // no accidental overwrites past end of queue
267 TEST(SchedulerUnittest, TestQueueArray)
269 // test there are no "out by one" errors or buffer overruns when items are added and removed
270 queueClear();
271 taskQueueArray[TASK_COUNT_UNITTEST + 1] = deadBeefPtr; // note, must set deadBeefPtr after queueClear
273 unsigned enqueuedTasks = 0;
274 EXPECT_EQ(enqueuedTasks, taskQueueSize);
276 for (int taskId = 0; taskId < TASK_COUNT_UNITTEST - 1; ++taskId) {
277 if (tasks[taskId].taskFunc) {
278 setTaskEnabled(static_cast<taskId_e>(taskId), true);
279 enqueuedTasks++;
280 EXPECT_EQ(enqueuedTasks, taskQueueSize);
281 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT_UNITTEST + 1]);
285 EXPECT_NE(static_cast<task_t*>(0), taskQueueArray[enqueuedTasks - 1]);
286 const task_t *lastTaskPrev = taskQueueArray[enqueuedTasks - 1];
287 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks]);
288 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks + 1]);
289 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT_UNITTEST + 1]);
291 setTaskEnabled(TASK_SYSTEM, false);
292 EXPECT_EQ(enqueuedTasks - 1, taskQueueSize);
293 EXPECT_EQ(lastTaskPrev, taskQueueArray[enqueuedTasks - 2]);
294 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks - 1]); // NULL at end of queue
295 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks]);
296 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks + 1]);
297 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT_UNITTEST + 1]);
299 taskQueueArray[enqueuedTasks - 1] = 0;
300 setTaskEnabled(TASK_SYSTEM, true);
301 EXPECT_EQ(enqueuedTasks, taskQueueSize);
302 EXPECT_EQ(lastTaskPrev, taskQueueArray[enqueuedTasks - 1]);
303 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks]);
304 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks + 1]);
305 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT_UNITTEST + 1]);
307 taskInfo_t taskInfo;
308 getTaskInfo(static_cast<taskId_e>(enqueuedTasks + 1), &taskInfo);
309 EXPECT_FALSE(taskInfo.isEnabled);
310 setTaskEnabled(static_cast<taskId_e>(enqueuedTasks), true);
311 EXPECT_EQ(enqueuedTasks, taskQueueSize);
312 EXPECT_EQ(lastTaskPrev, taskQueueArray[enqueuedTasks - 1]);
313 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks + 1]); // check no buffer overrun
314 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT_UNITTEST + 1]);
316 setTaskEnabled(TASK_SYSTEM, false);
317 EXPECT_EQ(enqueuedTasks - 1, taskQueueSize);
318 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks]);
319 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks + 1]);
320 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT_UNITTEST + 1]);
322 setTaskEnabled(TASK_ACCEL, false);
323 EXPECT_EQ(enqueuedTasks - 2, taskQueueSize);
324 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks - 1]);
325 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks]);
326 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks + 1]);
327 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT_UNITTEST + 1]);
329 setTaskEnabled(TASK_BATTERY_VOLTAGE, false);
330 EXPECT_EQ(enqueuedTasks - 2, taskQueueSize);
331 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks - 2]);
332 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks - 1]);
333 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks]);
334 EXPECT_EQ(NULL, taskQueueArray[enqueuedTasks + 1]);
335 EXPECT_EQ(deadBeefPtr, taskQueueArray[TASK_COUNT_UNITTEST + 1]);
338 TEST(SchedulerUnittest, TestSchedulerInit)
340 schedulerInit();
341 EXPECT_EQ(1, taskQueueSize);
342 EXPECT_EQ(&tasks[TASK_SYSTEM], queueFirst());
345 TEST(SchedulerUnittest, TestScheduleEmptyQueue)
347 queueClear();
348 simulatedTime = 4000;
349 // run the with an empty queue
350 scheduler();
351 EXPECT_EQ(NULL, unittest_scheduler_selectedTask);
354 TEST(SchedulerUnittest, TestSingleTask)
356 schedulerInit();
357 // disable all tasks except TASK_ACCEL
358 for (int taskId = 0; taskId < TASK_COUNT; ++taskId) {
359 setTaskEnabled(static_cast<taskId_e>(taskId), false);
361 setTaskEnabled(TASK_ACCEL, true);
362 tasks[TASK_ACCEL].lastExecutedAtUs = 1000;
363 tasks[TASK_ACCEL].lastStatsAtUs = 1000;
364 simulatedTime = 2050;
365 // run the scheduler and check the task has executed
366 scheduler();
367 EXPECT_NE(unittest_scheduler_selectedTask, static_cast<task_t*>(0));
368 EXPECT_EQ(unittest_scheduler_selectedTask, &tasks[TASK_ACCEL]);
369 EXPECT_EQ(1050, tasks[TASK_ACCEL].taskLatestDeltaTimeUs);
370 EXPECT_EQ(2050, tasks[TASK_ACCEL].lastExecutedAtUs);
371 EXPECT_EQ(TEST_UPDATE_ACCEL_TIME, tasks[TASK_ACCEL].totalExecutionTimeUs);
372 // task has run, so its dynamic priority should have been set to zero
373 EXPECT_EQ(0, tasks[TASK_GYRO].dynamicPriority);
376 TEST(SchedulerUnittest, TestTwoTasks)
378 // disable all tasks except TASK_ACCEL and TASK_ATTITUDE
379 for (int taskId = 0; taskId < TASK_COUNT; ++taskId) {
380 setTaskEnabled(static_cast<taskId_e>(taskId), false);
382 setTaskEnabled(TASK_ACCEL, true);
383 setTaskEnabled(TASK_ATTITUDE, true);
385 // set it up so that TASK_ACCEL ran just before TASK_ATTITUDE
386 static const uint32_t startTime = 4000;
387 simulatedTime = startTime;
388 tasks[TASK_ACCEL].lastExecutedAtUs = simulatedTime;
389 tasks[TASK_ATTITUDE].lastExecutedAtUs = tasks[TASK_ACCEL].lastExecutedAtUs - TEST_UPDATE_ATTITUDE_TIME;
390 EXPECT_EQ(0, tasks[TASK_ATTITUDE].taskAgeCycles);
391 // run the scheduler
392 scheduler();
393 // no tasks should have run, since neither task's desired time has elapsed
394 EXPECT_EQ(static_cast<task_t*>(0), unittest_scheduler_selectedTask);
396 // NOTE:
397 // TASK_ACCEL desiredPeriodUs is 1000 microseconds
398 // TASK_ATTITUDE desiredPeriodUs is 10000 microseconds
399 // 500 microseconds later
400 simulatedTime += 500;
401 // no tasks should run, since neither task's desired time has elapsed
402 scheduler();
403 EXPECT_EQ(static_cast<task_t*>(0), unittest_scheduler_selectedTask);
405 // 500 microseconds later, TASK_ACCEL desiredPeriodUs has elapsed
406 simulatedTime += 500;
407 // TASK_ACCEL should now run
408 scheduler();
409 EXPECT_EQ(&tasks[TASK_ACCEL], unittest_scheduler_selectedTask);
410 EXPECT_EQ(5000 + TEST_UPDATE_ACCEL_TIME, simulatedTime);
412 simulatedTime += 1000 - TEST_UPDATE_ACCEL_TIME;
413 scheduler();
414 // TASK_ACCEL should run again
415 EXPECT_EQ(&tasks[TASK_ACCEL], unittest_scheduler_selectedTask);
417 scheduler();
418 // No task should have run
419 EXPECT_EQ(static_cast<task_t*>(0), unittest_scheduler_selectedTask);
421 simulatedTime = startTime + 10500; // TASK_ACCEL and TASK_ATTITUDE desiredPeriodUss have elapsed
422 // of the two TASK_ACCEL should run first
423 scheduler();
424 EXPECT_EQ(&tasks[TASK_ACCEL], unittest_scheduler_selectedTask);
425 // and finally TASK_ATTITUDE should now run
426 scheduler();
427 EXPECT_EQ(&tasks[TASK_ATTITUDE], unittest_scheduler_selectedTask);
430 TEST(SchedulerUnittest, TestGyroTask)
432 static const uint32_t startTime = 4000;
434 // enable the gyro
435 schedulerEnableGyro();
437 // disable all tasks except TASK_GYRO, TASK_FILTER and TASK_PID
438 for (int taskId = 0; taskId < TASK_COUNT; ++taskId) {
439 setTaskEnabled(static_cast<taskId_e>(taskId), false);
441 setTaskEnabled(TASK_GYRO, true);
442 setTaskEnabled(TASK_FILTER, true);
443 setTaskEnabled(TASK_PID, true);
445 // First set it up so TASK_GYRO just ran
446 simulatedTime = startTime;
447 tasks[TASK_GYRO].lastExecutedAtUs = simulatedTime;
448 // reset the flags
449 resetGyroTaskTestFlags();
451 // run the scheduler
452 scheduler();
453 // no tasks should have run
454 EXPECT_EQ(static_cast<task_t*>(0), unittest_scheduler_selectedTask);
455 // also the gyro, filter and PID task indicators should be false
456 EXPECT_FALSE(taskGyroRan);
457 EXPECT_FALSE(taskFilterRan);
458 EXPECT_FALSE(taskPidRan);
460 /* Test the gyro task running but not triggering the filtering or PID */
461 // set the TASK_GYRO last executed time to be one period earlier
462 simulatedTime = startTime;
463 tasks[TASK_GYRO].lastExecutedAtUs = simulatedTime - TASK_PERIOD_HZ(TEST_GYRO_SAMPLE_HZ);
465 // reset the flags
466 resetGyroTaskTestFlags();
468 // run the scheduler
469 scheduler();
471 // the gyro task indicator should be true and the TASK_FILTER and TASK_PID indicators should be false
472 EXPECT_TRUE(taskGyroRan);
473 EXPECT_FALSE(taskFilterRan);
474 EXPECT_FALSE(taskPidRan);
475 // expect that no other tasks other than TASK_GYRO should have run
476 EXPECT_EQ(static_cast<task_t*>(0), unittest_scheduler_selectedTask);
478 /* Test the gyro task running and triggering the filtering task */
479 // set the TASK_GYRO last executed time to be one period earlier
480 simulatedTime = startTime;
481 tasks[TASK_GYRO].lastExecutedAtUs = simulatedTime - TASK_PERIOD_HZ(TEST_GYRO_SAMPLE_HZ);
483 // reset the flags
484 resetGyroTaskTestFlags();
485 taskFilterReady = true;
487 // run the scheduler
488 scheduler();
489 // the gyro and filter task indicators should be true and TASK_PID indicator should be false
490 EXPECT_TRUE(taskGyroRan);
491 EXPECT_TRUE(taskFilterRan);
492 EXPECT_FALSE(taskPidRan);
493 // expect that no other tasks other tasks should have run
494 EXPECT_EQ(static_cast<task_t*>(0), unittest_scheduler_selectedTask);
496 /* Test the gyro task running and triggering the PID task */
497 // set the TASK_GYRO last executed time to be one period earlier
498 simulatedTime = startTime;
499 tasks[TASK_GYRO].lastExecutedAtUs = simulatedTime - TASK_PERIOD_HZ(TEST_GYRO_SAMPLE_HZ);
501 // reset the flags
502 resetGyroTaskTestFlags();
503 taskPidReady = true;
505 // run the scheduler
506 scheduler();
507 // the gyro and PID task indicators should be true and TASK_FILTER indicator should be false
508 EXPECT_TRUE(taskGyroRan);
509 EXPECT_FALSE(taskFilterRan);
510 EXPECT_TRUE(taskPidRan);
511 // expect that no other tasks other tasks should have run
512 EXPECT_EQ(static_cast<task_t*>(0), unittest_scheduler_selectedTask);