2. Understanding the working of scheduler
Intro
In first tutorial we saw how to create and use a task. Now we will see how the scheduler works.
As we know, scheduler always executes the highest priority task ready to run and when the current task goes in blocked condition scheduler will look for next highest priority task in ready state.
API Details
=Task Create function
portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask);
Name : xTaskCreate()
Arguments : pvTaskCode : Pointer to the task entry function pcName : A descriptive name for the task. It is a character pointer and is mainly used for debugging. usStackDepth : The stack size of the task in terms of number of variables not the number of bytes pvParameters : void pointer which will be used as the parameter for the task uxPriority : The task priority pvCreatedTask : Used to pass back a handle using which the task can be referenced
Return type : Returns TRUE on successful creation of task and adding it to ready list Returns FALSE otherwise.
Function : It creates a task and adds it to ready list.
Task Delay Function
void vTaskDelay( portTickType xTicksToDelay )
Name : vTaskDelay()
Arguments : Number of ticks for which task is to be delayed.
Return type : None
Function : It delays the calling task for specified number of ticks.
Set the macro INCLUDE_vTaskDelay to use this API.
Use the constant portTICK_RATE_MS in the file portmacro.h to calculate real time delay. Its resolution is one tick period.
Code
/* Scheduler include files */ #include "FreeRtOSConfig.h" #include "FreeRTOS.h" #include "task.h" #include "croutine.h" #include "uart.h" // Explore Embedded UART library /* Local Tasks declaration */ static void MyTask1(void* pvParameters); static void MyTask2(void* pvParameters); static void MyTask3(void* pvParameters); static void MyIdleTask(void* pvParameters); #define LED_IdleTask 0x01u #define LED_Task1 0x02u #define LED_Task2 0x04u #define LED_Task3 0x08u #define LED_Task4 0x10u #define LED_PORT LPC_GPIO2->FIOPIN int main(void) { /* Initialize the Uart module */ LPC_GPIO2->FIODIR = 0xffffffffu; SystemInit(); UART_Init(38400); /* Create the three tasks with priorities 1,2,3. Only tasks will be created. */ xTaskCreate( MyTask1, ( signed char * )"Task1", configMINIMAL_STACK_SIZE, NULL, 1, NULL ); xTaskCreate( MyTask2, ( signed char * )"Task2", configMINIMAL_STACK_SIZE, NULL, 2, NULL ); xTaskCreate( MyTask3, ( signed char * )"Task3", configMINIMAL_STACK_SIZE, NULL, 3, NULL ); xTaskCreate( MyIdleTask, ( signed char * )"IdleTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); UART_Printf("\n\rIn the main"); vTaskStartScheduler(); /* Start the schedular */ while(1); } static void MyTask1(void* pvParameters) /* Task1 with priority 1 */ { while(1) { LED_PORT = LED_Task1; /* Led to indicate the execution of Task1*/ UART_Printf("\n\rTask1"); vTaskDelay(100); } } static void MyTask2(void* pvParameters) /* Task1 with priority 2 */ { while(1) { LED_PORT = LED_Task2; /* Led to indicate the execution of Task2*/ UART_Printf("\n\rTask2"); vTaskDelay(250); } } static void MyTask3(void* pvParameters) /* Task1 with priority 3 */ { while(1) { LED_PORT = LED_Task3; /* Led to indicate the execution of Task3*/ UART_Printf("\n\rTask3"); vTaskDelay(600); } } static void MyIdleTask(void* pvParameters) /* Task1 with priority 4 */ { while(1) { LED_PORT = LED_IdleTask; /* Led to indicate the execution of Idle Task*/ UART_Printf("\n\rIn idle state"); } }