创建任务函数有两个:OSTaskCreate和OSTaskCreateExt。
OSTaskCreate有4个参数。
OSTaskCreateExt在OSTaskCreate基础上增加了一些功能参数,有9个参数。其中4个参数和OSTaskCreate一样。
这里就只讲解OSTaskCreateExt。
#if OS_TASK_CREATE_EXT_EN > 0u //选通开关
INT8U OSTaskCreateExt (void (*task)(void *p_arg),//函数指针
void *p_arg, //任意类型指针
OS_STK *ptos, //栈顶指针
INT8U prio, //优先级
INT16U id, //任务ID
OS_STK *pbos, //栈底指针
INT32U stk_size,//任务堆栈大小
void *pext, //指向用户提供的内存
INT16U opt) //用户操作选项参数
{
OS_STK *psp;
INT8U err;
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
1.task 指向函数的指针,传递的是一个函数
在main函数中调用OSTaskCreateExt传递的参数是"start_task",就是应用程序的名字。
2.p_arg
传递参数的指针,是一个任意类型的参数。当我们需要传递某些参数给函数时,可以通过该参数进行传递。
在main函数中调用OSTaskCreateExt传递的参数是"(void*)0",就是传递一个"空指针"给函数(没有参数,就传递一个空指针)。
3.ptos
指向任务堆栈栈顶指针。
这个参数和第六个参数pbos对应,根据栈的增长方向"OS_STK_GROWTH"来决定。具体见os_cpu.h文件54行中OS_STK_GROWTH的宏定义,
//定义栈的增长方向.
//CM3中,栈是由高地址向低地址增长的,所以OS_STK_GROWTH设置为1
#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */
我们定义栈的增长方向为从高地址往低地址增长,因此,在main函数中调用OSTaskCreateExt我们传递的参数是"START_TASK_STK[TaskStkLengh-1]",
也就是栈的高地址为栈顶。
4.prio
优先级唯一,优先级决定该任务指向的优先权利(值越小,优先级越高)。
5.ID
任务的ID
给每一个创建的任务分配一个ID编号,相当于一篇文章的每章节号。
我们在创建的任务中以"优先级"作为编号,所以在参数中,可以看到连续两个参数都是优先级。
6.pbos
指向栈底的指针。
这个参数和第3个参数ptos类似和栈的增长方向有关。
根据栈的增长方向#define OS_STK_GROWTH 1 是从高地址往低地址增长,在main函数调用OSTaskCreateExt中传递的参数是START_TASK_STK[0]。
7.stk_size
任务堆栈大小。
这个参数与app_cfg.h文件中定义的"堆栈变量"有关,我们需要传递的大小就是堆栈数组的大小值。
8.pext
指向用户提供的内存(指针)。
这个参数用作TCB扩展的参数。
9.opt
用户操作选项参数
这个参数用户创建任务时需要处理一些额外信息(操作)的参数。在注解中opt参数主要有三个
* OS_TASK_OPT_STK_CHK Stack checking to be allowed for the task检测参数是否可用
* OS_TASK_OPT_STK_CLR Clear the stack when the task is created清除堆栈(创建任务时清除堆栈)
* OS_TASK_OPT_SAVE_FP If the CPU has floating-point registers, save them(保存浮点指针)
* during a context switch.(进行上下文切换时)
参数是宏定义在ucos_ii.h中,210--213行:
#define OS_TASK_OPT_NONE 0x0000u /* NO option selected无操作选项 */
#define OS_TASK_OPT_STK_CHK 0x0001u /* Enable stack checking for the task使能参数检查 */
#define OS_TASK_OPT_STK_CLR 0x0002u /* Clear the stack when the task is create使能清除堆栈 */
#define OS_TASK_OPT_SAVE_FP 0x0004u /* Save the contents of any floating-point registers使能保存浮点指针*/
就是调用了某一个宏定义,那个宏定义的功能就使能了。
在main函数中调用OSTaskCreateExt传递的参数是"OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR",进行参数检查和堆栈清除。
3.创建任务时的堆栈
#if OS_TASK_CREATE_EXT_EN > 0u
INT8U OSTaskCreateExt (void (*task)(void *p_arg),
void *p_arg,
OS_STK *ptos,
INT8U prio,
INT16U id,
OS_STK *pbos,
INT32U stk_size,
void *pext,
INT16U opt)
{
OS_STK *psp;
INT8U err;
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
if (OSSafetyCriticalStartFlag == OS_TRUE) {
OS_SAFETY_CRITICAL_EXCEPTION();
}
#endif
#if OS_ARG_CHK_EN > 0u
if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range 确保优先级在指定范围内*/
return (OS_ERR_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (OSIntNesting > 0u) { /* Make sure we don't create the task from within an ISR确保我们不会从ISR中创建任务*/
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_CREATE_ISR);
}
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority确保任务优先级未被使用*/
OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ...保留这个优先级,*/
/* ... the same thing until task is created.防止再次创建相同优先级的任务*/
OS_EXIT_CRITICAL();
#if (OS_TASK_STAT_STK_CHK_EN > 0u)
OS_TaskStkClr(pbos, stk_size, opt); /* Clear the task stack (if needed)清除使用到的堆栈*/
#endif
psp = OSTaskStkInit(task, p_arg, ptos, opt); /* Initialize the task's stack初始化任务堆栈*/
err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
if (err == OS_ERR_NONE) {
if (OSRunning == OS_TRUE) { /* Find HPT if multitasking has started如果多任务已经开始,找到HPT使其运行*/
OS_Sched();
}
} else { //创建TCB不成功
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others使这个优先级有效,留给其他任务使用*/
OS_EXIT_CRITICAL();
}
return (err);
}
OS_EXIT_CRITICAL();
return (OS_ERR_PRIO_EXIST);
}
#endif
(1)OS_TaskStkClr
创建任务时清除堆栈。
这个函数需要在os_cfg.h中使能OS_TASK_STAT_STK_CHK_EN这个参数。
清除堆栈的顺序与栈的增长方向有关。看到源代码可以理解为清除堆栈,就是初始化时情况一下堆栈空间。
(2)OSTaskInit
初始化创建任务的堆栈。
这个函数位于os_cpu_c.c文件中,这个函数主要的参数是"ptos"栈顶,我们需要分配并保存堆栈。