2_xTaskCreateStatic静态创建任务
如何静态创建一个任务?
[[#4 静态创建任务例子]]
1.开启功能
修改配置文件:FreeRTOSconfig.h
//配置支持静态分配
#define configSUPPORT_STATIC_ALLOCATION 1
2.实现2个函数接口(静态的空闲任务与定时器任务)
因为freertos至少需要一个任务,而静态任务功能打开后,
空闲任务所需空间也要静态方法来创建,需用户自己定义这个函数。
而定时器服务是可选的,而默认是打开的,
所以定时器服务所需空间也要静态方法来创建,需用户自己定义这个函数
空闲任务静态方法
定义静态的TCB和任务栈数组
//空闲任务的静态创建
static StaticTask_t IdleTaskTCB;//静态空闲任务TCB
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
//静态空闲任务栈,用数组实现,空间大小默认使用宏定义最小栈空间大小configMINIMAL_STACK_SIZE
实现静态空闲任务创建接口
给参数赋值:
修改一级TCB指针指向
修改一级任务栈指针指向
修改栈空间大小数值
void vApplicationGetIdleTaskMemory(
StaticTask_t ** ppxIdleTaskTCBBuffer,
//空闲任务TCB二级指针,传一级TCB指针地址,则可以修改一级指针的指向
StackType_t ** ppxIdleTaskStackBuffer,
//空闲任务栈二级指针,传一级栈指针地址(栈的数组名),则可以修改一级指针的指向
uint32_t * pulIdleTaskStackSize )
//空闲任务大小,32位整型指针,传栈数组的大小值,则可以修改指针指向的数值
{
*ppxIdleTaskTCBBuffer=&IdleTaskTCB;//使一级TCB指针指向静态空闲任务TCB地址
*ppxIdleTaskStackBuffer=IdleTaskStack;//使一级任务栈指针指向静态空闲任务栈数组
*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;//通过栈空间大小指针,修改空闲任务栈空间大小变量的值
}
定时器服务静态方法
定义静态的TCB和任务栈数组
//定时器任务的静态创建
static StaticTask_t TimerTaskTCB;
//定时器任务TCB
static StackType_t TimerTaskStack[configMINIMAL_STACK_SIZE];
//静态定时器任务栈,用数组实现,空间大小默认使用宏定义最小栈空间大小
实现定时器创建任务接口
给参数赋值
修改一级TCB指针指向
修改一级任务栈指针指向
修改栈空间大小数值
void vApplicationGetTimerTaskMemory(
StaticTask_t ** ppxTimerTaskTCBBuffer,
//定时器任务TCB二级指针,传一级TCB指针地址,则可以修改一级指针的指向
StackType_t ** ppxTimerTaskStackBuffer,
//定时器任务栈二级指针,传一级栈指针地址(栈的数组名),则可以修改一级指针的指向
uint32_t * pulTimerTaskStackSize )
//定时器任务大小,32位整型指针,传栈数组的大小值,则可以修改指针指向的数值
{
*ppxTimerTaskTCBBuffer=&TimerTaskTCB;//使一级TCB指针指向静态定时器任务TCB地址
*ppxTimerTaskStackBuffer=TimerTaskStack;//使一级任务栈指针指向静态定时器任务栈数组
*pulTimerTaskStackSize=configMINIMAL_STACK_SIZE;//通过栈空间大小指针,修改定时器任务栈空间大小变量的值
}
3.函数接口
函数定义头文件: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 //任务缓存区
);
4. 函数参数与返回值说明
参数:
-
pxTaskCode (函数名):
任务函数必须是无法返回的,即无return且内含无限循环 -
pcName (名称):
任务名称字符串,只是方便调试时使用的,
字符串长度包含’\0’,最大长度由宏定义configMAX_TASK_NAME_LEN决定
字符串超出长度自动则以’\0’截断 -
usStackDepth (堆栈大小):
任务堆栈的大小,实际申请到的内存空间为usStackDepth的4倍
任务函数占用的内存大小不可以超过这个任务栈申请到的内存空间。
空闲任务的堆栈大小由宏定义configMINIMAL_STACK_SIZE决定,可以根据需求更改其大小
任务所需栈空间,一般都是估算后取较大值防止溢出,但是这样可能会导致不必要的内存浪费
等学到后面就可以调试来查看任务执行过程中的内存占用情况,再来取一个合理的值。
-
pvParameters(参数):
需要传递给任务函数的参数,如同mian函数的参数一样,
通过这个参数可以实现对任务采用不同的模式等。 -
uxPriority(优先级):
0是最低优先级,最高优先级是configMAX_PRIORITIES-1
configMAX_PRIORITIES是任务优先级个数宏定义常量 -
puxStackBuffer(栈缓存器)
是必须指向StackType_t类型的静态数组变量,且数组至少要有参数ulStackDepth的大小
这个必须是一个持续存在的变量,不可以是在函数开辟的空间,不可以被应用程序覆盖。 -
pxTaskBuffer(任务缓存器)
是必须指向StaticTask_t类型的静态变量,用来保存任务的数据结构(TCB)
这个必须是一个持续存在的变量,不可以是在函数开辟的空间,不可以被应用程序覆盖 -
pxCreatedTask(任务句柄):
任务句柄可以引索到任务任务的堆栈,是指向任务控制块的指针
后面所有对任务的操作都需要通过这个句柄。
返回值:
- 返回 0 (NULL):
任务不能创建因为puxStackBuffer或 pxTaskBuffer是NULL - 返回 非0 (!=NULL):
TaskHandle_t类型的任务句柄
任务成功创建,函数返回值是任务的句柄,我们后面对这个函数进行操作则需要用到它。
所以需创建一个函数句柄变量把这个函数返回值存起来,赋值给句柄变量。
4.静态创建任务例子
//放在.h头文件的声明
#define TASK_T2_STACK_SIZE 512宏定义t2任务栈大小
#define TASK_T2_PRIORITY 2 //宏定义t2任务优先级
void task_t2(void *pvParameters); //声明任务函数
extern TaskHandle_t Handler_t2; //创建任务句柄,存储函数返回值
//放在.c文件的定义
TaskHandle_t Handler_t2; //创建任务句柄,存储函数返回值
static StaticTask_t task_t2_TaskTCB; //创建静态任务TCB
static StackType_t task_t2_TaskStack[TASK_T2_STACK_SIZE]; //创建静态任务堆栈
//创建任务成功后返回值为任务句柄,给任务句柄变量赋值
task3_Handler=xTaskCreateStatic(
task_t2,//任务函数名
"t2",//任务名称
TASK_T2_STACK_SIZE,//任务堆栈大小
NULL,//传递给任务函数的参数
TASK_T2_PRIORITY,//任务优先级
task_t2_TaskStack,//任务栈数组名
&task_t2_TaskTCB//任务TCB地址
);