Task Management 김백규
Task states(1/2) Running currently utilising the processor. Ready tasks are those that are able to execute. they are not blocked or suspended. Blocked it is currently waiting for either a temporal or external event. Suspended state are also not available for scheduling. vTaskSuspend() and xTaskResume() API calls
Task states (2/2)
Task Control Block(1/2) *pxTopOfStack(volatile portSTACK_TYPE) Points to the location of the last item placed on the tasks stack. xGenericListItem(xListItem) List item used to place the TCB in ready and blocked queues. xEventListItem(xListItem) List item used to place the TCB in event lists. uxPriority(unsigned portBASE_TYPE) The priority of the task *pxStack(portSTACK_TYPE) Points to the start of the stack uxTCBNumber(unsigned portBASE_TYPE) used for tracing the scheduler and making debugging easier only pcTaskName[ configMAX_TASK_NAME_LEN ](signed portCHAR) Descriptive name given to the task when created. Facilitates debugging only usStackDepth(unsigned portSHORT) Total depth of the stack (when empty)
Task Control Block(2/2) pxTopofStack (portSTACK_TYPE*) xGenericListItem (xListItem) xEventListItem (xListItem) uxPriority (portBASE_TYPE) pxStack (portSTACK_TYPE) uxTCBNumber (portBASE_TYPE) pcTaskName [ configMAX_TASK_NAME_LEN ] (portCHAR) usStackDepth (portSHORT)
Implementing a Task All task functions should be of this type. Task functions should never return typically implemented as a continuous loop. void vATaskFunction( void *pvParameters ) { for( ;; ) { -- Task application code here. -- }
The Idle Task created automatically when the scheduler is started. is responsible for freeing memory allocated by the RTOS Be careful of using vTaskDelete() to ensure the idle task is not starved of processing time.
The Idle Task Hook What is the Idle Task Hook? a function that is called during each cycle of the idle task. Implement Idle Task Hook (2 options) 1) Implement the functionality in an idle task hook. 2) Create an idle priority task to implement the functionality.
Creating Idle Task Hook(2 nd option) 1. Set configUSE_IDLE_HOOK to 1 within FreeRTOSConfig.h. 2. Define a function that has the following prototype: void vApplicationIdleHook( void );
APIs in FreeRTOS
API - xTaskCreate Create a new task and add it to the list of tasks that are ready to run. Returns: pdPASS : task was successfully created and added to a ready list error code : defined in the file projdefs. h portBASE_TYPE xTaskCreate ( pdTASK_CODE pvTaskCode, //pointer to a task function const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, //parameters for task unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask //handle for task. );
Stack creation for task Set information of Task
Critical section start Add a task to Ready Queue Critical section end
If success, Save handle Macro for forcing a context switch. asm volatile ( "SWI" );
Usage of xTaskCreate // Task to be created. void vTaskCode( void * pvParameters ) { for( ;; ) { // Task code goes here. } // Function that creates a task. void vOtherFunction( void ) { unsigned char ucParameterToPass; xTaskHandle xHandle; // Create the task, storing the handle. xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle ); // Use the handle to delete the task. vTaskDelete( xHandle ); }
API - vTaskDelete INCLUDE_vTaskDelete must be defined as 1 Remove a task from the kernel removed from all ready, blocked, suspended and event lists. Parameter : pxTask The handle of the task to be deleted. void vTaskDelete( xTaskHandle pxTask );
Handle to task to be deleted Check this is a current TCB or not 1) Get a handle for the task 2) Remove the task from the ready list 3) Remove the task from the event list 4) Add the TCB to xTasksWaitingTermination to deallocate in the future
Usage of vTaskDelete void vOtherFunction( void ) { xTaskHandle xHandle; // Create the task, storing the handle. xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); // Use the handle to delete the task. vTaskDelete( xHandle ); }
API - vTaskDelay INCLUDE_vTaskDelay must be defined as 1 Delay a task for a given number of ticks. Parameters : xTicksToDelay The amount of time, in tick periods, that the calling task should block. void vTaskDelay( portTickType xTicksToDelay );
Usage of vTaskDelay // Perform an action every 10 ticks. // NOTE: // This is for demonstration only and would be better achieved // using vTaskDelayUntil(). void vTaskFunction( void * pvParameters ) { portTickType xDelay, xNextTime; // Calc the time at which we want to perform the action // next. xNextTime = xTaskGetTickCount () + ( portTickType ) 10; for( ;; ) { xDelay = xNextTime - xTaskGetTickCount (); xNextTime += ( portTickType ) 10; // Guard against overflow if( xDelay <= ( portTickType ) 10 ) { vTaskDelay( xDelay ); } // Perform action here. }
API - vTaskDelayUntil Delay a task until a specified time. can be used by cyclical tasks to ensure a constant execution frequency. Parameters: pxPreviousWakeTime Pointer to a variable that holds the time at which the task was last unblocked. The variable must be initialised with the current time prior to its first use Following this, the variable is automatically updated within vTaskDelayUntil(). Parameters: xTimeIncrement The cycle time period. void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );
Usage of vTaskDelayUntil Example usage: // Perform an action every 10 ticks. void vTaskFunction( void * pvParameters ) { portTickType xLastWakeTime; const portTickType xFrequency = 10; // Initialise the xLastWakeTime variable with the current time. xLastWakeTime = xTaskGetTickCount(); for( ;; ) { // Wait for the next cycle. vTaskDelayUntil( &xLastWakeTime, xFrequency ); // Perform action here. }
API - vTaskSuspend INCLUDE_vTaskSuspend must be defined as 1 Suspend any task. Parameters: pxTaskToSuspend Handle to the task being suspended. NULL handle will cause the calling task to be suspended. Calls to vTaskSuspend are not accumulative calling vTaskSuspend () twice requires one call to vTaskResume () to ready void vTaskSuspend( xTaskHandle pxTaskToSuspend );
Usage of vTaskSuspend void vAFunction( void ) { xTaskHandle xHandle; // Create a task, storing the handle. xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); //... // Use the handle to suspend the created task. vTaskSuspend( xHandle ); //... // The created task will not run during this period, unless // another task calls vTaskResume( xHandle ). //... // Suspend ourselves. vTaskSuspend( NULL ); // We cannot get here unless another task calls vTaskResume // with our handle as the parameter. }
Other APIs vTaskResume TaskPrioritySet uxTaskPriorityGet vTaskPrioritySet vTaskResumeFromISR
Context Switch Process
Call TaskYield() PortYield() vPortYieldProcessor() portSAVE_CONTEXT() vTaskSwitchContext() portRESTORE_CONTEXT() Generate Interrupt asm volatile ( "SWI" );
SWI interrupt causes …
vPortYieldProcessor()
vTaskSwitchContext
List Structures
xList Used in ready, blocked, event queue for scheduling
Various Queue in FreeRTOS TCB Priority 0 TCB Priority 1 TCB Priority 2 TCB Priority 3 TCB