任务创建和删除API函数位于文件task.c中,需要包含task.h头文件。
task.h里面包函数任务的类型函数。例如,对xTaskCreate的调用(通过指针方式)返回一个TaskHandle_t 变量,然后可将该变量用vTaskDelete来进行任务的删除工作。
BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
const char * const pcName,
configSTACK_DEPTH_TYPE usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *pxCreatedTask
);
创建新的任务并加入任务就绪列表之中。
configSUPPORT_DYNAMIC_ALLOCATION在 FreeRTOSConfig.h文件中必须设置为1,只有这样才能访问API函数。
每个任务都需要用于保存任务状态的RAM,并被任务用作其堆栈。如果使用xTaskCreate()创建任务,则从FreeRTOS堆中自动分配所需的RAM。如果使用xTaskCreateStatic()创建任务,则RAM由应用程序编写器提供,因此可以在编译时静态分配。
如果你使用的是 FreeRTOS-MPU,官方建议是使用 xTaskCreateRestricted这个API,而不是xTaskCreateStatic()API函数。
/* Task to be created. */
void vTaskCode( void * pvParameters )
{
/* The parameter value is expected to be 1 as 1 is passed in the
pvParameters value in the call to xTaskCreate() below.
configASSERT( ( ( uint32_t ) pvParameters ) == 1 );
for( ;; )
{
/* Task code goes here. */
}
}
/* Function that creates a task. */
void vOtherFunction( void )
{
BaseType_t xReturned;
TaskHandle_t xHandle = NULL;
/* Create the task, storing the handle. */
xReturned = xTaskCreate(
vTaskCode, /* Function that implements the task. */
"NAME", /* 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. */
&xHandle ); /* Used to pass out the created task's handle. */
if( xReturned == pdPASS )
{
/* The task was created. Use the task's handle to delete the task. */
vTaskDelete( xHandle );
}
}
task. h
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer );
创建新任务并将其添加到准备运行的任务列表中。configSUPPORT_STATIC_ALLOCATION必须设置为 1。这时候API函数才可以调用。
pxTaskCode:参考1
pcName:参考1
ulStackDepth:参考1
pvParameters:参考1
uxPriority:参考1
puxStackBuffer:必须指向一个至少具有ulStackDepth索引的StackType_t数组(参见上面的ulStackDepth参数)-该数组将被用作任务的堆栈,因此它必须是持久的(没有在函数的堆栈上声明)。
pxTaskBuffer:必须指向StaticTask_t类型的变量。该变量将用于保存新任务的数据结构(TCB),因此它必须是持久的(没有在函数的堆栈上声明)。
返回:如果puxStackBuffer和pxTaskBuffer都不是NULL,那么将创建任务,并返回任务句柄。如果puxStackBuffer或pxTaskBuffer中有一个是NULL,那么任务将不会被创建,并返回NULL。
用例
/* Dimensions of the buffer that the task being created will use as its stack.
NOTE: This is the number of words the stack will hold, not the number of
bytes. For example, if each stack item is 32-bits, and this is set to 100,
then 400 bytes (100 * 32-bits) will be allocated. */
#define STACK_SIZE 200
/* Structure that will hold the TCB of the task being created. */
StaticTask_t xTaskBuffer;
/* Buffer that the task being created will use as its stack. Note this is
an array of StackType_t variables. The size of StackType_t is dependent on
the RTOS port. */
StackType_t xStack[ STACK_SIZE ];
/* Function that implements the task being created. */
void vTaskCode( void * pvParameters )
{
/* The parameter value is expected to be 1 as 1 is passed in the
pvParameters value in the call to xTaskCreateStatic(). */
configASSERT( ( uint32_t ) pvParameters == 1UL );
for( ;; )
{
/* Task code goes here. */
}
}
/* Function that creates a task. */
void vOtherFunction( void )
{
TaskHandle_t xHandle = NULL;
/* Create the task without using any dynamic memory allocation. */
xHandle = xTaskCreateStatic(
vTaskCode, /* Function that implements the task. */
"NAME", /* Text name for the task. */
STACK_SIZE, /* Number of indexes in the xStack array. */
( void * ) 1, /* Parameter passed into the task. */
tskIDLE_PRIORITY,/* Priority at which the task is created. */
xStack, /* Array to use as the task's stack. */
&xTaskBuffer ); /* Variable to hold the task's data structure. */
/* puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
been created, and xHandle will be the task's handle. Use the handle
to suspend the task. */
vTaskSuspend( xHandle );
}
BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition,
TaskHandle_t *pxCreatedTask );
创建一个新的内存保护单元(MPU)受限任务,并将其添加到准备运行的任务列表。必须在FreeRTOSConfig.h中将configSUPPORT_STATIC_ALLOCATION设置为1,才能使这个RTOS API函数可用。
在FreeRTOS内部,每个任务都需要两块内存。第一个块用于保存任务的数据结构。第二个块用作任务的堆栈。如果使用xTaskCreateRestricted()创建任务,那么任务堆栈的内存由应用程序编写者提供,任务数据结构的内存从FreeRTOS堆中自动分配。如果使用xTaskCreateRestrictedStatic()创建任务,那么应用程序编写者也必须为任务的数据结构提供内存。因此,xTaskCreateRestrictedStatic()允许在不使用任何动态内存分配的情况下创建内存保护任务。
pxTaskDefinition :指向定义任务的结构的指针
pxCreatedTask:用于传回可引用所创建任务的句柄。
返回: 如果任务成功创建并添加到就绪列表,则为pdPASS,否则为projdefs.h文件中定义的错误代码。
包含MPU支持的任务比不包含MPU支持的任务需要创建更多的参数。将每个参数单独传递给xTaskCreateRestrictedStatic()会很麻烦,因此使用结构TaskParameters_t来允许在编译时静态地配置参数。结构在task.h中定义为:
typedef struct xTASK_PARAMETERS
{
TaskFunction_t pvTaskCode;
const signed char * const pcName;
unsigned short usStackDepth;
void *pvParameters;
UBaseType_t uxPriority;
portSTACK_TYPE *puxStackBuffer;
MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
StaticTask_t * const pxTaskBuffer;
#endif
} TaskParameters_t;
....where MemoryRegion_t is defined as:
typedef struct xMEMORY_REGION
{
void *pvBaseAddress;
unsigned long ulLengthInBytes;
unsigned long ulParameters;
} MemoryRegion_t;
下面是上面这个结构体的说明:
char cTaskStack[ 1024 ] __attribute__((aligned(1024));
puxStackBuffer通常被设置为静态声明的堆栈的地址。作为替代,puxStackBuffer可以设置为NULL——在这种情况下,pvportmallocalsigned()将被调用来分配任务堆栈,应用程序编写人员有责任提供pvportmallocalsigned()的实现,以满足MPU的对齐要求。
portMPU_REGION_READ_WRITE
portMPU_REGION_PRIVILEGED_READ_ONLY
portMPU_REGION_READ_ONLY
portMPU_REGION_PRIVILEGED_READ_WRITE
portMPU_REGION_CACHEABLE_BUFFERABLE
portMPU_REGION_EXECUTE_NEVER
/* Create an TaskParameters_t structure that defines the task to be created.
* The StaticTask_t variable is only included in the structure when
* configSUPPORT_STATIC_ALLOCATION is set to 1. The PRIVILEGED_DATA macro can
* be used to force the variable into the RTOS kernel's privileged data area. */
static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
static const TaskParameters_t xCheckTaskParameters =
{
vATask, /* pvTaskCode - the function that implements the task. */
"ATask", /* pcName - just a text name for the task to assist debugging. */
100, /* usStackDepth - the stack size DEFINED IN WORDS. */
NULL, /* pvParameters - passed into the task function as the function parameters. */
( 1UL | portPRIVILEGE_BIT ),/* uxPriority - task priority, set the portPRIVILEGE_BIT
if the task should run in a privileged state. */
cStackBuffer,/* puxStackBuffer - the buffer to be used as the task stack. */
/* xRegions - Allocate up to three separate memory regions for access by
* the task, with appropriate access permissions. Different processors have
* different memory alignment requirements - refer to the FreeRTOS documentation
* for full information. */
{
/* Base address Length Parameters */
{ cReadWriteArray, 32, portMPU_REGION_READ_WRITE },
{ cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },
{ cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }
}
&xTaskBuffer; /* Holds the task's data structure. */
};
int main( void )
{
TaskHandle_t xHandle;
/* Create a task from the const structure defined above. The task handle
* is requested (the second parameter is not NULL) but in this case just for
* demonstration purposes as its not actually used. */
xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
* and/or timer task. */
for( ;; );
}
void vTaskDelete( TaskHandle_t xTask );
INCLUDE_vTaskDelete必须定义为1才能使该函数可用。
从RTOS内核管理中移除一个任务。被删除的任务将从所有就绪、阻塞、挂起和事件列表中删除。
注意:空闲任务负责从已删除的任务中释放RTOS内核分配的内存。因此,如果应用程序调用vTaskDelete(),空闲任务不缺少微控制器处理时间是很重要的。任务代码分配的内存不会自动释放,应该在删除任务之前释放。
xTask要删除的任务句柄。传递NULL将导致调用任务被删除。
用例:
void vOtherFunction( void )
{
TaskHandle_t xHandle = NULL;
// Create the task, storing the handle.
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
// Use the handle to delete the task.
if( xHandle != NULL )
{
vTaskDelete( xHandle );
}
}