Since we use FreeRTOS, you’ll see it mentioned frequently throughout this document. However, the concepts are applicable to all commercial real-time operating systems.
If you find any mistakes or have questions, send a message in Firmware #onboarding on Discord.
A real-time operating system (RTOS) is a piece of software that’s capable of running applications very reliably and within critical time constraints.
Let’s look at the difference between a real-time operating system (like FreeRTOS) and a general-purpose operating system (like Windows).
The main difference is the response time. In an RTOS, programs must run within critical time constraints. For example, imagine having to control a satellite’s orientation based on sensor data. If the calculations are done too late, then the result can be catastrophic, even if the calculations are done eventually. On the flip side, imagine editing a spreadsheet in Microsoft Excel. If there’s a late response, but the sheet is successfully edited, then there’s not much harm done.
In short, an RTOS is responsible for managing hardware resources and running applications (just like a GPOS), but they’re also able to run applications very reliably and with very precise timing.
Task: Tasks are discrete units of work that can be executed independently within a software system and are able to run concurrently with other tasks. When a particular task is ready to run and is selected by the scheduler (we will talk about the scheduler later), the task’s callback function is called. Note this callback function commonly has an infinite loop, but not always. Each task is partly isolated from each other with each task having their own stack (Check out this video if you do not know about the stack: https://www.youtube.com/watch?v=PL31I-Xge5s&list=PLFnDc5Kpka6XulaKLQgvtvWr7caaUVHzs&index=38). On some systems, including FreeRTOS, tasks are also called threads.
Process: A process is an instance of a program. For example, let’s say you wrote a program that runs on Windows. Anytime you run that program, you’re starting a process. You can run multiple instances of that program which creates multiple processes. However, on a single-core system (such as our system), you can only run a single process at a time.
You can run multiple tasks in a single process. The RTOS will deal with switching between these tasks in a way that looks like there are multiple tasks running at the same time. In reality, at any moment in time, only a single task will be running (assuming we’re dealing with a single-core processor).
The graphic below may help visualize this. Note: The order in which the tasks execute depends on the scheduling algorithm being used (discussed in the Scheduling section).
An example of two tasks in FreeRTOS is shown below. In the main
function, we create the tasks. This tells FreeRTOS that these tasks exist and which function implements each task. Now, when FreeRTOS wants to run Task A, it just runs the taskA
function.
Then, we start the scheduler. FreeRTOS will then handle switching between the two tasks.
// Assume required headers are already included
// Declare task handles
TaskHandle_t xHandleA = NULL;
TaskHandle_t xHandleB = NULL;
// Define the task stack size in words
#define STACK_SIZE 256
/* Task to be created. */
void taskA(void * pvParameters)
{
/* Task code goes here. */
}
/* Task to be created. */
void taskB(void * pvParameters)
{
/* Task code goes here. */
}
/* Function that creates a task(s). */
int main(void)
{
BaseType_t xReturnedA, xReturnedB;
/* Create the task, storing the handle. */
xReturnedA = xTaskCreate(
taskA, /* Function that implements the task. */
"NAMEA", /* Text name for the task. */
STACK_SIZE, /* Stack size in words, not bytes. */
( void * ) 1, /* Parameter passed into the task. */
tskIDLE_PRIORITY, /* Priority at which the task is created. */
&xHandleA ); /* Used to pass out the created task's handle. */
xReturnedB = xTaskCreate(
taskB,
"NAMEB",
STACK_SIZE,
( void * ) 1,
tskIDLE_PRIORITY,
&xHandleB );
if( xReturnedA == pdPASS && xReturnedB == pdPASS ) {
/* The tasks were created successfully, so start the scheduler */
vTaskStartScheduler()
}
/* If the tasks were created successfully, this line is never reached */
while (1); /* Enter an infinite loop */
return 0;
}