【FreeRTOS】任务管理:创建与删除任务,任务优先级与阻塞
创建任务
动态分配内存:
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资源让其他任务工作了。