接上文,继续分析Autosar多核系统的启动过程。本节分析StartOS函数。
EcuM_StartOS用来启动其他CPU核及OS。
EcuM_StartOS
if(GetCoreID()==ECUM_CORE_ID_STARTUP)
{
for(coreId=0; coreId < ECUM_NUMBER_OF_CORES; coreId++)
{
if(coreId!=ECUM_CORE_ID_STARTUP)
{
StartCore(coreId, &status); /* SBSW_ECUM_ADRESSPARAMETER_TOOS */
}
}
}
通过上面的代码来启动其他CPU,只有在核0(启动核)才运行
启动的其他CPU后也会运行EcuM_StartOS来启动对应核的OS
/* Start OS must be called for each core */
StartOS(appMode);//三个核都会运行该函数
至此,多核CPU就启动起来了
StartCore
Os_TrapCallStartCore->Os_Api_StartCore->Os_Hal_CoreStart
OS_FUNC_ATTRIBUTE_DEFINITION(OS_LOCAL_INLINE void, OS_CODE, OS_ALWAYS_INLINE, /* PRQA S 3219 */ /* MD_Os_Hal_3219 */
Os_Hal_CoreStart,
(
P2CONST(Os_Hal_CoreConfigType, AUTOMATIC, OS_CONST) Core
))
{
/* #10 Write the foreign PC with the startup code symbol for core 1. */
//设置PC指针
/* #20 Reset the core. */
// 设置HALT位,启动CPU
/* #30 Release the core. */
}
对于DBGSR寄存器的描述,可以参考我的另一篇文章或查看芯片手册
TC277寄存器学习
StartOS
StartOS->Os_TrapCallStartOS->Os_Api_StartOS->Os_HookCallOs_CoreInitHook
Os_HookCallOs_CoreInitHook调用Os_ThreadInit
Os_ThreadInit调用Os_Hal_ContextInit
Os_Hal_ContextInit调用Os_Hal_ContextIntInitialize
Os_Hal_ContextIntInitialize通过调用Entry函数来初始化
Default_Init_Task_Core0
/***********************************************************************************************************************
* Default_Init_Task_Core0
**********************************************************************************************************************/
TASK(Default_Init_Task_Core0)
{
/**********************************************************************************************************************
* DO NOT CHANGE THIS COMMENT! <USERBLOCK Default_Init_Task_Core0 begin block>
*********************************************************************************************************************/
/* Wait for startup of slave cores */
while ((((volatile uint8)Rte_InitState_1) != RTE_STATE_INIT) ||
(((volatile uint8)Rte_InitState_2) != RTE_STATE_INIT))
{
}
/**********************************************************************************************************************
* DO NOT CHANGE THIS COMMENT! </USERBLOCK>
*********************************************************************************************************************/
EcuM_StartupTwo();
/**********************************************************************************************************************
* DO NOT CHANGE THIS COMMENT! <USERBLOCK Default_Init_Task_Core0 end block>
*********************************************************************************************************************/
{
ISRType i;
for (i = (ISRType)0; i < OS_ISRID_COUNT; i++)
{
Os_EnableInterruptSource(i, TRUE);
}
}
/**********************************************************************************************************************
* DO NOT CHANGE THIS COMMENT! </USERBLOCK>
*********************************************************************************************************************/
(void)TerminateTask();
}
配置为Autostart的task
在task中调用EcuM_StartupTwo,进入STARTUP II状态,执行StartPostOS Sequence
从核的初始化task优先调用EcuM_StartupTwo,从核执行完后会将Rte_InitState置为初始化完成,主核等待从核初始化完后再进行初始化
从核初始化task会等待主核Rte_InitState置为初始化完成才会进入TerminateTask
下一节介绍EcuM_StartupTwo,其实到这里启动环节和芯片相关性就不大了,后面主要是按照Autosar的标准来启动,也就是模式管理,还需要继续学习~~~
你的点赞、关注、收藏是鼓励我的最大动力~