ucos review_2

来源:互联网 发布:合肥办公软件培训 编辑:程序博客网 时间:2024/03/29 06:48

ucos任务创建后,什么时候开始运行?

举例验证

举一个例子:

main:

int main(void)
{
  unsigned char os_err;
  InterruptCount = 0; //for test
  MailSendCount = 0; //for test
  MailRecCount = 0;   //for test
  SendCount  = 0; //for test

 CPU_IntDis();            //关闭中断,在初始化进程结束后才打开中断
  OSInit();                      //初始化UCOS
  os_err = OSTaskCreateExt((void (*)(void *)) tApp_MainTask,//创建主任务
(void *) 0,
(OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE -1] , //指定任务堆栈栈顶
(INT8U ) APP_TASK_START_PRIO,                       //指定任务优先级
(INT16U ) APP_TASK_START_PRIO, //指定任务标识号
  (OS_STK        *) &App_TaskStartStk[0],             //指定任务堆栈栈底
(INT32U          ) APP_TASK_START_STK_SIZE,//任务堆栈大小
(void          *) 0,//指向附加数据域
(INT16U ) (OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK) //操作选项
  );
#if OS_TASK_NAME_EN > 0
    OSTaskNameSet(APP_TASK_START_PRIO, (INT8U *)"Start Task", &os_err);
#endif  

  OSStart(); //开始任务调度 ,该函数内部将会打开中断允许
  return(0);

}

main->OS环境设置->任务创建->启动系统

OS环境设置:

void  OSInit (void)
{
    OSInitHookBegin();                                           /* Call port specific initialization code   */


    OS_InitMisc();                                               /* Initialize miscellaneous variables       */


    OS_InitRdyList();                                            /* Initialize the Ready List                */


    OS_InitTCBList();                                            /* Initialize the free list of OS_TCBs      */


    OS_InitEventList();                                          /* Initialize the free list of OS_EVENTs    */


#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
    OS_FlagInit();                                               /* Initialize the event flag structures     */
#endif


#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
    OS_MemInit();                                                /* Initialize the memory manager            */
#endif


#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
    OS_QInit();                                                  /* Initialize the message queue structures  */
#endif


    OS_InitTaskIdle();                                           /* Create the Idle Task                     */
#if OS_TASK_STAT_EN > 0u
    OS_InitTaskStat();                                           /* Create the Statistic Task                */
#endif


#if OS_TMR_EN > 0u
    OSTmr_Init();                                                /* Initialize the Timer Manager             */
#endif


    OSInitHookEnd();                                             /* Call port specific init. code            */
#if OS_DEBUG_EN > 0u
    OSDebugInit();
#endif
}

OS_InitMisc用于初始化系统变量,如时钟、中断层数、调度锁、任务数、OS运行状态、空闲计数、上下文转换次数等等。

OS_InitRdyList用于初始换就绪队列

OS_InitTCBList用于初始化TCB空闲列表

OS_InitEventList用于初始化事件控制块

OS_FlagInit用于初始化事件标志控制块

OS_MemInit用于初始化内存管理

OS_QInit用于初始化消息队列

OS_InitTaskIdle用于创建一个空闲任务

OS_InitTaskStat用于创建一个统计任务

OSTmr_Init用于初始化定时器list

任务创建:

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  */
        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 */
                OS_Sched();
            }
        } else {
            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);
}

做的工作包括:检查多任务OS开启、优先级范围、是否在ISR中创建任务、TCB检测、清除任务堆栈、初始化堆栈。

结论:

由: if (OSRunning == OS_TRUE) {                        /* Find HPT if multitasking has started */
                OS_Sched();

可知:

    在ucos启动的时候,创建的任务并不立即进行调度,而是在OSStart中进行调度,而对于已经启动,在创建任务的时候,任务一创建完成就会立即调度,如下:

OSStart:

void  OSStart (void)
{
    if (OSRunning == OS_FALSE) {
        OS_SchedNew();                               /* Find highest priority's task priority number   */
        OSPrioCur     = OSPrioHighRdy;
        OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run    */
        OSTCBCur      = OSTCBHighRdy;
        OSStartHighRdy();                            /* Execute target specific code to start task     */
    }
}

原创粉丝点击