KL15 高电平请求 FullCom:AUTOSAR 项目调用流程
1. 场景与结论
KL15 为高电平时,项目中的 AppWakeUpCtrl_MainFunction 周期性读取 KL15,并通过 RTE 请求 COMM_FULL_COMMUNICATION。请求经 BswM 转交给 ComM。ComM 再驱动 CanSM 启动 CAN 控制器,并通知 Nm/CanNm 请求网络。CanSM 的控制器启动是异步过程,所以从 KL15 读高到 CAN 总线上出现 NM 帧,会经过多个调度周期。
项目中还有一条并行的 KL15 唤醒来源路径:WakeUpCdd_MainFunction 在 ComM 尚未 FullCom 时向 EcuM 报告 KL15 唤醒事件;BswM 再设置 NmCdd 的 KL15 来源标志,供 NM 状态切换时写入 NM 用户数据。AppWakeUpCtrl 路径负责请求 FullCom;EcuM/BswM/NmCdd 路径负责记录唤醒来源。
2. 状态机图
KL15 高电平请求 FullCom:AUTOSAR 项目调用流程
1. 场景与结论
KL15 为高电平时,项目中的 AppWakeUpCtrl_MainFunction 周期性读取 KL15,并通过 RTE 请求 COMM_FULL_COMMUNICATION。请求经 BswM 转交给 ComM。ComM 再驱动 CanSM 启动 CAN 控制器,并通知 Nm/CanNm 请求网络。CanSM 的控制器启动是异步过程,所以从 KL15 读高到 CAN 总线上出现 NM 帧,会经过多个调度周期。
项目中还有一条并行的 KL15 唤醒来源路径:WakeUpCdd_MainFunction 在 ComM 尚未 FullCom 时向 EcuM 报告 KL15 唤醒事件;BswM 再设置 NmCdd 的 KL15 来源标志,供 NM 状态切换时写入 NM 用户数据。AppWakeUpCtrl 路径负责请求 FullCom;EcuM/BswM/NmCdd 路径负责记录唤醒来源。
2. 状态机图

