【Ucos-III源码分析】——系统初始化

一、系统调用OSInit(&err); 初始化内核都做了什么

1、进入初始化函数到这里大致可以分为几个步骤

        (1)、初始化数据

OSInitHook();                           /* Call port specific initialization code    */

OSIntNestingCtr   = (OS_NESTING_CTR)0;    /* Clear the interrupt nesting counter    */

OSRunning          =  OS_STATE_OS_STOPPED;  /* Indicate that multitasking not started  */

OSSchedLockNestingCtr   = (OS_NESTING_CTR)0;    /* Clear the scheduling lock counter    */

        这里简单来说就是惊醒了一些内容的初始化数值,包括有调用特殊端口的初始化,

清楚终端嵌套计数,不开启多任务、清楚任务调度的锁。


if (OSCfg_ISRStkSize > (CPU_STK_SIZE)0) {
   p_stk = OSCfg_ISRStkBasePtr;      /* Clear exception stack for stack checking.   */
   if (p_stk != (CPU_STK *)0) {
      size  = OSCfg_ISRStkSize;
      while (size > (CPU_STK_SIZE)0) {
      size--;
      *p_stk = (CPU_STK)0;
      p_stk++;
   }
  }
}

这里的话也很简单,简单理解就是通过循环来清除栈空间的内容,全部设置成0,为了后续检查。

void  OS_PrioInit (void)
{
    CPU_DATA  i;

、 /* Clear the bitmap table ... no task is ready            */
    for (i = 0u; i < OS_PRIO_TBL_SIZE; i++) {
         OSPrioTbl[i] = (CPU_DATA)0;
    }
}
void  OS_RdyListInit (void)
{
    OS_PRIO       i;
    OS_RDY_LIST  *p_rdy_list;


    for (i = 0u; i < OS_CFG_PRIO_MAX; i++) { 
                   /* Initialize the array of OS_RDY_LIST at each priority   */
        p_rdy_list = &OSRdyList[i];
        p_rdy_list->NbrEntries = (OS_OBJ_QTY)0;
        p_rdy_list->HeadPtr    = (OS_TCB   *)0;
        p_rdy_list->TailPtr    = (OS_TCB   *)0;
    }
}

再就是调用这个函数,这个函数大概可以理解为每一个就绪态的任务都会在这个数组中对应优先级的位置去置为1,现在经行初始化,代表没有任务需要被设置为1,所以这里的作用就是清空数组中的内容,代表此时系统正在初始化,代表没有任务就绪。

下方函数就是对于每一个优先级的任务,经行就绪列表的初始化。

void  OS_TaskInit (OS_ERR  *p_err)
{
#ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif

#if OS_CFG_DBG_EN > 0u
    OSTaskDbgListPtr = (OS_TCB      *)0;
#endif

    OSTaskQty        = (OS_OBJ_QTY   )0;    /* Clear the number of tasks   */
    OSTaskCtxSwCtr   = (OS_CTX_SW_CTR)0;    /* Clear the context switch counter     */

   *p_err            = OS_ERR_NONE;
}

这个就是初始化系统的任务管理器。说白了也就是去给参数赋值0


        (2)、创建空闲任务

接下来来到了比较关键的地方,就是ucos初始化就会创建两个任务出来

   OS_IdleTaskInit(p_err);    /* Initialize the Idle Task                               */
    if (*p_err != OS_ERR_NONE) {
        return;
    }

    OS_TickTaskInit(p_err);  /* Initialize the Tick Task                               */
    if (*p_err != OS_ERR_NONE) {
        return;
    }

这里就是创建任务的地方,先讲第一个任务(空闲任务)

void  OS_IdleTask (void *p_arg)
{
    CPU_SR_ALLOC();



    p_arg = p_arg;     /* Prevent compiler warning for not using 'p_arg'         */

    while (DEF_ON) {
        CPU_CRITICAL_ENTER();
        OSIdleTaskCtr++;
#if OS_CFG_STAT_TASK_EN > 0u
        OSStatTaskCtr++;
#endif
        CPU_CRITICAL_EXIT();

        OSIdleTaskHook();   /* Call user definable HOOK                               */
    }
}

这里可以看到空闲任务的实际运行非常的简单,就是不断地对一个变量进行++,OSIdleTaskCtr这个变量,从侧面来说,这个变量自增的快慢也可以反映出我们的系统工作的效率,增加的越快代表系统的利用率越低,(因为系统用都去做这个空闲任务了)

这里面还有一个点:空闲任务是最大优先级-1的优先级位置,这个位置也只允许空闲任务在这里。

           (3)、创建时钟基准任务

void  OS_TickTask (void *p_arg)
{
    OS_ERR  err;
    CPU_TS  ts;


    p_arg = p_arg;        /* Prevent compiler warning                               */

    while (DEF_ON) {
        (void)OSTaskSemPend((OS_TICK  )0,
                            (OS_OPT   )OS_OPT_PEND_BLOCKING,
                            (CPU_TS  *)&ts,
                            (OS_ERR  *)&err);   /* Wait for signal from tick interrupt 
        if (err == OS_ERR_NONE) {
            if (OSRunning == OS_STATE_OS_RUNNING) {
                OS_TickListUpdate();    /* Update all tasks waiting for time         */
            }
        }
    }
}

 这个函数是为了去配置ucos的时钟基准。这里面设置的超时时间是0意思也就是一旦时钟基准设置了之后就会无限制的运行下去,这也和实际情况是相符的。

        (4)、初始化消息队列的列表

#if (OS_MSG_EN) > 0u                /* Initialize the free list of OS_MSGs        */
    OS_MsgPoolInit(p_err);
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif

像这样的初始化还有很多,比如什么内存初始化,锁初始化,信号量,栈初始化等等需要根据你设置的使能位置来确定。
    上述在初始化创建的任务都还有一些,但是都需看你的宏是否置为1u了,所以把这些归为后面一类了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值