uC/OS-ii内核源码理解(五)创建任务函数

来源:互联网 发布:.net水电管理系统源码 编辑:程序博客网 时间:2024/06/05 03:40

创建任务函数有两个: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"栈顶,我们需要分配并保存堆栈。





0 0
原创粉丝点击