0x00 LOS_KernelInit函数在实时操作系统中的意义
运行在MCU上的实时操作系统,大致流程都是初始化内存,初始化任务队列,初始化空闲任务等,然后开启调度器,对任务进行调度。
这篇文章分析的LOS_KernelInit这个函数,主要完成的就是内核的启动,包括内存初始化、任务队列初始化等。
0x01 函数分析
/*****************************************************************************
Function : LOS_KernelInit
Description : System kernel initialization function, configure all system modules
Input : None
Output : None
Return : LOS_OK on success or error code on failure
*****************************************************************************/
先看官方的注释:函数作用是初始化系统内核的所有模块。(这里准确来说是根据配置文件来初始化,并不是所有模块都初始化了)没有输入参数,返回值表示初始化是否成功。
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;
}
首先调用osRegister
函数,这个函数里只有一条语句,官方给的解释是配置最大任务数量。
接着调用osMemSystemInit
函数,根据函数返回值判断是否正确初始化。看名字就知道是初始化内存系统的。我之前写的一篇文章《浅析LOS_MemInit函数》里的LOS_MemInit函数就是在这个函数里调用的。
#if (LOSCFG_PLATFORM_HWI == YES)
{
osHwiInit();
}
#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
根据配置文件判断:是否调用osHwiInit
函数初始化硬件中断;调用osExcInit
函数初始化异常处理机制;调用osTaskMonInit
函数初始化任务监视功能。调用osTaskInit
函数初始化任务管理模块。
#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
流程跟上面差不多,都是判断宏定义,然后调用相关的函数对模块初始化。在代码中看得出,能配置的功能有互斥锁、信号量、队列等。
0x02 总结
LOS_KernelInit函数主要功能是初始化内核。具体步骤是判断宏定义,依次对内存、硬中断、异常、任务、任务监视、CPU使用量监视、信号量、互斥锁、队列、时间片、空闲任务等进行初始化。