写在前面:
入行一段时间了,基于个人理解整理一些东西,如有错误,欢迎各位大佬评论区指正!!!
在初始化代码中可以看到EcuM_StartupTwo中有两行代码,调用了SchM_Init和SchM_StartTiming两个函数。
那么SchM模块又是什么作用呢?
它用于调度和管理基础软件模块中的任务和事件。SchM 提供了任务的启动、停止和同步等功能,确保各个基础软件模块能够有序地执行。
SchM的主要职责是:
1. 任务调度
BSW Scheduler Module 通过预定义的调度表(Schedule Table)管理基础软件模块的任务。调度表定义了任务的触发时间和执行顺序,SchM 按照调度表触发任务的执行。
2. 任务同步
SchM 提供任务同步机制,确保多个并发任务能够协调工作。例如,资源访问同步,防止任务间的资源竞争。
3. 模式切换
系统在不同的操作模式下可能需要执行不同的任务。SchM 支持操作模式的切换,并根据当前的操作模式调度相应的任务。
4. 错误处理
在任务调度过程中,如果出现任何错误(如任务超时或资源冲突),SchM 会执行相应的错误处理机制,以确保系统的安全性和可靠性。
查看Davinci生产代码,在Rte.c中生成关于SchM函数如下:
在SchM_Init函数中,激活只包含BswSchedulableEntity的task、激活BswSchedulableEntity相关的alarm,SchM_Init的代码是RTE生成的。下文可以看到,对于Core0只激活Default_BSW_Task_Core0与Default_COM_Task_Core0。
FUNC(void, RTE_CODE) SchM_Init(void)
{
uint32 id = GetCoreID();
if (id == OS_CORE_ID_0) /* PRQA S 1843 */ /* MD_Rte_Os */
{
/* activate the tasks */
(void)ActivateTask(Default_BSW_Task_Core0); /* PRQA S 3417 */ /* MD_Rte_Os */
(void)ActivateTask(Default_COM_Task_Core0); /* PRQA S 3417 */ /* MD_Rte_Os */
Rte_InitState = RTE_STATE_SCHM_INIT;
}
if (id == OS_CORE_ID_1) /* PRQA S 1843 */ /* MD_Rte_Os */
{
/* activate the tasks */
(void)ActivateTask(Default_BSW_Task_Core1); /* PRQA S 3417 */ /* MD_Rte_Os */
Rte_InitState_1 = RTE_STATE_SCHM_INIT;
}
if (id == OS_CORE_ID_2) /* PRQA S 1843 */ /* MD_Rte_Os */
{
Rte_InitState_2 = RTE_STATE_SCHM_INIT;
}
if (id == OS_CORE_ID_3) /* PRQA S 1843 */ /* MD_Rte_Os */
{
/* activate the tasks */
(void)ActivateTask(Default_Com_Task_Core3); /* PRQA S 3417 */ /* MD_Rte_Os */
Rte_InitState_3 = RTE_STATE_SCHM_INIT;
}
if (id == OS_CORE_ID_4) /* PRQA S 1843 */ /* MD_Rte_Os */
{
Rte_InitState_4 = RTE_STATE_SCHM_INIT;
}
if (id == OS_CORE_ID_5) /* PRQA S 1843 */ /* MD_Rte_Os */
{
Rte_InitState_5 = RTE_STATE_SCHM_INIT;
}
}
在函数中切换状态
FUNC(void, RTE_CODE) SchM_Start(void)
{
uint32 id = GetCoreID();
if (id == OS_CORE_ID_0) /* PRQA S 1843 */ /* MD_Rte_Os */
{
Rte_InitState = RTE_STATE_SCHM_START;
}
if (id == OS_CORE_ID_1) /* PRQA S 1843 */ /* MD_Rte_Os */
{
Rte_InitState_1 = RTE_STATE_SCHM_START;
}
if (id == OS_CORE_ID_2) /* PRQA S 1843 */ /* MD_Rte_Os */
{
Rte_InitState_2 = RTE_STATE_SCHM_START;
}
if (id == OS_CORE_ID_3) /* PRQA S 1843 */ /* MD_Rte_Os */
{
Rte_InitState_3 = RTE_STATE_SCHM_START;
}
if (id == OS_CORE_ID_4) /* PRQA S 1843 */ /* MD_Rte_Os */
{
Rte_InitState_4 = RTE_STATE_SCHM_START;
}
if (id == OS_CORE_ID_5) /* PRQA S 1843 */ /* MD_Rte_Os */
{
Rte_InitState_5 = RTE_STATE_SCHM_START;
}
}
函数中激活alarm
FUNC(void, RTE_CODE) SchM_StartTiming(void)
{
uint32 id = GetCoreID();
if (id == OS_CORE_ID_0) /* PRQA S 1843 */ /* MD_Rte_Os */
{
SchM_StartTimingCore0(); /* PRQA S 2987 */ /* MD_Rte_2987 */
}
if (id == OS_CORE_ID_1) /* PRQA S 1843 */ /* MD_Rte_Os */
{
SchM_StartTimingCore1(); /* PRQA S 2987 */ /* MD_Rte_2987 */
}
if (id == OS_CORE_ID_2) /* PRQA S 1843 */ /* MD_Rte_Os */
{
SchM_StartTimingCore2(); /* PRQA S 2987 */ /* MD_Rte_2987 */
}
if (id == OS_CORE_ID_3) /* PRQA S 1843 */ /* MD_Rte_Os */
{
SchM_StartTimingCore3(); /* PRQA S 2987 */ /* MD_Rte_2987 */
}
if (id == OS_CORE_ID_4) /* PRQA S 1843 */ /* MD_Rte_Os */
{
SchM_StartTimingCore4(); /* PRQA S 2987 */ /* MD_Rte_2987 */
}
if (id == OS_CORE_ID_5) /* PRQA S 1843 */ /* MD_Rte_Os */
{
SchM_StartTimingCore5(); /* PRQA S 2987 */ /* MD_Rte_2987 */
}
}
UNC(void, RTE_CODE) SchM_StartTimingCore0(void)
{
/* activate the alarms used for TimingEvents */
(void)SetRelAlarm(Rte_Al_TE2_Default_COM_Task_Core0_0_20ms, RTE_MSEC_SystemTimerCore0(0) + (TickType)1, RTE_MSEC_SystemTimerCore0(20)); /* PRQA S 3417, 1840 */ /* MD_Rte_Os, MD_Rte_Os */
(void)SetRelAlarm(Rte_Al_TE2_Default_COM_Task_Core0_0_5ms, RTE_MSEC_SystemTimerCore0(0) + (TickType)1, RTE_MSEC_SystemTimerCore0(5)); /* PRQA S 3417, 1840 */ /* MD_Rte_Os, MD_Rte_Os */
(void)SetRelAlarm(Rte_Al_TE2_Default_BSW_Task_Core0_0_10ms, RTE_MSEC_SystemTimerCore0(0) + (TickType)1, RTE_MSEC_SystemTimerCore0(10)); /* PRQA S 3417, 1840 */ /* MD_Rte_Os, MD_Rte_Os */
(void)SetRelAlarm(Rte_Al_TE2_Default_BSW_Task_Core0_0_5ms, RTE_MSEC_SystemTimerCore0(0) + (TickType)1, RTE_MSEC_SystemTimerCore0(5)); /* PRQA S 3417, 1840 */ /* MD_Rte_Os, MD_Rte_Os */
}
切换Rte状态,关闭alarm
FUNC(void, RTE_CODE) SchM_Deinit(void)
{
uint32 id = GetCoreID();
if (id == OS_CORE_ID_0) /* PRQA S 1843 */ /* MD_Rte_Os */
{
/* deactivate alarms */
(void)CancelAlarm(Rte_Al_TE2_Default_BSW_Task_Core0_0_10ms); /* PRQA S 3417 */ /* MD_Rte_Os */
(void)CancelAlarm(Rte_Al_TE2_Default_BSW_Task_Core0_0_5ms); /* PRQA S 3417 */ /* MD_Rte_Os */
(void)CancelAlarm(Rte_Al_TE2_Default_COM_Task_Core0_0_20ms); /* PRQA S 3417 */ /* MD_Rte_Os */
(void)CancelAlarm(Rte_Al_TE2_Default_COM_Task_Core0_0_5ms); /* PRQA S 3417 */ /* MD_Rte_Os */
Rte_InitState = RTE_STATE_UNINIT;
}
if (id == OS_CORE_ID_1) /* PRQA S 1843 */ /* MD_Rte_Os */
{
/* deactivate alarms */
(void)CancelAlarm(Rte_Al_TE2_Default_BSW_Task_Core1_0_10ms); /* PRQA S 3417 */ /* MD_Rte_Os */
(void)CancelAlarm(Rte_Al_TE2_Default_BSW_Task_Core1_0_1ms); /* PRQA S 3417 */ /* MD_Rte_Os */
(void)CancelAlarm(Rte_Al_TE2_Default_BSW_Task_Core1_0_5ms); /* PRQA S 3417 */ /* MD_Rte_Os */
Rte_InitState_1 = RTE_STATE_UNINIT;
}
if (id == OS_CORE_ID_2) /* PRQA S 1843 */ /* MD_Rte_Os */
{
/* deactivate alarms */
(void)CancelAlarm(Rte_Al_TE2_Default_BSW_Task_Core2_0_10ms); /* PRQA S 3417 */ /* MD_Rte_Os */
Rte_InitState_2 = RTE_STATE_UNINIT;
}
if (id == OS_CORE_ID_3) /* PRQA S 1843 */ /* MD_Rte_Os */
{
/* deactivate alarms */
(void)CancelAlarm(Rte_Al_TE2_Default_BSW_Task_Core3_0_10ms); /* PRQA S 3417 */ /* MD_Rte_Os */
(void)CancelAlarm(Rte_Al_TE2_Default_Com_Task_Core3_0_10ms); /* PRQA S 3417 */ /* MD_Rte_Os */
(void)CancelAlarm(Rte_Al_TE2_Default_Com_Task_Core3_0_5ms); /* PRQA S 3417 */ /* MD_Rte_Os */
Rte_InitState_3 = RTE_STATE_UNINIT;
}
if (id == OS_CORE_ID_4) /* PRQA S 1843 */ /* MD_Rte_Os */
{
/* deactivate alarms */
(void)CancelAlarm(Rte_Al_TE2_Default_BSW_Task_Core4_0_10ms); /* PRQA S 3417 */ /* MD_Rte_Os */
Rte_InitState_4 = RTE_STATE_UNINIT;
}
if (id == OS_CORE_ID_5) /* PRQA S 1843 */ /* MD_Rte_Os */
{
/* deactivate alarms */
(void)CancelAlarm(Rte_Al_TE2_Default_BSW_Task_Core5_0_10ms); /* PRQA S 3417 */ /* MD_Rte_Os */
Rte_InitState_5 = RTE_STATE_UNINIT;
}
}