漫谈LiteOS-启动流程
9 启动流程
1 启动方式
目前对于多任务的实时操作系统中有两种比较流行的启动方式,一种是在main函数中进行硬件初始化以及系统初始化之后先将所有任务创建完成之后,一起启动,如移植代码中的主函数图1所示。
图1 启动方式一
另一种方式是在main函数中进行硬件初始化以及系统初始化之后创建任务之后直接启动调度器,然后在启动任务中创建各种应用任务,当所有任务创建成功后启动任务再把自己删除。具体如图2所示。
图2 启动方式二
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中。
图3 los_startup_keil.s
汇编程序如图4所示
图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所示。
图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的启动流程。
- 点赞
- 收藏
- 关注作者
评论(0)