【FreeRTOS】任务管理:创建与删除任务,任务优先级与阻塞
本文介绍了RTOS任务创建与管理的方法,包括任务优先级的使用和任务栈大小的估算。
创建任务
动态分配内存:
BaseType_t xTaskCreate(
TaskFunction_t pxTaskCode, // 函数指针, 任务函数
const char * const pcName, // 任务的名字
const configSTACK_DEPTH_TYPE usStackDepth, // 栈大小,单位为word,10表示40字节
void * const pvParameters, // 调用任务函数时传入的参数
UBaseType_t uxPriority, // 优先级
TaskHandle_t * const pxCreatedTask ); // 任务句柄, 以后使用它来操作这个任务

静态分配内存:
TaskHandle_t xTaskCreateStatic (
TaskFunction_t pxTaskCode, // 函数指针, 任务函数
const char * const pcName, // 任务的名字
const uint32_t ulStackDepth, // 栈大小,单位为word,10表示40字节
void * const pvParameters, // 调用任务函数时传入的参数
UBaseType_t uxPriority, // 优先级
StackType_t * const puxStackBuffer, // 静态分配的栈,就是一个buffer
StaticTask_t * const pxTaskBuffer // 静态分配的任务结构体的指针,用它来操作这个任务
);


使用任务参数:
任务传参一般使用结构体,用一个结构体来将函数需要的参数都包括在内,然后传参时传递结构体的地址就行了。
struct TaskPrintInfo{
uint8_t x;
uint8_t y;
char name[16];
};
static struct TaskPrintInfo LCDTask1 = {
0,
0,
"LCDTask1"
};
static struct TaskPrintInfo LCDTask2 = {
0,
3,
"LCDTask2"
};
static struct TaskPrintInfo LCDTask3 = {
0,
6,
"LCDTask3"
};
void LcdPrintTask(void* params)
{
struct TaskPrintInfo* pinfo = params;
//...
//通过 pinfo 指针调用结构体成员,完成任务
//...
}
//使用同一个函数创建不同的任务
xTaskCreate(LcdPrintTask,"LCDTask1",128,&LCDTask1,osPriorityNormal,NULL);
xTaskCreate(LcdPrintTask,"LCDTask2",128,&LCDTask2,osPriorityNormal,NULL);
xTaskCreate(LcdPrintTask,"LCDTask3",128,&LCDTask3,osPriorityNormal,NULL);
估算栈大小
估算栈的大小:

下图为理论上最多要保存的寄存器:

删除任务
使用 void vTaskDelete( TaskHandle_t xTaskToDelete ) 这个函数来删除任务,xTaskToDelete就是创建任务时接收的任务句柄,如下示例代码:
//读取红外遥控器
if (IRReceiver_Read(&dev, &data) == 0)
{
if (data == 0xa8)//play
{
//创建播放音乐的任务
extern void PlayMusic(void* params);
if (xSoundTaskHandle == NULL)
{
LCD_ClearLine(0, 0);
LCD_PrintString(0, 0, "Create Task");
SoundRet = xTaskCreate(PlayMusic, "SoundTask", 128, NULL, osPriorityNormal, &xSoundTaskHandle);
}
}
else if (data == 0xa2)//power
{
//删除播放音乐的任务
if (xSoundTaskHandle != NULL)
{
LCD_ClearLine(0, 0);
LCD_PrintString(0, 0, "Delete Task");
vTaskDelete(xSoundTaskHandle);
PassiveBuzzer_Control(0);//停止蜂鸣器
xSoundTaskHandle = NULL;
}
}
}
但是一般来说不会频繁创建任务与删除任务,因为任务创建需要栈的空间,频繁创建与删除会形成大量碎片内存空间,可能会导致大量内存空间无法利用,最后无内存可用。
任务如何退出


优先级与阻塞
假设此时有个任务是播放音乐,如果任务优先级较低,音乐播放会很缓慢,可以提高任务优先级来提高音乐质量,但是提高任务优先级会导致他抢占cpu,需要让他主动放弃cpu资源才能让其他任务工作,所以可以将音乐播放任务中断的mdelay函数换成vTaskDelay,这样,在delay过程中音乐播放任务就会主动放弃cpu资源让其他任务工作了。
更多推荐
所有评论(0)