动态创建任务
- 依据FreeRTOS源码,逐步分析使用动态方式创建任务的过程。
- 源码移植载体为DSP,型号TMS320F28377D,仿真测试软件CCS12.8.1。
1. 动态创建任务——创建动态任务
/* 任务优先级 */
#define START_TASK_PRIO 1
/* 任务堆栈大小 */
#define START_STK_SIZE 1024
/* 任务句柄 */
TaskHandle_t StartTask_Handler;
/* 任务函数 */
void start_task(void *pvParameters);
/* 主函数 */
void main(void)
{
/*
* 其余代码
*/
/* 创建任务 */
xTaskCreate((TaskFunction_t )start_task, //任务入口函数
(const char* )"start_task", //任务名称
(uint16_t )START_STK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
/* 启动任务调度器 */
vTaskStartScheduler();
// 正常情况下不会运行到此
while(1)
{
/* 死循环 */
}
}
/* 任务函数 */
void start_task(void * pvParameters)
{
for(;;)
{
/* 任务具体内容*/
}
}
2. 动态创建任务——函数定义
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) /* 允许动态创建任务宏,在"FreeRTOSConfig.h"文件中配置。 */
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, /* 指向任务入口函数的指针 */
const char * const pcName, /* 任务名称 */
const configSTACK_DEPTH_TYPE usStackDepth, /* 要分配用作任务堆栈的字数 */
void * const pvParameters, /* 作为参数传递给所创建任务的值 */
UBaseType_t uxPriority, /* 创建的任务将以该指定优先级执行 */
TaskHandle_t * const pxCreatedTask ) /* 任务句柄 */
{
TCB_t * pxNewTCB; /* 指向任务控制块 */
BaseType_t xReturn; /* 返回值 */
/* If the stack grows down then allocate the stack then the TCB so the stack
* does not grow into the TCB. Likewise if the stack grows up then allocate
* the TCB then the stack.
* 如果堆栈向下增长,则先分配堆栈,然后分配TCB,这样堆栈就不会增长到为TCB中。同样,如果堆栈向上增长,则分配TCB,然后分配堆栈。
*/
#if ( portSTACK_GROWTH > 0 ) /* DSP的堆栈是向上增长的 */
{
/* Allocate space for the TCB. Where the memory comes from depends on
* the implementation of the port malloc function and whether or not static
* allocation is being used.
* 为TCB分配空间。内存的来源取决于端口malloc函数的实现以及是否使用静态分配。
*/
/* 从大数组中找到一块可以满足TCB_t大小的内存块,函数返回的地址是跳过结构体可以直接存放数据的地址。 */
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
if( pxNewTCB != NULL ) /* 内存空间申请成功。 */
{
memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); /* 将内存空间赋值为0 */
/* Allocate space for the stack used by the task being cre