Scheduling

The scheduler is the part of the Sirius RTOS kernel that determines which task runs. It is a preemptive, priority-based, round-robin scheduler.

Priority-based scheduling

Priority scheduling ensures that only the highest priority tasks in the ready state are executed. This ensures that only the most important tasks in the system are performed.

Round-robin scheduling

When multiple tasks are in the ready state and share the same priority, the Round-Robin algorithm is used to activate the task that has not run for the longest time. This ensures a fair allocation of CPU time for each ready-to-run task.

Tasks are not simply added to the end of the ready-to-run queue (as most current RTOSs do). The scheduler ensures that the task selected to start is the one that has not run for the longest time. For example, when osSleep(25) is executed, the task is blocked for a specified amount of time. It will be resumed when all other ready tasks with the same priority have been executed at least once. In this case, the task will run immediately. This applies to all Sirius RTOS features except task creation and resuming via the osCreateTask and osResumeTask functions. These are designed for special purposes, such as task creation or task renewal after interrupt reception. System configuration determines whether tasks in these instances should be added to the end or the beginning of the ready-to-run task queue. To add to the beginning of the queue, the OS_RESUME_IMMEDIATELY constant should be set to 1; otherwise, it should be set to 0.

Time quanta

Each task can be assigned an individual number of CPU time slices (called time quanta) for each cycle of the Round-Robin algorithm. When several tasks with the same priority are active, every time preemption occurs, the scheduler assigns the task a specified number of CPU time slices. This allows deciding which task should run more often. This feature is available only when the OS_TASK_QUANTUM_FUNC constant is set to 1. It also enables the osSetTaskQuantum and osGetTaskQuantum functions, which allow modifying the number of time quanta assigned to a task.

Yielding task execution

Each task can voluntarily yield its execution to another task by calling the osSleep(0) function. When a running (current) task changes an object's state to signaled, and if any task with a higher priority is waiting for this object, the current task will yield its execution to immediately run the task with the higher priority. In case the described situation occurs in an ISR (after calling the osEnterISR function), the yielding will be delayed until the osLeaveISR function is executed.

System time

Each system operation that depends on a specific time is performed only when the scheduler is called. This applies to wait timeouts, sleeping, and timer objects. By default, the scheduler is called every millisecond; therefore, after calling osSleep for one millisecond, the task may become ready in less than one millisecond.

Time is specified in time units that depend on the AR_TICKS_PER_SECOND constant, which is specific to the used architecture. When port files provided by SpaceShadow are used, it is always set to 1000, corresponding to a one-millisecond interval. In this case, the time passed to each system function is specified in milliseconds.

The system uses the arGetTickCount function to obtain the current system time. It provides the time in time units, counted from system startup. This function often returns a 32-bit value, which allows counting up to 322-1 before rolling over to 0. For a one-millisecond interval, the rollover will occur after approximately 49.7 days. When a rollover occurs, the system may become unstable. This can be avoided by using a 64-bit integer.

Power saving (the idle task)

Whenever the CPU is not in use (all tasks are blocked or waiting for an event), the idle task runs. It executes the arSavePower function, which switches the CPU to power-save mode. The CPU is resumed on every interrupt. The idle task, like other tasks, has its own stack, the size of which is determined by OS_IDLE_STACK_SIZE.

System statistics

The system provides basic information on the CPU load. This feature is only enabled when the OS_GET_SYSTEM_STAT_FUNC or OS_GET_TASK_STAT_FUNC constants are set to 1. They enable the osGetSystemStat or osGetTaskStat functions, which return the total CPU load or the load for each task separately. The OS_STAT_SAMPLE_RATE constant defines the sampling rate for calculating statistics. It is defined in time units, and by default, it is set to 100 time units.

SpaceShadow documentation