ca13734bf0
Add kernel (Cortex-M0/M3/M4, Tricore, S32K, RISC-V ports), drivers, middleware (CAN stack, diagnostics, safety), applications, board support, build/test tooling, and documentation.
215 lines
4.9 KiB
C
215 lines
4.9 KiB
C
/**
|
|
* @file test_scheduler.c
|
|
* @brief Unit tests for scheduler
|
|
*/
|
|
|
|
#include "unity.h"
|
|
#include "kernel.h"
|
|
#include "scheduler.h"
|
|
#include "task.h"
|
|
#include <string.h>
|
|
|
|
/* Test task handles */
|
|
static TaskHandle_t test_tasks[10];
|
|
static volatile uint32_t task_execution_count[10];
|
|
static volatile uint32_t task_execution_order[100];
|
|
static volatile uint32_t execution_index = 0;
|
|
|
|
/* Test task functions */
|
|
static void test_task_0(void* params) {
|
|
(void)params;
|
|
while (1) {
|
|
task_execution_count[0]++;
|
|
task_execution_order[execution_index++] = 0;
|
|
kernel_delay(10);
|
|
}
|
|
}
|
|
|
|
static void test_task_1(void* params) {
|
|
(void)params;
|
|
while (1) {
|
|
task_execution_count[1]++;
|
|
task_execution_order[execution_index++] = 1;
|
|
kernel_delay(20);
|
|
}
|
|
}
|
|
|
|
static void test_task_2(void* params) {
|
|
(void)params;
|
|
while (1) {
|
|
task_execution_count[2]++;
|
|
task_execution_order[execution_index++] = 2;
|
|
kernel_delay(50);
|
|
}
|
|
}
|
|
|
|
/* Test Setup */
|
|
void setUp(void) {
|
|
/* Reset test state */
|
|
memset((void*)task_execution_count, 0, sizeof(task_execution_count));
|
|
execution_index = 0;
|
|
|
|
/* Initialize kernel */
|
|
kernel_init();
|
|
}
|
|
|
|
/* Test Teardown */
|
|
void tearDown(void) {
|
|
/* Stop kernel */
|
|
kernel_stop();
|
|
}
|
|
|
|
/* ============================================================================
|
|
* Test Cases
|
|
* ============================================================================ */
|
|
|
|
/**
|
|
* @brief Test scheduler initialization
|
|
*/
|
|
void test_scheduler_init(void) {
|
|
SchedulerConfig_t config = {
|
|
.type = SCHEDULER_PRIORITY_PREEMPTIVE,
|
|
.time_slice_ticks = 10,
|
|
.enable_deadline_monitoring = true
|
|
};
|
|
|
|
scheduler_init(&config);
|
|
|
|
/* Verify scheduler is initialized */
|
|
TEST_ASSERT_NOT_NULL(scheduler_get_current_task());
|
|
}
|
|
|
|
/**
|
|
* @brief Test task creation and scheduling
|
|
*/
|
|
void test_task_creation(void) {
|
|
TaskConfig_t config = {
|
|
.name = "test_task",
|
|
.function = test_task_0,
|
|
.parameters = NULL,
|
|
.stack_size = 1024,
|
|
.priority = 1,
|
|
.period_ticks = 0
|
|
};
|
|
|
|
test_tasks[0] = task_create(&config);
|
|
|
|
TEST_ASSERT_NOT_NULL(test_tasks[0]);
|
|
TEST_ASSERT_EQUAL(1, task_get_priority(test_tasks[0]));
|
|
TEST_ASSERT_EQUAL(TASK_READY, task_get_state(test_tasks[0]));
|
|
}
|
|
|
|
/**
|
|
* @brief Test priority-based scheduling
|
|
*/
|
|
void test_priority_scheduling(void) {
|
|
/* Create tasks with different priorities */
|
|
TaskConfig_t config1 = {
|
|
.name = "high_priority",
|
|
.function = test_task_0,
|
|
.parameters = NULL,
|
|
.stack_size = 1024,
|
|
.priority = 0,
|
|
.period_ticks = 10
|
|
};
|
|
|
|
TaskConfig_t config2 = {
|
|
.name = "low_priority",
|
|
.function = test_task_1,
|
|
.parameters = NULL,
|
|
.stack_size = 1024,
|
|
.priority = 5,
|
|
.period_ticks = 10
|
|
};
|
|
|
|
test_tasks[0] = task_create(&config1);
|
|
test_tasks[1] = task_create(&config2);
|
|
|
|
/* Start kernel */
|
|
kernel_start();
|
|
|
|
/* Let tasks run for 100ms */
|
|
kernel_delay(100);
|
|
|
|
/* High priority task should execute more */
|
|
TEST_ASSERT_GREATER_THAN(task_execution_count[1], task_execution_count[0]);
|
|
}
|
|
|
|
/**
|
|
* @brief Test round-robin scheduling
|
|
*/
|
|
void test_round_robin_scheduling(void) {
|
|
/* Create two tasks with same priority */
|
|
TaskConfig_t config1 = {
|
|
.name = "task_a",
|
|
.function = test_task_0,
|
|
.parameters = NULL,
|
|
.stack_size = 1024,
|
|
.priority = 3,
|
|
.period_ticks = 0
|
|
};
|
|
|
|
TaskConfig_t config2 = {
|
|
.name = "task_b",
|
|
.function = test_task_1,
|
|
.parameters = NULL,
|
|
.stack_size = 1024,
|
|
.priority = 3,
|
|
.period_ticks = 0
|
|
};
|
|
|
|
test_tasks[0] = task_create(&config1);
|
|
test_tasks[1] = task_create(&config2);
|
|
|
|
kernel_start();
|
|
kernel_delay(100);
|
|
|
|
/* Both tasks should execute */
|
|
TEST_ASSERT_GREATER_THAN(0, task_execution_count[0]);
|
|
TEST_ASSERT_GREATER_THAN(0, task_execution_count[1]);
|
|
}
|
|
|
|
/**
|
|
* @brief Test scheduler statistics
|
|
*/
|
|
void test_scheduler_statistics(void) {
|
|
SchedulerStatistics_t stats;
|
|
|
|
scheduler_get_statistics(&stats);
|
|
|
|
TEST_ASSERT_GREATER_THAN(0, stats.context_switches);
|
|
TEST_ASSERT_GREATER_OR_EQUAL(0, stats.preemptions);
|
|
}
|
|
|
|
/**
|
|
* @brief Test scheduler lock/unlock
|
|
*/
|
|
void test_scheduler_lock_unlock(void) {
|
|
/* Lock scheduler */
|
|
scheduler_lock();
|
|
|
|
/* Try to yield */
|
|
scheduler_yield();
|
|
|
|
/* Unlock scheduler */
|
|
scheduler_unlock();
|
|
|
|
TEST_ASSERT_TRUE(true);
|
|
}
|
|
|
|
/* ============================================================================
|
|
* Test Runner
|
|
* ============================================================================ */
|
|
int main(void) {
|
|
UNITY_BEGIN();
|
|
|
|
RUN_TEST(test_scheduler_init);
|
|
RUN_TEST(test_task_creation);
|
|
RUN_TEST(test_priority_scheduling);
|
|
RUN_TEST(test_round_robin_scheduling);
|
|
RUN_TEST(test_scheduler_statistics);
|
|
RUN_TEST(test_scheduler_lock_unlock);
|
|
|
|
return UNITY_END();
|
|
}
|