3. 端到端调用时序
PduR / Com User Data Nm / CanNm (5 ms) CanDrv CanIf CanSM (5 ms) ComM (20 ms) BswM (5 ms) RTE Mode Request AppWakeUpCtrl (10 ms) KL15 / IoHwAb PduR / Com User Data Nm / CanNm (5 ms) CanDrv CanIf CanSM (5 ms) ComM (20 ms) BswM (5 ms) RTE Mode Request AppWakeUpCtrl (10 ms) KL15 / IoHwAb #mermaid-svg-oj09NvEHDyY6050w{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-oj09NvEHDyY6050w .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oj09NvEHDyY6050w .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oj09NvEHDyY6050w .error-icon{fill:#552222;}#mermaid-svg-oj09NvEHDyY6050w .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oj09NvEHDyY6050w .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oj09NvEHDyY6050w .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oj09NvEHDyY6050w .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oj09NvEHDyY6050w .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oj09NvEHDyY6050w .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oj09NvEHDyY6050w .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oj09NvEHDyY6050w .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oj09NvEHDyY6050w .marker.cross{stroke:#333333;}#mermaid-svg-oj09NvEHDyY6050w svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oj09NvEHDyY6050w p{margin:0;}#mermaid-svg-oj09NvEHDyY6050w .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-oj09NvEHDyY6050w text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-oj09NvEHDyY6050w .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-oj09NvEHDyY6050w .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-oj09NvEHDyY6050w .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-oj09NvEHDyY6050w .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-oj09NvEHDyY6050w #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-oj09NvEHDyY6050w .sequenceNumber{fill:white;}#mermaid-svg-oj09NvEHDyY6050w #sequencenumber{fill:#333;}#mermaid-svg-oj09NvEHDyY6050w #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-oj09NvEHDyY6050w .messageText{fill:#333;stroke:none;}#mermaid-svg-oj09NvEHDyY6050w .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-oj09NvEHDyY6050w .labelText,#mermaid-svg-oj09NvEHDyY6050w .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-oj09NvEHDyY6050w .loopText,#mermaid-svg-oj09NvEHDyY6050w .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-oj09NvEHDyY6050w .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-oj09NvEHDyY6050w .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-oj09NvEHDyY6050w .noteText,#mermaid-svg-oj09NvEHDyY6050w .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-oj09NvEHDyY6050w .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-oj09NvEHDyY6050w .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-oj09NvEHDyY6050w .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-oj09NvEHDyY6050w .actorPopupMenu{position:absolute;}#mermaid-svg-oj09NvEHDyY6050w .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-oj09NvEHDyY6050w .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-oj09NvEHDyY6050w .actor-man circle,#mermaid-svg-oj09NvEHDyY6050w line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-oj09NvEHDyY6050w :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 读取为 STD_HIGH写 COMM_FULL_COMMUNICATION读取 ModeReq规则状态 FALSE → TRUEComM_RequestComMode(User 0, FULL)保存 FullCom 请求请求 COMM_FULL_COMMUNICATIONNm_NetworkRequest(Channel 0)请求控制器 STARTED / 设置 PDU Mode请求控制器启动ControllerModeIndication(STARTED)BswM_CanSM_CurrentState(FULL)ComM_BusSM_ModeIndication(FULL)启用应用 Tx/Rx I-PDU 组CanNm 进入 Repeat MessagePduR_CanNmTriggerTransmit 获取用户数据CanIf_Transmit(NM PDU)Can_Write
CAN 控制器启动和 NM 网络请求会并行推进。ComM_RequestComMode 返回只表示请求被接受或记录,不代表控制器已经启动,也不代表 NM 帧已经发到总线上。
4. 按状态机图步骤对应项目代码
步骤 1--2:SWC 请求 FullCom,RTE 保存请求值
AppWakeUpCtrl_MainFunction 每 10 ms 执行一次,通过 IoHwAb 读取 KL15:
- KL15 为
STD_HIGH:将ComM_Mode设置为COMM_FULL_COMMUNICATION。 - KL15 为低:将
ComM_Mode设置为COMM_NO_COMMUNICATION。 - 调用
Rte_Write_App_ComM_Mode_Request_Request_Mode(ComM_Mode)将请求写入 RTE Sender-Receiver 数据。
关键代码:
Proj_Code/_00_ASW/Core0/AppWakeUpCtrl/AppWakeUpCtrl.c:AppWakeUpCtrl_MainFunctionProj_Code/_01_BSW/Gen/GenData/Components/Rte_AppWakeUpCtrl.h:RTE 写接口宏Proj_Code/_01_BSW/Gen/GenData/Rte_SystemApplication_OsCore0.c:10 ms OS Task 调度AppWakeUpCtrl_MainFunction
RTE 生成代码中的写接口最终更新共享 Mode Request 变量;BswM 随后通过对应的 RTE Read 接口读取它。
步骤 2:BswM 读取请求并执行规则
BswM 的 BswM_MainFunction 在 5 ms OS Task 中运行。它调用生成的 BswM_SwcModeRequestUpdateFct_BSWM_SINGLEPARTITION,其中执行:
c
Rte_Read_Request_ModeReq_App_ComM_Mode_Request_Request_Mode(
&Request_ModeReq_App_ComM_Mode_Request_Request_Mode);
随后 BswM_Rule_BswMRule_App_ComM_Request 检查请求值。值为 COMM_FULL_COMMUNICATION 且规则状态之前不是 TRUE 时,触发 BswM_ActionList_AL_Request_ComM_FULL_COM,调用:
c
ComM_RequestComMode(
ComMConf_ComMUser_CN_DBCNetWork_f94df0c8,
COMM_FULL_COMMUNICATION);
关键代码:
Proj_Code/_01_BSW/Src/BswM/BswM.c:BswM_MainFunctionProj_Config/Bsw_Config/Gen/GenData/BswM_Lcfg.c:BswM_SwcModeRequestUpdateFct_BSWM_SINGLEPARTITION- 同文件:
BswM_Rule_BswMRule_App_ComM_Request - 同文件:
BswM_ActionList_AL_Request_ComM_FULL_COM
该规则带有状态记忆:KL15 持续为高时不会每次 BswM 调用都重新触发 FullCom Action List。KL15 变低后,规则切换回 FALSE 并触发 COMM_NO_COMMUNICATION 请求。
步骤 2、9、10:ComM 仲裁请求并通知 CanSM 与 Nm
ComM_RequestComMode 主要负责记录对应 ComM User 的请求。项目生成配置中:
ComMConf_ComMUser_CN_DBCNetWork_f94df0c8是 User 0。ComMConf_ComMChannel_CN_DBCNetWork_05d62413是 channel 0。- 另有 INTER1 的 User 和 channel,分别是 1;本流程的请求指向 DBCNetWork 主网络的 User 0。
ComM 由 ComM_MainFunction_0 每 20 ms 做请求仲裁并执行状态转换。从 NoCom 转向网络请求状态时,ComM_TF_NoCom_NetReq 先请求 BusSM 进入 FullCom,再按该 channel 的 NM 类型调用 Nm_NetworkRequest(Channel)。Nm 函数表将该请求转发给 CanNm。
关键代码:
Proj_Code/_01_BSW/Src/ComM/ComM.c:ComM_RequestComMode- 同文件:
ComM_MainFunction - 同文件:
ComM_TF_NoCom_NetReq Proj_Config/Bsw_Config/Gen/GenData/ComM_Cfg.h:User 与 channel 编号Proj_Config/Bsw_Config/Gen/GenData/Nm_Cfg.c:Nm 函数表到 CanNm 的映射
ComM 的 FullCom 用户请求和 CanSM 的物理控制器状态是不同层次的状态;前者表达"需要通信",后者负责真正启动 CAN 控制器并开放 PDU 通信。
步骤 3--6:CanSM、CanIf、CanDrv 启动控制器
ComM 通过 ComM_RequestBusSMMode 调用 CanSM_RequestComMode。CanSM 记录请求后,由 CanSM_MainFunction 按状态机推进启动过程,并调用 CanIf 设置控制器模式和 PDU Mode。
控制器启动有异步确认:
- CanSM 请求 CanIf 将控制器切换为
CANIF_CS_STARTED。 - CanIf 调用 CanDrv 执行硬件控制器模式切换。
- CanDrv/CanIf 报告控制器模式变化。
CanSM_ControllerModeIndication收到CANIF_CS_STARTED后调用CanSM_CtrlStartedIndicated。- CanSM 完成 FullCom 状态处理,并按状态开放 CanIf PDU 通信。
关键代码:
Proj_Code/_01_BSW/Src/CanSM/CanSM.c:CanSM_RequestComMode- 同文件:
CanSM_HandleComModeRequest - 同文件:
CanSM_MainFunction - 同文件:
CanSM_ControllerModeIndication - 同文件:
CanSM_CtrlStartedIndicated - 同文件:
CanSM_FullComReached Proj_Code/_01_BSW/Src/CanIf/CanIf.c:CanIf_SetControllerMode、CanIf_SetPduModeProj_Code/_01_BSW/Gen/GenData/CanIf_Lcfg.c:控制器模式指示回调映射到CanSM_ControllerModeIndication
步骤 6--8:CanSM 报状态,BswM 控制应用报文组
CanSM 的 CanSM_CheckModeIndication 在状态变化时调用 BswM_CanSM_CurrentState,并通过 ComM_BusSM_ModeIndication 向 ComM 报告 BusSM 通信模式。
项目中的 BswM 规则 BswM_Rule_CC_CN_DBCNetWork_05d62413_TX 检查 channel 0 是否处于 CANSM_BSWM_FULL_COMMUNICATION。达到 FullCom 后,相关 Action List 启用对应应用 TX I-PDU 组;RX 和 DM 规则也会据 CanSM 状态管理相应 COM 组。
关键代码:
Proj_Code/_01_BSW/Src/CanSM/CanSM.c:CanSM_CheckModeIndicationProj_Code/_01_BSW/Src/BswM/BswM.c:BswM_CanSM_CurrentStateProj_Config/Bsw_Config/Gen/GenData/BswM_Lcfg.c:BswM_Rule_CC_CN_DBCNetWork_05d62413_TX- 同文件:
BswM_ActionList_CC_AL_CN_DBCNetWork_05d62413_TX_EnableNoinit
应用 I-PDU 组的启用与 NM PDU 发送是相关但不同的动作:应用组由 BswM 管理;NM PDU 的周期发送由 CanNm 管理。
步骤 9--17:Nm/CanNm 进入网络模式并发送 NM 报文
CanNm_NetworkRequest 设置内部通信请求,并在 BusSleep/PrepareBusSleep 等符合条件的情况下设置 active restart 标志。CanNm_MainFunction 每 5 ms 处理该标志,调用 CanNm_StateTransition(..., NM_STATE_REPEAT_MESSAGE) 进入重复消息状态。
进入重复消息状态时,CanNm_TransitionToRepeatMessage 启动 Repeat Message 定时器。若本节点主动请求网络且 CanNmImmediateNmTransmissions 配置大于零,则加载快速发送计数并启动消息计时器。快速发送计数耗尽后,CanNm 再恢复普通 NM 消息周期。
报文发送路径如下:
CanNm_TriggerTransmission准备 NM PDU 数据。- 若启用了 COM User Data,CanNm 调用
PduR_CanNmTriggerTransmit从 COM 获取用户数据。 - CanNm 调用
CanIf_Transmit请求发送 NM PDU。 - CanIf 将请求交给 CanDrv 的
Can_Write。 - CAN 控制器完成总线发送后,通过 Tx Confirmation 回报发送结果。
关键代码:
Proj_Code/_01_BSW/Src/CanNm/CanNm.c:CanNm_NetworkRequest- 同文件:
CanNm_MainFunction中处理 Network Restart 的逻辑 - 同文件:
CanNm_StateTransition - 同文件:
CanNm_TransitionToRepeatMessage - 同文件:
CanNm_TransitionToNetworkMode - 同文件:
CanNm_TriggerTransmission Proj_Code/_01_BSW/Src/CanIf/CanIf.c:CanIf_Transmit- 同文件:调用
Can_Write的发送路径
5. KL15 唤醒来源标记路径
除 AppWakeUpCtrl 的 FullCom 请求路径外,项目还执行以下唤醒来源处理:
AppCtrl_MainFunction调用WakeUpCdd_MainFunction。- 当 ComM 当前不是 FullCom 且 KL15 为高时,WakeUpCdd 调用
EcuM_SetWakeupEvent(ECUM_WKSOURCE_KL15)。 - BswM 的
BswM_Rule_WakeUp_KL15PENDING检测到 KL15 Wakeup Source 为 PENDING。 BswM_ActionList_AL_SetKL15_WUSRC调用BswM_SetWUSRC_KL15,Callout 再调用NmCdd_SetWUSRC_KL15。- Nm 的状态切换回调
App_Nm_StateChangeIndication检查该标志,并在 NM 用户数据中写入 KL15 唤醒原因。
关键代码:
Proj_Code/_00_ASW/Core0/AppCtrl/AppCtrl.c:调用WakeUpCdd_MainFunctionProj_Code/_02_CDD/WakeUpCdd/WakeUpCdd.c:WakeUpCdd_MainFunctionProj_Config/Bsw_Config/Gen/GenData/BswM_Lcfg.c:BswM_Rule_WakeUp_KL15PENDING和BswM_ActionList_AL_SetKL15_WUSRCProj_Config/Bsw_Config/Gen/Source/BswM_Callout_Stubs.c:BswM_SetWUSRC_KL15Proj_Code/_02_CDD/NmCdd/NmCdd.c:NmCdd_SetWUSRC_KL15和App_Nm_StateChangeIndication
6. 相关任务周期
| Runnable / Main Function | 项目调度周期 | 作用 |
|---|---|---|
AppWakeUpCtrl_MainFunction |
10 ms | 读取 KL15,写入 FullCom/NoCom 请求 |
AppCtrl_MainFunction / WakeUpCdd_MainFunction |
10 ms | 检查 KL15 唤醒源,向 EcuM 报告事件 |
BswM_MainFunction |
5 ms | 读取 SWC Mode Request,处理 BswM 规则和动作 |
ComM_MainFunction_0 |
20 ms | 仲裁 ComM 请求并执行 channel 状态转换 |
CanSM_MainFunction |
5 ms | 推进控制器/总线通信状态机 |
CanNm_MainFunction |
5 ms | 推进 NM 状态机和 NM PDU 发送定时 |
这些调度周期来自生成的 Proj_Code/_01_BSW/Gen/GenData/Rte_SystemApplication_OsCore0.c。实际端到端耗时还受 OS 相位、CanSM 控制器模式异步确认和 CAN 总线仲裁影响。
7. 调试断点与检查项
AppWakeUpCtrl_MainFunction:检查KL15_State是否为STD_HIGH,ComM_Mode是否设成 FullCom。Rte_AppWakeUpCtrl_App_ComM_Mode_Request_Request_Mode:确认 RTE 写入值,以及 BswM 是否读到。BswM_Rule_BswMRule_App_ComM_Request:确认规则是否由 FALSE 转 TRUE,FullCom Action List 是否执行。ComM_RequestComMode/ComM_MainFunction_0:确认 User 0 请求位和 channel 0 状态。CanSM_RequestComMode/CanSM_MainFunction/CanSM_ControllerModeIndication:确认控制器是否进入 STARTED、CanIf PDU Mode 是否允许通信。CanNm_NetworkRequest/CanNm_MainFunction:确认 active restart 标志和NM_STATE_REPEAT_MESSAGE状态迁移。CanNm_TriggerTransmission/CanIf_Transmit:确认 NM PDU、User Data、发送返回值和 Tx Confirmation。NmCdd.c的KL15WUSRC_State:若需核对 NM 用户数据中的 KL15 来源,确认它在状态切换回调前已经置位。
8. 总结
KL15 高电平后,AppWakeUpCtrl_MainFunction 通过 RTE 请求 FullCom;BswM 识别请求并调用 ComM;ComM 仲裁后同时请求 CanSM 启动 CAN 控制器、请求 Nm/CanNm 唤醒网络。CanSM 完成控制器启动和 CanIf 通信模式配置后报告 FullCom;CanNm 进入 Repeat Message,并通过 PduR、CanIf 和 CanDrv 将 NM 报文发到总线上。与此同时,EcuM/BswM/NmCdd 路径记录 KL15 唤醒来源,用于 NM 用户数据标识。