创建任务
任务涉及到三个部分:1.做何事(函数) 2.栈和TCB结构体 3.优先级
对于栈和TCB结构体的分配有两种方式:1.malloc/静态 2.动态
/* 动态分配方式只需要提供需要的栈的大小 */
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 ); // 任务句柄, 以后使用它来操作这个任务
/* 静态分配方式需要自己提供数组作为栈 还需要自己提供TCB结构体*/
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 // 静态分配的任务结构体的指针,用它来操作这个任务
);
如何判断栈的深度是否够用?
寄存器部分:每个函数中最多使用R4-R11以及LR共9个寄存器需要保存入栈,当有5级调用关系时最大需要使用到的栈深度为5*9*4=180字节
局部变量部分:单个函数中定义的局部变量也会入栈保存,局部变量越大需要的栈的深度越深,局部变量占据的栈的深度取决于变量类型和数量。
现场部分:现场固定占据16*4=64字节的深度。
估算所需要的栈的深度也就是将函数中最复杂的一条分支所需要的以上三个部分相加即可。
单函数创建多任务
//保存打印信息
struct TaskPrintInfo
{
uint8_t x;
uint8_t y;
char name[16];
};
static struct TaskPrintInfo task1={0,0,"task1"};
static struct TaskPrintInfo task2={0,3,"task2"};
static struct TaskPrintInfo task3={0,6,"task3"};
/* 通过创建一个全局变量来使任务互斥运行 */
static int LCDCanUse = 1;
//通过传入结构体的方式使得函数执行效果不同
void LCDPrintTask(void *params)
{
LCD_Init();
LCD_Clear();
struct TaskPrintInfo *pInfo = params;
uint32_t cnt = 0;
int len;
while(1)
{
/* 判断全局变量的值决定是否能运行 */
if(LCDCanUse = 1)
{
/* 在确定可以运行的时候将全局变量置0使得其他任务无法打断 */
LCDCanUse = 0;
len = LCD_PrintString(pInfo->x,pInfo->y,pInfo->name);
len += LCD_PrintString(len,pInfo->y,":");
LCD_PrintSignedVal(len,pInfo->y,cnt++);
/* 判断全局变量的值决定是否能运行 */
LCDCanUse = 1;
}
/* 如果不延时在重置全局变量的时候刚好切换任务的概率极低 */
mdelay(500);
}
/* 创建任务 */
xTaskCreate(LCDPrintTask,"print1",128,&task1,osPriorityNormal,NULL);
xTaskCreate(LCDPrintTask,"print2",128,&task2,osPriorityNormal,NULL);
xTaskCreate(LCDPrintTask,"print3",128,&task3,osPriorityNormal,NULL);
删除任务
/* 删除任务,参数为句柄,通过句柄确认具体任务 */
void vTaskDelete( TaskHandle_t xTaskToDelete )