Let’s get some facts about FreeRTOS tasks before attempting to create one. A task has four states it can be in: Running, Ready, Blocked or Suspended state. So a task is running if it’s been allocated time and is executing in the CPU. A task is ready if it is not running, simply because there is another task running in the CPU and its waiting its turn, kinda. A task is blocked if it’s waiting for an external event or it’s called the delay function. It’s worth noting that a blocked task usually has a timeout after which it will enter the ready state whether the external event already happened or not. And finally a task is in suspended state if it calls the function to suspend itself, vTaskSuspend(NULL) or another task calls that function passing the task’s handle, vTaskSuspend(xTaskHandle). A task will only come out of the suspended state if there is a call to the vTaskSuspend( xTaskHandle ) function passing the task’s handle, xTaskHandle.
Each task also has a priority which can have a value from 0 upto (configMAX_PRIORITIES -1). For now lets assume this maximum priority value is 32. You can read up on the details of what determines this maximum value in the docs.
To create a task, we will need to decide the priority we need to assign it. The priority number denotes the urgency of running the task in the the CPU. The bigger the number, the higher the priority. The system has what is called the idle task with priority 0. We will talk more about it later, but for now we can base our tasks’ priorities on the idle task’s priority, tskIDLE_PRIORITY. Priorities make sense if you have multiple tasks in the system, so we will create two tasks. One task to print “hello” and the other one to print “world” to the standard output. We will assign both tasks priority 1 and test, then change the priorities to see what happens.
We need to understand the FreeRTOS API functions necessary to create a task and schedule it.
Writing code for a task
Tasks in FreeRTOS are created to execute C functions with infinite loops in them. In C, we declare a function in a .h file, define it in a .c file and then you call it in the main method. Similarly, we need to declare and define a task before we can create it.
The process of a task goes something like:
So for our hello task will have have the following code in the .h and .c files.