漫谈LiteOS-启动流程

举报
星辰27 发表于 2019/12/02 10:09:04 2019/12/02
【摘要】 本文通过对代码的解析对LiteOS的启动流程做了一个较为详细的介绍,希望对你有所帮助。

9 启动流程

1 启动方式

目前对于多任务的实时操作系统中有两种比较流行的启动方式,一种是在main函数中进行硬件初始化以及系统初始化之后先将所有任务创建完成之后,一起启动,如移植代码中的主函数图1所示。

1574647997430545.png

图1 启动方式一

另一种方式是在main函数中进行硬件初始化以及系统初始化之后创建任务之后直接启动调度器,然后在启动任务中创建各种应用任务,当所有任务创建成功后启动任务再把自己删除。具体如图2所示。

1574648029279270.png

2 启动方式二

启动流程

2.1 Reset_Handler函数

一般在程序下载到开发板之后,我们首先会按一下Reset按键进行开发板的启动,因此在开发板上电后第一个执行的就是Reset_Handler函数,其位于los_startup_gcc.s文件中,该文件可以在LiteOS源码中的targets示例工程中找到。该函数主要进行了以下工作。

1)初始化栈指针;

2)初始化 PC 指针;

3)初始化中断向量表;

4)配置系统时钟;

5)调用 C 库函数_main。

具体如图3所示,位于los_startup_keil.s中。

1574648052687069.png

3 los_startup_keil.s

  汇编程序如图4所示

1574648117484013.png

4 汇编程序

2.2 LiteOS的初始化

进入主函数之后首先进行的是LiteOS的初始化。LOS_KernelInit函数,其具体如下代码所示。

LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID)
{
  UINT32 uwRet;
 
  osRegister();
 
  m_aucSysMem0 = OS_SYS_MEM_ADDR;
  uwRet = osMemSystemInit();
  if (uwRet != LOS_OK)
  {
    PRINT_ERR("osMemSystemInit error %d\n", uwRet);/*lint !e515*/
      return uwRet;
  }
  
#if (LOSCFG_PLATFORM_HWI == YES)
    {
      sHwiInit();
    }
#endif
 
#if (LOSCFG_PLATFORM_EXC == YES)
  {
    osExcInit(MAX_EXC_MEM_SIZE);
  }
#endif
     
  uwRet =osTaskInit();
  if (uwRet != LOS_OK)
  {
    PRINT_ERR("osTaskInit error\n");
    return uwRet;
  }
     
#if (LOSCFG_BASE_CORE_TSK_MONITOR == YES)
  {
    osTaskMonInit();
  }
#endif
     
#if (LOSCFG_BASE_CORE_CPUP == YES)
  {
    uwRet = osCpupInit();
    if (uwRet != LOS_OK)
    {
      PRINT_ERR("osCpupInit error\n");
      return uwRet;
    }
  }
#endif
     
#if (LOSCFG_BASE_IPC_SEM == YES)
  {
    uwRet = osSemInit();
    if (uwRet != LOS_OK)
    {
      return uwRet;
    }
  }
#endif
     
#if (LOSCFG_BASE_IPC_MUX == YES)
  {
    uwRet = osMuxInit();
    if (uwRet != LOS_OK)
    {
      return uwRet;
    }
  }
#endif
     
#if (LOSCFG_BASE_IPC_QUEUE == YES)
  {
    uwRet = osQueueInit();
    if (uwRet != LOS_OK)
    {
      PRINT_ERR("osQueueInit error\n");
      return uwRet;
    }
  }
#endif
     
#if (LOSCFG_BASE_CORE_SWTMR == YES)
  {
    uwRet = osSwTmrInit();
    if (uwRet != LOS_OK)
    {
      PRINT_ERR("osSwTmrInit error\n");
      return uwRet;
    }
  }
#endif
     
#if(LOSCFG_BASE_CORE_TIMESLICE == YES)
  osTimesliceInit();
#endif
     
  uwRet = osIdleTaskCreate();
  if (uwRet != LOS_OK)
  {
    return uwRet;
  }
     
#if (LOSCFG_TEST == YES)
  uwRet = los_TestInit();

  if (uwRet != LOS_OK)
  {
    PRINT_ERR("los_TestInit error\n");
    return uwRet;
  }
#endif
     
  return LOS_OK;
}
     
#ifdef __cplusplus
#if __cplusplus
    }
#endif /* __cpluscplus */
#endif /* __cpluscplus */

具体说明如图5所示。

1574649496942527.png

图5 内核函数示意图

下面对上图其中的几个宏以及函数(1、2、3、4、10)做一个较为详细的介绍:

1:根据 target_config.h 中的 LOSCFG_BASE_CORE_TSK_LIMIT 来配置最大支持的任务个数,默认为 LOSCFG_BASE_CORE_TSK_LIMIT+1,包括空闲任务IDLE

2:初始化 LiteOS 管理的内存模块,系统管理的内存大小为OS_SYS_MEM_SIZE

3 :如果在 target_config.h 中使用了 LOSCFG_PLATFORM_HWI 这个宏定义,则进行硬件中断模块的初始化。则表示 LiteOS 接管了系统的中断,使用时需要注册中断,否则无法响应中断,而如果不使用 LOSCFG_PLATFORM_HWI 这个宏定义,系中断将由硬件响应,系统不接管中断的操作与裸机基本是差不多的。

4 :初始化任务模块相关的函数,进行分配任务内存,初始化相关链表,为后面创建任务做准备。

10:在 target_config.h 中使用 LOSCFG_BASE_CORE_SWTMR 软件定时器的宏,所以,需要对软件定时器的使用进行相关初始化,当使用软件定时器的时候,系统还会创建一个软件定时器任务,并且必须使用消息队列。

之后直接开启任务调度,配置SysTick,以及配置 SysTick PendSVd 的优先级即可,通过上述步骤即完成了LiteOS的启动流程。

目录主博文https://bbs.huaweicloud.com/blogs/124244

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。