A task is a user define function with a given priorityTask must return void and take a
void pointer parameter.
void ATaskFunction( void *pvParameters );
Each task is a small program in
its own right normally
run forever within an infinite loop, and will not exit.A single task function definition can be used to create any number of tasks
run forever within an infinite loop, and will not exit.A single task function definition can be used to create any number of tasks
A task should have the following
structure:
void vTaskName( void *pvParameters )
{
for( ;; )
{
-- Task application code here. --
}
}
Task States
Running
It is currently using the processor. Only one task can be in RUN mode at the moment.
Ready
Able to execute but a different task of equal or higher priority is already in the Running state.
Blocked
Currently waiting for either a temporal or external event (indicated by semaphore or queue).
Suspended
Not available for scheduling.
Creating Tasks
Tasks are created using the
FreeRTOS xTaskCreate() API function
portBASE_TYPE xTaskCreate
(
pdTASK_CODE pvTaskCode,
const signed portCHAR * const pcName,
unsigned portSHORT usStackDepth,
void *pvParameters,
unsigned portBASE_TYPE uxPriority,
xTaskHandle *pxCreatedTask
const signed portCHAR * const pcName,
unsigned portSHORT usStackDepth,
void *pvParameters,
unsigned portBASE_TYPE uxPriority,
xTaskHandle *pxCreatedTask
);
pvTaskCode:
Ø The
pvTaskCode parameter is simply a pointer to the function(in effect just the
function name) that implements the task
pcName:
Ø This
is not used by FreeRTOS in any way. It is included purely as a debugging aid
usStackDepth:
Ø The
usStackDepth value tells the kernel how big to make the stack
pvParameters:
Ø The
value assigned to pvParameters will be the value passed into the task.
pxCreatedTask:
Ø pxCreatedTask
can be used to pass out a handle to the task being created.
Example:
void vTask1( void
*pvParameters )
{
const char *pcTaskName =
"Task 1 is running\r\n";
volatile unsigned long ul;
for( ;; )
{
vPrintString( pcTaskName );
for( ul = 0; ul <
mainDELAY_LOOP_COUNT; ul++ )
{
}
}
}
void vTask2( void
*pvParameters )
{
const char *pcTaskName =
"Task 2 is running\r\n";
volatile unsigned long ul;
/* As per most tasks, this task
is implemented in an infinite loop. */
for( ;; )
{
/* Print out the name of this
task. */
vPrintString( pcTaskName );
/* Delay for a period. */
for( ul = 0; ul <
mainDELAY_LOOP_COUNT; ul++ )
{
}
}
}
The main() function simply
creates the tasks before starting the scheduler
int main( void )
{
xTaskCreate( vTask1, "Task
1", 1000, NULL, 1, NULL );
xTaskCreate( vTask2, "Task 2", 1000,
NULL, 1, NULL );
vTaskStartScheduler();
for( ;; );
}
Create a task from within another
task:
void vTask1( void
*pvParameters )
{
const char *pcTaskName =
"Task 1 is running\r\n";
volatile unsigned long ul;
xTaskCreate( vTask2,
"Task 2", 1000, NULL, 1, NULL );
for( ;; )
{
vPrintString( pcTaskName );
for( ul = 0; ul <
mainDELAY_LOOP_COUNT; ul++ )
{
}
}
}
Using the Task Parameter
void vTaskFunction( void *pvParameters
)
{
char *pcTaskName;
volatile unsigned long ul;
pcTaskName = ( char * )
pvParameters;
for( ;; )
{
vPrintString( pcTaskName );
for( ul = 0; ul <
mainDELAY_LOOP_COUNT; ul++ )
{
}
}
}
static const char
*pcTextForTask1 = “Task 1 is running\r\n”;
static const char
*pcTextForTask2 = “Task 2 is running\t\n”;
int main( void )
{
xTaskCreate( vTaskFunction,
"Task 1", 1000, (void*)pcTextForTask1,1,NULL );
xTaskCreate( vTaskFunction,
"Task 2", 1000, (void*)pcTextForTask2,1, NULL );
vTaskStartScheduler();
for( ;; );
}
Task Priority
Ø The
Priority parameter of the xTaskCreate() API function assigns an initial
priority to the task being created
Ø The
priority can be changed after the scheduler has been started
Ø The
maximum number of priorities available is set by the application defined
configMAX_PRIORIIES within FreeRTOSConfig.h.
Experimenting with priorities
static const char
*pcTextForTask1 = “Task 1 is running\r\n”;
static const char
*pcTextForTask2 = “Task 2 is running\t\n”;
int main( void )
{
xTaskCreate( vTaskFunction,
"Task 1", 1000, (void*)pcTextForTask1, 1, NULL );
xTaskCreate( vTaskFunction,
"Task 2", 1000, (void*)pcTextForTask2, 2, NULL );
vTaskStartScheduler();
return 0;
}
The output
The Idle Task and Idle Task Hook
Idle Task
Ø The
processor always needs something to execute
Ø An
Idle task is automatically created by the scheduler when vTaskStartScheduler()
is called
Ø The
idle task has the lowest possible priority (priority 0)
Ø The
idle task is responsible for freeing memory allocated by RTOS to
tasks that have since been deleted
Idle Task Hook
Ø A
function that is automatically called by the idle task once per iteration of
the idle task loop
Changing priority of a Task
Ø The
vTaskPrioritySet() API function can be used to change the priority of any task
after the schedulerhas been started
void vTaskPrioritySet( xTaskHandle pxTask, unsigned
portBASE_TYPE uxNewPriority );
Ø The
uxTaskPriorityGet() API function can be used to query the priority of a task.
unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask
);
Changing task priorities
void vTask1( void *pvParameters )
{
unsigned portBASE_TYPE uxPriority;
uxPriority = uxTaskPriorityGet( NULL );
for( ;; )
{
vPrintString( "Task1 is running\r\n" );
vPrintString( "About to raise the Task2
priority\r\n" );
vTaskPrioritySet( xTask2Handle, ( uxPriority + 1 ) );
}
}
void vTask2( void *pvParameters )
{
unsigned portBASE_TYPE uxPriority;
uxPriority = uxTaskPriorityGet( NULL );
for( ;; )
{
vPrintString( "Task2 is running\r\n" );
vPrintString( "About to lower the Task2
priority\r\n" );
vTaskPrioritySet( NULL, ( uxPriority - 2 ) );
}
}
xTaskHandle xTask2Handle;
int main( void )
{
xTaskCreate( vTask1, "Task 1", 1000, NULL, 2,
NULL );
xTaskCreate( vTask2, "Task 2", 1000, NULL, 1,
&xTask2Handle );
vTaskStartScheduler();
for( ;; );
}
Task Delete
Deleting
A Task
Ø A
task can use the vTaskDelete() API function to delete itself or any other task
void vTaskDelete( xTaskHandle pxTaskToDelete );
pxTaskToDelete:
The handle of the task that is to be deleted
int main( void )
{
/* Create the first task at priority 1. The task parameter
is not used
so is set to NULL. The task handle is also not used so
likewise is set
to NULL. */
xTaskCreate( vTask1, "Task 1", 1000, NULL, 1,
NULL );
/* The task is created at priority 1 ______^. */
/* Start the scheduler so the tasks start executing. */
vTaskStartScheduler();
/* main() should never reach here as the scheduler has been
started. */
for( ;; );
}
void vTask1( void *pvParameters )
{
const portTickType xDelay100ms = 100 / portTICK_RATE_MS;
for( ;; )
{
/* Print out the name of this task. */
vPrintString( "Task1 is running\r\n" );
xTaskCreate( vTask2, "Task 2", 1000, NULL, 2,
&xTask2Handle );
vTaskDelay( xDelay100ms );
}
}
void vTask2( void *pvParameters )
{
vPrintString( "Task2 is running and about to delete itself\r\n" );
vTaskDelete( xTask2Handle );
}
No comments:
Post a Comment