欢迎光临
我们一直在努力

通信服务的“幕后指挥”:深入理解SM(状态管理器)

在前面我们详细探讨了AUTOSAR通信栈中的多个核心模块——COM负责信号打包拆包,PduR负责I-PDU路由,CanTp负责大包分段,ComM负责通信需求管理,NM负责网络休眠唤醒协同。这些模块如同一个交响乐团中的各个乐器组,各自演奏着精妙的乐章。但一个交响乐团要能和谐演奏,光有乐手还不够,还需要一位能够协调各乐器组、控制演奏节奏和音量的指挥家。在AUTOSAR通信服务层中,这个指挥家的角色正是由一类特殊的模块来承担的——SM。

你可能在许多AUTOSAR架构图、配置工具、技术文档中反复看到这些名字:CanSM、LinSM、FrSM、EthSM。它们看起来结构相似,但各自又有特定的细节。这些SM到底做什么?为什么需要它们?它们和ComM、NM是什么关系?今天我们就来完整地回答这些问题。

第一章:SM的全称与定位——谁是SM?

SM的全称是State Manager(状态管理器)。在AUTOSAR通信服务层中,每种总线类型都有自己专属的SM模块。这个命名非常直接——它的核心职责就是管理状态。具体来说,是管理通信通道的完整生命周期状态。

在AUTOSAR标准文档中,SM被明确定义为“通信系统特定的状态管理器”,负责处理通信系统依赖的启动和关闭特性,同时控制COM的不同选项来发送PDU并监控信号超时。每个通信系统(如CAN、LIN、FlexRay)都有一个对应的SM模块。

AUTOSAR架构中标准的SM模块包括:

模块名全称管理对象
CanSM CAN State Manager CAN通信通道的状态
LinSM LIN State Manager LIN通信通道的状态
FrSM FlexRay State Manager FlexRay通信通道的状态
EthSM Ethernet State Manager 以太网通信通道的状态

虽然它们管理的总线类型不同,但核心设计理念和工作机制是高度一致的。理解了CanSM,就能触类旁通理解其他SM。

在分层架构中,SM位于通信服务层,与ComM、NM等模块并列。CanSM对于CAN通信的控制通过CanIf和CanDrv这两个模块执行,它本身不直接操作硬件,而是通过标准接口向CanIf发出控制请求。

第二章:为什么需要SM?——ComM不能直接控制硬件吗?

这个问题是理解SM价值的关键。ComM是通信管理器的核心决策者,它决定“现在应该开启哪个网络”。但ComM的职责定位决定了它不能直接去操作CAN控制器的寄存器,不能直接去配置CAN收发器的模式,不能直接去处理CAN控制器的Bus-Off错误恢复。

ComM管理的是“通信需求”和“网络模式”这个层面的抽象,它不知道CAN控制器有几种工作模式(初始化、停止、睡眠、正常运行),它不知道FlexRay有复杂的启动时序(冷启动节点、同步节点、非同步节点),它不知道以太网有PHY协商、MAC地址配置、VLAN划分。

如果让ComM来处理这些细节,ComM会变得无比臃肿,并且与具体总线类型紧耦合。一旦增加一种新总线,ComM就得大改。这完全违背了AUTOSAR分层解耦的设计哲学。

因此,AUTOSAR将“通信通道的具体控制”委托给了SM。ComM只做高层决策,SM执行底层控制。

#mermaid-svg-WNoSlHOVL6DFUZmL{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-WNoSlHOVL6DFUZmL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WNoSlHOVL6DFUZmL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WNoSlHOVL6DFUZmL .error-icon{fill:#552222;}#mermaid-svg-WNoSlHOVL6DFUZmL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WNoSlHOVL6DFUZmL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WNoSlHOVL6DFUZmL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WNoSlHOVL6DFUZmL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WNoSlHOVL6DFUZmL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WNoSlHOVL6DFUZmL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WNoSlHOVL6DFUZmL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WNoSlHOVL6DFUZmL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WNoSlHOVL6DFUZmL .marker.cross{stroke:#333333;}#mermaid-svg-WNoSlHOVL6DFUZmL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WNoSlHOVL6DFUZmL p{margin:0;}#mermaid-svg-WNoSlHOVL6DFUZmL .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-WNoSlHOVL6DFUZmL .cluster-label text{fill:#333;}#mermaid-svg-WNoSlHOVL6DFUZmL .cluster-label span{color:#333;}#mermaid-svg-WNoSlHOVL6DFUZmL .cluster-label span p{background-color:transparent;}#mermaid-svg-WNoSlHOVL6DFUZmL .label text,#mermaid-svg-WNoSlHOVL6DFUZmL span{fill:#333;color:#333;}#mermaid-svg-WNoSlHOVL6DFUZmL .node rect,#mermaid-svg-WNoSlHOVL6DFUZmL .node circle,#mermaid-svg-WNoSlHOVL6DFUZmL .node ellipse,#mermaid-svg-WNoSlHOVL6DFUZmL .node polygon,#mermaid-svg-WNoSlHOVL6DFUZmL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WNoSlHOVL6DFUZmL .rough-node .label text,#mermaid-svg-WNoSlHOVL6DFUZmL .node .label text,#mermaid-svg-WNoSlHOVL6DFUZmL .image-shape .label,#mermaid-svg-WNoSlHOVL6DFUZmL .icon-shape .label{text-anchor:middle;}#mermaid-svg-WNoSlHOVL6DFUZmL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WNoSlHOVL6DFUZmL .rough-node .label,#mermaid-svg-WNoSlHOVL6DFUZmL .node .label,#mermaid-svg-WNoSlHOVL6DFUZmL .image-shape .label,#mermaid-svg-WNoSlHOVL6DFUZmL .icon-shape .label{text-align:center;}#mermaid-svg-WNoSlHOVL6DFUZmL .node.clickable{cursor:pointer;}#mermaid-svg-WNoSlHOVL6DFUZmL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WNoSlHOVL6DFUZmL .arrowheadPath{fill:#333333;}#mermaid-svg-WNoSlHOVL6DFUZmL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WNoSlHOVL6DFUZmL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WNoSlHOVL6DFUZmL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WNoSlHOVL6DFUZmL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WNoSlHOVL6DFUZmL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WNoSlHOVL6DFUZmL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WNoSlHOVL6DFUZmL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WNoSlHOVL6DFUZmL .cluster text{fill:#333;}#mermaid-svg-WNoSlHOVL6DFUZmL .cluster span{color:#333;}#mermaid-svg-WNoSlHOVL6DFUZmL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WNoSlHOVL6DFUZmL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WNoSlHOVL6DFUZmL rect.text{fill:none;stroke-width:0;}#mermaid-svg-WNoSlHOVL6DFUZmL .icon-shape,#mermaid-svg-WNoSlHOVL6DFUZmL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WNoSlHOVL6DFUZmL .icon-shape p,#mermaid-svg-WNoSlHOVL6DFUZmL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WNoSlHOVL6DFUZmL .icon-shape .label rect,#mermaid-svg-WNoSlHOVL6DFUZmL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WNoSlHOVL6DFUZmL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WNoSlHOVL6DFUZmL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WNoSlHOVL6DFUZmL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

CanSM 的视角

ComM 的视角

“ComM_RequestMode”

“网络A需要进入完全通信模式”

1. 检查CAN控制器当前状态2. 配置CAN收发器进入正常模式3. 等待Bus-Off恢复?4. 确认网络稳定后通知ComM

这就是SM存在的核心理由——它是ComM的“执行代理”,将高层的模式请求翻译成具体的硬件控制序列。

第三章:CanSM的完整状态机解析

CanSM内部维护着一个精确的状态机,定义了CAN通信通道从“未初始化”到“完全运行”,再到“故障恢复”和“关闭”的完整生命周期。

#mermaid-svg-SKhu4JEa8BsidHVg{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-SKhu4JEa8BsidHVg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SKhu4JEa8BsidHVg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SKhu4JEa8BsidHVg .error-icon{fill:#552222;}#mermaid-svg-SKhu4JEa8BsidHVg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SKhu4JEa8BsidHVg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SKhu4JEa8BsidHVg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SKhu4JEa8BsidHVg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SKhu4JEa8BsidHVg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SKhu4JEa8BsidHVg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SKhu4JEa8BsidHVg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SKhu4JEa8BsidHVg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SKhu4JEa8BsidHVg .marker.cross{stroke:#333333;}#mermaid-svg-SKhu4JEa8BsidHVg svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SKhu4JEa8BsidHVg p{margin:0;}#mermaid-svg-SKhu4JEa8BsidHVg defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-SKhu4JEa8BsidHVg g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-SKhu4JEa8BsidHVg g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-SKhu4JEa8BsidHVg g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-SKhu4JEa8BsidHVg g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-SKhu4JEa8BsidHVg g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-SKhu4JEa8BsidHVg .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-SKhu4JEa8BsidHVg .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-SKhu4JEa8BsidHVg .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-SKhu4JEa8BsidHVg .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-SKhu4JEa8BsidHVg .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-SKhu4JEa8BsidHVg .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-SKhu4JEa8BsidHVg .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-SKhu4JEa8BsidHVg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SKhu4JEa8BsidHVg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-SKhu4JEa8BsidHVg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SKhu4JEa8BsidHVg .edgeLabel .label text{fill:#333;}#mermaid-svg-SKhu4JEa8BsidHVg .label div .edgeLabel{color:#333;}#mermaid-svg-SKhu4JEa8BsidHVg .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-SKhu4JEa8BsidHVg .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-SKhu4JEa8BsidHVg .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-SKhu4JEa8BsidHVg .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-SKhu4JEa8BsidHVg .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-SKhu4JEa8BsidHVg .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SKhu4JEa8BsidHVg .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SKhu4JEa8BsidHVg #statediagram-barbEnd{fill:#333333;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SKhu4JEa8BsidHVg .cluster-label,#mermaid-svg-SKhu4JEa8BsidHVg .nodeLabel{color:#131300;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-SKhu4JEa8BsidHVg .note-edge{stroke-dasharray:5;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-note text{fill:black;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram-note .nodeLabel{color:black;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagram .edgeLabel{color:red;}#mermaid-svg-SKhu4JEa8BsidHVg #dependencyStart,#mermaid-svg-SKhu4JEa8BsidHVg #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-SKhu4JEa8BsidHVg .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-SKhu4JEa8BsidHVg :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

ECU上电

ComM初始化CanSM

ComM请求FULL_COMM

ComM请求NO_COMM

ComM请求静默

ComM请求关闭

ComM请求FULL_COMM

ComM请求关闭

ComM请求FULL_COMM

CANSM_UNINIT

CANSM_INIT

Bus-Off事件

CANSM_INIT_FULL

CANSM_INIT_BUS_OFF

CANSM_COMM_FULL

Bus-Off事件

等待恢复

Bus-Off恢复

CANSM_FULL_COM_READY

CANSM_FULL_COM_BUS_OFF

CANSM_FULL_COM_WAIT_BUS_OFF

CANSM_COMM_NO_COMM

CANSM_COMM_SILENT

CANSM_SILENT_COM_READY

这个状态机看起来复杂,但我们可以把它分成几个核心逻辑来理解。

3.1 初始化状态:CANSM_UNINIT 与 CANSM_INIT

ECU上电后,CanSM首先进入CANSM_UNINIT状态。此时CanSM还没有被初始化,不能接受任何通信请求。当EcuM在启动流程中调用CanSM的初始化函数后,CanSM进入CANSM_INIT状态。此时CAN控制器被配置为初始状态(通常是不发送不接收的停止模式),等待ComM的进一步指令。

这种设计确保了CAN通信不会在系统完全准备好之前被意外激活。

3.2 完全通信状态:CANSM_COMM_FULL

当ComM调用CanSM_RequestMode(FULL_COMM)时,CanSM进入这个状态。这是CanSM最复杂、最核心的状态,包含了完整的运行逻辑和Bus-Off故障处理能力。

#mermaid-svg-tUqncQQbUfWwOFdi{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-tUqncQQbUfWwOFdi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tUqncQQbUfWwOFdi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tUqncQQbUfWwOFdi .error-icon{fill:#552222;}#mermaid-svg-tUqncQQbUfWwOFdi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tUqncQQbUfWwOFdi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tUqncQQbUfWwOFdi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tUqncQQbUfWwOFdi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tUqncQQbUfWwOFdi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tUqncQQbUfWwOFdi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tUqncQQbUfWwOFdi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tUqncQQbUfWwOFdi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tUqncQQbUfWwOFdi .marker.cross{stroke:#333333;}#mermaid-svg-tUqncQQbUfWwOFdi svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tUqncQQbUfWwOFdi p{margin:0;}#mermaid-svg-tUqncQQbUfWwOFdi .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-tUqncQQbUfWwOFdi .cluster-label text{fill:#333;}#mermaid-svg-tUqncQQbUfWwOFdi .cluster-label span{color:#333;}#mermaid-svg-tUqncQQbUfWwOFdi .cluster-label span p{background-color:transparent;}#mermaid-svg-tUqncQQbUfWwOFdi .label text,#mermaid-svg-tUqncQQbUfWwOFdi span{fill:#333;color:#333;}#mermaid-svg-tUqncQQbUfWwOFdi .node rect,#mermaid-svg-tUqncQQbUfWwOFdi .node circle,#mermaid-svg-tUqncQQbUfWwOFdi .node ellipse,#mermaid-svg-tUqncQQbUfWwOFdi .node polygon,#mermaid-svg-tUqncQQbUfWwOFdi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tUqncQQbUfWwOFdi .rough-node .label text,#mermaid-svg-tUqncQQbUfWwOFdi .node .label text,#mermaid-svg-tUqncQQbUfWwOFdi .image-shape .label,#mermaid-svg-tUqncQQbUfWwOFdi .icon-shape .label{text-anchor:middle;}#mermaid-svg-tUqncQQbUfWwOFdi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tUqncQQbUfWwOFdi .rough-node .label,#mermaid-svg-tUqncQQbUfWwOFdi .node .label,#mermaid-svg-tUqncQQbUfWwOFdi .image-shape .label,#mermaid-svg-tUqncQQbUfWwOFdi .icon-shape .label{text-align:center;}#mermaid-svg-tUqncQQbUfWwOFdi .node.clickable{cursor:pointer;}#mermaid-svg-tUqncQQbUfWwOFdi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tUqncQQbUfWwOFdi .arrowheadPath{fill:#333333;}#mermaid-svg-tUqncQQbUfWwOFdi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tUqncQQbUfWwOFdi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tUqncQQbUfWwOFdi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tUqncQQbUfWwOFdi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tUqncQQbUfWwOFdi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tUqncQQbUfWwOFdi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tUqncQQbUfWwOFdi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tUqncQQbUfWwOFdi .cluster text{fill:#333;}#mermaid-svg-tUqncQQbUfWwOFdi .cluster span{color:#333;}#mermaid-svg-tUqncQQbUfWwOFdi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tUqncQQbUfWwOFdi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tUqncQQbUfWwOFdi rect.text{fill:none;stroke-width:0;}#mermaid-svg-tUqncQQbUfWwOFdi .icon-shape,#mermaid-svg-tUqncQQbUfWwOFdi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tUqncQQbUfWwOFdi .icon-shape p,#mermaid-svg-tUqncQQbUfWwOFdi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tUqncQQbUfWwOFdi .icon-shape .label rect,#mermaid-svg-tUqncQQbUfWwOFdi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tUqncQQbUfWwOFdi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tUqncQQbUfWwOFdi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tUqncQQbUfWwOFdi :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

CANSM_COMM_FULL 完整状态

“检测到Bus-Off”

“进入恢复流程”

“恢复成功CAN控制器回到正常模式”

“恢复失败超时”

“正常操作”

CANSM_FULL_COM_READY完全通信就绪

CANSM_FULL_COM_BUS_OFFBus-Off发生

CANSM_FULL_COM_WAIT_BUS_OFF等待Bus-Off恢复

CANSM_FULL_COM_ERROR报告错误

“允许COM发送和接收周期性监控信号超时”

Bus-Off是CAN总线最严重的故障状态。当CAN控制器检测到发送错误计数达到255时,它会自动进入Bus-Off状态,从总线上断开。CanSM检测到这个状态后,会自动启动恢复流程,等待一定时间后尝试重新初始化CAN控制器。如果恢复成功,CanSM回到完全通信就绪状态。如果恢复失败(超时),CanSM上报错误给上层。

这个自动恢复能力是CanSM的核心价值之一。应用层完全不需要关心Bus-Off的发生和恢复细节,CanSM在后台默默处理了一切。

3.3 静默通信状态:CANSM_COMM_SILENT

静默通信状态是一种特殊的通信模式,在此状态下ECU可以接收CAN总线上的数据,但不能发送任何数据(包括ACK应答)。这种模式通常用于诊断监听或网络监听场景,不会对总线产生任何干扰。

3.4 无通信状态:CANSM_COMM_NO_COMM

当ComM请求关闭通信时,CanSM进入无通信状态。此时CAN控制器和收发器通常进入低功耗模式,不发送也不接收任何数据。这种状态通常对应着NM的BusSleep状态,用于ECU休眠时的省电管理。

第四章:SM的四大核心职责

通过上面的状态机解析,我们可以提炼出SM的四大核心职责。

4.1 职责一:通信系统的启动控制

SM负责按照正确的时序启动通信硬件。这个过程涉及多个步骤,每一步都有时序要求。

CAN收发器CanDrvCanIfCanSMComMCAN收发器CanDrvCanIfCanSMComM#mermaid-svg-wgLUHyz4Og8vK3X2{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-wgLUHyz4Og8vK3X2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wgLUHyz4Og8vK3X2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wgLUHyz4Og8vK3X2 .error-icon{fill:#552222;}#mermaid-svg-wgLUHyz4Og8vK3X2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wgLUHyz4Og8vK3X2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wgLUHyz4Og8vK3X2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wgLUHyz4Og8vK3X2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wgLUHyz4Og8vK3X2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wgLUHyz4Og8vK3X2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wgLUHyz4Og8vK3X2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wgLUHyz4Og8vK3X2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wgLUHyz4Og8vK3X2 .marker.cross{stroke:#333333;}#mermaid-svg-wgLUHyz4Og8vK3X2 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wgLUHyz4Og8vK3X2 p{margin:0;}#mermaid-svg-wgLUHyz4Og8vK3X2 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-wgLUHyz4Og8vK3X2 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-wgLUHyz4Og8vK3X2 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-wgLUHyz4Og8vK3X2 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-wgLUHyz4Og8vK3X2 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-wgLUHyz4Og8vK3X2 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-wgLUHyz4Og8vK3X2 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-wgLUHyz4Og8vK3X2 .sequenceNumber{fill:white;}#mermaid-svg-wgLUHyz4Og8vK3X2 #sequencenumber{fill:#333;}#mermaid-svg-wgLUHyz4Og8vK3X2 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-wgLUHyz4Og8vK3X2 .messageText{fill:#333;stroke:none;}#mermaid-svg-wgLUHyz4Og8vK3X2 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-wgLUHyz4Og8vK3X2 .labelText,#mermaid-svg-wgLUHyz4Og8vK3X2 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-wgLUHyz4Og8vK3X2 .loopText,#mermaid-svg-wgLUHyz4Og8vK3X2 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-wgLUHyz4Og8vK3X2 .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-wgLUHyz4Og8vK3X2 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-wgLUHyz4Og8vK3X2 .noteText,#mermaid-svg-wgLUHyz4Og8vK3X2 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-wgLUHyz4Og8vK3X2 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-wgLUHyz4Og8vK3X2 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-wgLUHyz4Og8vK3X2 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-wgLUHyz4Og8vK3X2 .actorPopupMenu{position:absolute;}#mermaid-svg-wgLUHyz4Og8vK3X2 .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-wgLUHyz4Og8vK3X2 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-wgLUHyz4Og8vK3X2 .actor-man circle,#mermaid-svg-wgLUHyz4Og8vK3X2 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-wgLUHyz4Og8vK3X2 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}ComM收到通知网络已就绪,可以开始通信CanSM_RequestMode(FULL_COMM)检查当前状态确认可以从INIT转换到COMM_FULLCanIf_SetControllerMode(CAN_CS_STARTED)Can_SetControllerMode(CAN_CS_STARTED)配置CAN控制器寄存器进入运行模式配置完成控制器已启动CanIf_SetTransceiverMode(TRCV_MODE_NORMAL)配置收发器进入正常模式收发器就绪收发器已就绪等待网络稳定(可选延时)CanSM_CurrentMode(NETWORK_ACTIVE)

AUTOSAR对于CAN通信的启动有专门的状态定义。CAN状态机状态的转换请求和通知通过CanIf模块进行管理,CanSM本身不直接访问硬件寄存器。

4.2 职责二:通信系统的关闭控制

当ComM请求关闭通信时,SM负责按照正确的时序关闭通信硬件。这个顺序必须严格,否则可能导致总线错误。

CAN收发器CanIfCanSMComMCAN收发器CanIfCanSMComM#mermaid-svg-fhvQXFulrDT7VkkZ{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-fhvQXFulrDT7VkkZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fhvQXFulrDT7VkkZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fhvQXFulrDT7VkkZ .error-icon{fill:#552222;}#mermaid-svg-fhvQXFulrDT7VkkZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fhvQXFulrDT7VkkZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fhvQXFulrDT7VkkZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fhvQXFulrDT7VkkZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fhvQXFulrDT7VkkZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fhvQXFulrDT7VkkZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fhvQXFulrDT7VkkZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fhvQXFulrDT7VkkZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fhvQXFulrDT7VkkZ .marker.cross{stroke:#333333;}#mermaid-svg-fhvQXFulrDT7VkkZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fhvQXFulrDT7VkkZ p{margin:0;}#mermaid-svg-fhvQXFulrDT7VkkZ .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fhvQXFulrDT7VkkZ text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-fhvQXFulrDT7VkkZ .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-fhvQXFulrDT7VkkZ .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-fhvQXFulrDT7VkkZ .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-fhvQXFulrDT7VkkZ .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-fhvQXFulrDT7VkkZ #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-fhvQXFulrDT7VkkZ .sequenceNumber{fill:white;}#mermaid-svg-fhvQXFulrDT7VkkZ #sequencenumber{fill:#333;}#mermaid-svg-fhvQXFulrDT7VkkZ #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-fhvQXFulrDT7VkkZ .messageText{fill:#333;stroke:none;}#mermaid-svg-fhvQXFulrDT7VkkZ .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fhvQXFulrDT7VkkZ .labelText,#mermaid-svg-fhvQXFulrDT7VkkZ .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-fhvQXFulrDT7VkkZ .loopText,#mermaid-svg-fhvQXFulrDT7VkkZ .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-fhvQXFulrDT7VkkZ .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-fhvQXFulrDT7VkkZ .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-fhvQXFulrDT7VkkZ .noteText,#mermaid-svg-fhvQXFulrDT7VkkZ .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-fhvQXFulrDT7VkkZ .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fhvQXFulrDT7VkkZ .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fhvQXFulrDT7VkkZ .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fhvQXFulrDT7VkkZ .actorPopupMenu{position:absolute;}#mermaid-svg-fhvQXFulrDT7VkkZ .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-fhvQXFulrDT7VkkZ .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fhvQXFulrDT7VkkZ .actor-man circle,#mermaid-svg-fhvQXFulrDT7VkkZ line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-fhvQXFulrDT7VkkZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}CAN控制器停止不再发送任何帧CAN收发器进入休眠仅监听唤醒信号CanSM_RequestMode(NO_COMM)等待所有待发送数据发送完成CanIf_SetControllerMode(CAN_CS_STOPPED)CanIf_SetTransceiverMode(TRCV_MODE_SLEEP)CanSM_CurrentMode(NETWORK_INACTIVE)

在CAN网络管理架构中,CAN状态机的状态转换最终会传递到CanSM,由CanSM统一协调处理。关闭时,控制器必须先从总线断开,收发器才能休眠。如果顺序反了,收发器先休眠可能导致总线上出现错误帧。

4.3 职责三:控制COM的PDU发送和信号超时监控

SM还负责根据通信状态控制COM模块的PDU发送行为,以及监控信号超时。

SM通过控制COM的I-PDU组来实现这一点。当网络状态正常时,SM允许所有I-PDU组正常发送。当网络正在启动或出现故障时,SM可以暂时禁止某些I-PDU组的发送,避免在通信不稳定时发送错误数据。当网络状态变化时(比如进入静默模式),SM通知COM只接收不发送。

这种机制保证了信号发送的正确性和可靠性。

4.4 职责四:Bus-Off故障的自动恢复

Bus-Off是CAN通信中最严重的故障状态。当CAN控制器检测到连续发送失败(发送错误计数达到255)时,它会自动从总线断开,进入Bus-Off状态。CanSM检测到这个状态后,会自动启动恢复流程。

CanSM定义了CAN控制器恢复的机制:先停止控制器,等待128次总线空闲(对应11位隐性位),然后重新初始化控制器。如果恢复成功,CanSM回到完全通信状态。如果恢复超时失败,CanSM上报错误给DET(开发错误追踪器)。

在AUTOSAR中,CanSM还提供生产错误和扩展生产错误的报告功能。例如CAN控制器初始化失败时,CanSM可以报告CANSM_E_INIT_FAILED错误;Bus-Off恢复失败时,可以报告CANSM_E_BUS_OFF错误给Dem模块,最终可能会点亮仪表盘的警告灯。

这个自动恢复机制对于车辆安全至关重要。CAN总线上的干扰(如电磁干扰、连接器接触不良)可能导致瞬时的Bus-Off。CanSM的自动恢复机制能确保ECU在干扰消失后自动恢复正常通信,而不需要重启整个ECU。

第五章:SM与ComM、NM的关系——通信栈的三角协作

SM不是孤岛,它与ComM、NM共同构成了通信栈的“三角核心”。这三个模块的协作关系是理解AUTOSAR通信服务的关键。

#mermaid-svg-3Q51ieVJAr7YVZKZ{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-3Q51ieVJAr7YVZKZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3Q51ieVJAr7YVZKZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3Q51ieVJAr7YVZKZ .error-icon{fill:#552222;}#mermaid-svg-3Q51ieVJAr7YVZKZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3Q51ieVJAr7YVZKZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3Q51ieVJAr7YVZKZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3Q51ieVJAr7YVZKZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3Q51ieVJAr7YVZKZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3Q51ieVJAr7YVZKZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3Q51ieVJAr7YVZKZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3Q51ieVJAr7YVZKZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3Q51ieVJAr7YVZKZ .marker.cross{stroke:#333333;}#mermaid-svg-3Q51ieVJAr7YVZKZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3Q51ieVJAr7YVZKZ p{margin:0;}#mermaid-svg-3Q51ieVJAr7YVZKZ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-3Q51ieVJAr7YVZKZ .cluster-label text{fill:#333;}#mermaid-svg-3Q51ieVJAr7YVZKZ .cluster-label span{color:#333;}#mermaid-svg-3Q51ieVJAr7YVZKZ .cluster-label span p{background-color:transparent;}#mermaid-svg-3Q51ieVJAr7YVZKZ .label text,#mermaid-svg-3Q51ieVJAr7YVZKZ span{fill:#333;color:#333;}#mermaid-svg-3Q51ieVJAr7YVZKZ .node rect,#mermaid-svg-3Q51ieVJAr7YVZKZ .node circle,#mermaid-svg-3Q51ieVJAr7YVZKZ .node ellipse,#mermaid-svg-3Q51ieVJAr7YVZKZ .node polygon,#mermaid-svg-3Q51ieVJAr7YVZKZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3Q51ieVJAr7YVZKZ .rough-node .label text,#mermaid-svg-3Q51ieVJAr7YVZKZ .node .label text,#mermaid-svg-3Q51ieVJAr7YVZKZ .image-shape .label,#mermaid-svg-3Q51ieVJAr7YVZKZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-3Q51ieVJAr7YVZKZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3Q51ieVJAr7YVZKZ .rough-node .label,#mermaid-svg-3Q51ieVJAr7YVZKZ .node .label,#mermaid-svg-3Q51ieVJAr7YVZKZ .image-shape .label,#mermaid-svg-3Q51ieVJAr7YVZKZ .icon-shape .label{text-align:center;}#mermaid-svg-3Q51ieVJAr7YVZKZ .node.clickable{cursor:pointer;}#mermaid-svg-3Q51ieVJAr7YVZKZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3Q51ieVJAr7YVZKZ .arrowheadPath{fill:#333333;}#mermaid-svg-3Q51ieVJAr7YVZKZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3Q51ieVJAr7YVZKZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3Q51ieVJAr7YVZKZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3Q51ieVJAr7YVZKZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3Q51ieVJAr7YVZKZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3Q51ieVJAr7YVZKZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3Q51ieVJAr7YVZKZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3Q51ieVJAr7YVZKZ .cluster text{fill:#333;}#mermaid-svg-3Q51ieVJAr7YVZKZ .cluster span{color:#333;}#mermaid-svg-3Q51ieVJAr7YVZKZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3Q51ieVJAr7YVZKZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3Q51ieVJAr7YVZKZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-3Q51ieVJAr7YVZKZ .icon-shape,#mermaid-svg-3Q51ieVJAr7YVZKZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3Q51ieVJAr7YVZKZ .icon-shape p,#mermaid-svg-3Q51ieVJAr7YVZKZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3Q51ieVJAr7YVZKZ .icon-shape .label rect,#mermaid-svg-3Q51ieVJAr7YVZKZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3Q51ieVJAr7YVZKZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3Q51ieVJAr7YVZKZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3Q51ieVJAr7YVZKZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

协同层 – NM

执行层 – SM

决策层 – ComM

“RequestMode”

“NetworkRequest”

“CurrentMode通知”

“StateChange通知”

“共用CanIf”

ComM管理通信需求决定网络模式

SM控制通信硬件处理启动/关闭/Bus-Off

NM协同休眠/唤醒发送NM PDU

三角协作的精髓:

模块角色核心问题
ComM 决策者 “我们需要通信吗?”
SM 执行者 “通信硬件怎么打开/关闭?”
NM 协同者 “其他ECU同意休眠了吗?”

一个完整的上电到通信就绪的流程是这样的:

CanIfCanNmCanSMComMSW-CCanIfCanNmCanSMComMSW-C#mermaid-svg-KHd8hXCmR2i2QQtb{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-KHd8hXCmR2i2QQtb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KHd8hXCmR2i2QQtb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KHd8hXCmR2i2QQtb .error-icon{fill:#552222;}#mermaid-svg-KHd8hXCmR2i2QQtb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KHd8hXCmR2i2QQtb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KHd8hXCmR2i2QQtb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KHd8hXCmR2i2QQtb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KHd8hXCmR2i2QQtb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KHd8hXCmR2i2QQtb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KHd8hXCmR2i2QQtb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KHd8hXCmR2i2QQtb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KHd8hXCmR2i2QQtb .marker.cross{stroke:#333333;}#mermaid-svg-KHd8hXCmR2i2QQtb svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KHd8hXCmR2i2QQtb p{margin:0;}#mermaid-svg-KHd8hXCmR2i2QQtb .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KHd8hXCmR2i2QQtb text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-KHd8hXCmR2i2QQtb .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-KHd8hXCmR2i2QQtb .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-KHd8hXCmR2i2QQtb .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-KHd8hXCmR2i2QQtb .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-KHd8hXCmR2i2QQtb #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-KHd8hXCmR2i2QQtb .sequenceNumber{fill:white;}#mermaid-svg-KHd8hXCmR2i2QQtb #sequencenumber{fill:#333;}#mermaid-svg-KHd8hXCmR2i2QQtb #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-KHd8hXCmR2i2QQtb .messageText{fill:#333;stroke:none;}#mermaid-svg-KHd8hXCmR2i2QQtb .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KHd8hXCmR2i2QQtb .labelText,#mermaid-svg-KHd8hXCmR2i2QQtb .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-KHd8hXCmR2i2QQtb .loopText,#mermaid-svg-KHd8hXCmR2i2QQtb .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-KHd8hXCmR2i2QQtb .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-KHd8hXCmR2i2QQtb .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-KHd8hXCmR2i2QQtb .noteText,#mermaid-svg-KHd8hXCmR2i2QQtb .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-KHd8hXCmR2i2QQtb .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KHd8hXCmR2i2QQtb .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KHd8hXCmR2i2QQtb .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KHd8hXCmR2i2QQtb .actorPopupMenu{position:absolute;}#mermaid-svg-KHd8hXCmR2i2QQtb .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-KHd8hXCmR2i2QQtb .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KHd8hXCmR2i2QQtb .actor-man circle,#mermaid-svg-KHd8hXCmR2i2QQtb line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-KHd8hXCmR2i2QQtb :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}通知网络上其他ECU“我需要通信”CanSM_RequestMode(FULL_COMM)启动CAN控制器配置CAN收发器网络已就绪Nm_NetworkRequest发送NM PDU“通信已可用”

关键观察点:

  • ComM先让SM启动硬件:在通知NM之前,必须确保CAN控制器和收发器已经就绪。否则NM PDU发不出去。
  • SM完成后通知ComM:ComM收到SM的就绪确认后,才通知NM开始发送NM PDU。
  • 三者各司其职:SM不管休眠协同(那是NM的事),NM不管硬件控制(那是SM的事),ComM不管具体执行细节(那是SM和NM的事)。
  • 第六章:COM中I-PDU组控制与信号超时监控

    SM对COM模块的控制主要通过两个机制:I-PDU组控制和信号超时监控。

    6.1 I-PDU组控制

    COM模块将需要发送的I-PDU组织成不同的组。SM可以根据当前的通信状态,动态地启动或停止这些组的发送。

    SM状态I-PDU组状态说明
    FULL_COM 所有组启动 正常通信,所有信号都可以发送
    SILENT_COM 所有组停止 静默模式,不发送任何信号
    Bus-Off恢复中 发送组暂停,接收组可能保持 故障期间暂停发送,避免错误帧扩散

    AUTOSAR COM模块为I-PDU组提供了状态管理功能,通过Com_IpduGroupStart和Com_IpduGroupStop接口来控制信号和I-PDU的接收与发送。当SM请求某个I-PDU组停止时,COM会将该组内所有信号的发送挂起,但对接收没有影响。

    6.2 信号超时监控

    SM还负责监控信号的超时。如果某个应该周期性接收的信号(如车速)在规定时间内没有更新,SM会上报信号超时事件。这个监控机制与COM的信号超时检测配合。当网络状态异常时,COM可能无法正常接收信号,SM可以检测到这种情况并上报故障。

    这种机制的意义在于:当网络正在恢复时(如Bus-Off恢复),SM可以暂时禁止信号超时监控,避免因为恢复期间的正常信号缺失而产生误报故障。

    第七章:SM的配置实践

    在AUTOSAR配置工具中,SM的配置相对直观,但有一些关键参数需要精心设定。

    7.1 CanSM的核心配置参数
    参数含义典型值
    CanSMBorCounterL1 Bus-Off恢复尝试次数(级别1) 3次
    CanSMBorTimeL1 Bus-Off恢复超时(级别1) 1000ms
    CanSMBorCounterL2 Bus-Off恢复尝试次数(级别2) 10次
    CanSMBorTimeL2 Bus-Off恢复超时(级别2) 5000ms
    CanSMMainFunctionPeriod CanSM主处理函数调度周期 10ms
    7.2 Bus-Off恢复策略的两级配置

    CanSM支持两级Bus-Off恢复策略:

    • L1恢复:较短的恢复超时,适用于偶发性Bus-Off(如强电磁干扰)。快速恢复后不记录故障。
    • L2恢复:较长的恢复超时,适用于持续性Bus-Off(如总线短路)。如果L2也恢复失败,则上报永久性故障给Dem。

    这种两级策略平衡了“快速自愈”和“故障报告”两个目标。偶发性干扰不应该被记录为故障码,但持续性硬件故障必须上报。

    第八章:代码模拟——CanSM状态机的完整实现

    现在我们来写一个模拟CanSM状态机的C程序,展示其核心逻辑。

    /**
    * @file can_sm_demo.c
    * @brief 模拟 AUTOSAR CanSM 状态机核心逻辑
    *
    * 本程序模拟 CanSM 的完整状态机:
    * UNINIT → INIT → COMM_FULL / COMM_SILENT / NO_COMM
    * 以及 Bus-Off 检测和自动恢复。
    *
    * 编译: make clean && make
    * 运行: ./can_sm_demo
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <stdint.h>
    #include <stdbool.h>

    /* CanSM 状态定义 */
    typedef enum {
    CANSM_UNINIT,
    CANSM_INIT,
    CANSM_COMM_FULL_READY,
    CANSM_COMM_FULL_BUS_OFF,
    CANSM_COMM_FULL_WAIT_BUS_OFF,
    CANSM_COMM_SILENT_READY,
    CANSM_COMM_NO_COMM
    } CanSM_State;

    static const char *state_names[] = {
    "UNINIT",
    "INIT",
    "FULL_COM_READY",
    "FULL_COM_BUS_OFF",
    "FULL_COM_WAIT_BUS_OFF",
    "SILENT_COM_READY",
    "NO_COMM"
    };

    /* CanSM 内部状态 */
    typedef struct {
    CanSM_State state;
    uint32_t state_entry_ms;
    uint32_t bor_start_ms; /* Bus-Off 恢复开始时间 */
    int bor_attempts; /* Bus-Off 恢复尝试次数 */
    int bor_timeout_ms; /* Bus-Off 恢复超时 */
    bool comm_active;
    } CanSM_Channel;

    static CanSM_Channel g_channel;
    static uint32_t g_sim_time_ms = 0;

    /* 模拟 ComM 的请求 */
    typedef enum {
    REQ_FULL_COMM,
    REQ_SILENT_COMM,
    REQ_NO_COMM
    } ComM_Request;

    static void can_sm_print_state(void)
    {
    printf(" [CanSM] 当前状态: %s | 通信活跃: %s | 时间: %dms\\n",
    state_names[g_channel.state],
    g_channel.comm_active ? "是" : "否",
    g_sim_time_ms);
    }

    static void can_sm_request_mode(ComM_Request req)
    {
    printf("\\n[ComM → CanSM] 请求: %s\\n",
    req == REQ_FULL_COMM ? "FULL_COMM" :
    req == REQ_SILENT_COMM ? "SILENT_COMM" : "NO_COMM");

    switch (g_channel.state) {
    case CANSM_UNINIT:
    printf(" [CanSM] 错误:未初始化,无法处理请求\\n");
    break;

    case CANSM_INIT:
    if (req == REQ_FULL_COMM) {
    printf(" [CanSM] INIT → FULL_COM_READY\\n");
    printf(" [CanSM] 启动CAN控制器…\\n");
    printf(" [CanSM] 配置CAN收发器为正常模式…\\n");
    g_channel.state = CANSM_COMM_FULL_READY;
    g_channel.comm_active = true;
    g_channel.state_entry_ms = g_sim_time_ms;
    printf(" [CanSM → ComM] 网络已就绪\\n");
    } else if (req == REQ_SILENT_COMM) {
    printf(" [CanSM] INIT → SILENT_COM_READY\\n");
    g_channel.state = CANSM_COMM_SILENT_READY;
    g_channel.comm_active = false;
    g_channel.state_entry_ms = g_sim_time_ms;
    } else {
    printf(" [CanSM] INIT → NO_COMM (保持)\\n");
    g_channel.state = CANSM_COMM_NO_COMM;
    g_channel.comm_active = false;
    g_channel.state_entry_ms = g_sim_time_ms;
    }
    break;

    case CANSM_COMM_FULL_READY:
    if (req == REQ_SILENT_COMM) {
    printf(" [CanSM] FULL_COM_READY → SILENT_COM_READY\\n");
    printf(" [CanSM] 停止所有发送I-PDU组…\\n");
    g_channel.state = CANSM_COMM_SILENT_READY;
    g_channel.comm_active = false;
    g_channel.state_entry_ms = g_sim_time_ms;
    } else if (req == REQ_NO_COMM) {
    printf(" [CanSM] FULL_COM_READY → NO_COMM\\n");
    printf(" [CanSM] 关闭CAN控制器…\\n");
    printf(" [CanSM] 收发器进入休眠…\\n");
    g_channel.state = CANSM_COMM_NO_COMM;
    g_channel.comm_active = false;
    g_channel.state_entry_ms = g_sim_time_ms;
    }
    break;

    case CANSM_COMM_SILENT_READY:
    if (req == REQ_FULL_COMM) {
    printf(" [CanSM] SILENT_COM_READY → FULL_COM_READY\\n");
    printf(" [CanSM] 重新启动所有发送I-PDU组…\\n");
    g_channel.state = CANSM_COMM_FULL_READY;
    g_channel.comm_active = true;
    g_channel.state_entry_ms = g_sim_time_ms;
    } else if (req == REQ_NO_COMM) {
    printf(" [CanSM] SILENT_COM_READY → NO_COMM\\n");
    g_channel.state = CANSM_COMM_NO_COMM;
    g_channel.comm_active = false;
    g_channel.state_entry_ms = g_sim_time_ms;
    }
    break;

    case CANSM_COMM_NO_COMM:
    if (req == REQ_FULL_COMM) {
    printf(" [CanSM] NO_COMM → FULL_COM_READY\\n");
    printf(" [CanSM] 启动CAN控制器…\\n");
    g_channel.state = CANSM_COMM_FULL_READY;
    g_channel.comm_active = true;
    g_channel.state_entry_ms = g_sim_time_ms;
    }
    break;

    case CANSM_COMM_FULL_BUS_OFF:
    case CANSM_COMM_FULL_WAIT_BUS_OFF:
    printf(" [CanSM] 当前处于Bus-Off恢复中,请求暂缓处理\\n");
    break;
    }

    can_sm_print_state();
    }

    static void can_sm_trigger_bus_off(void)
    {
    if (g_channel.state == CANSM_COMM_FULL_READY) {
    printf("\\n*** [模拟] CAN总线Bus-Off事件发生! ***\\n");
    printf(" [CanSM] 检测到发送错误计数达到255\\n");
    printf(" [CanSM] FULL_COM_READY → FULL_COM_BUS_OFF\\n");
    g_channel.state = CANSM_COMM_FULL_BUS_OFF;
    g_channel.comm_active = false;
    g_channel.state_entry_ms = g_sim_time_ms;
    g_channel.bor_start_ms = g_sim_time_ms;
    g_channel.bor_attempts = 0;
    g_channel.bor_timeout_ms = 1000; /* 1秒恢复超时 */
    can_sm_print_state();
    }
    }

    static void can_sm_process_bus_off(void)
    {
    if (g_channel.state == CANSM_COMM_FULL_BUS_OFF) {
    printf(" [CanSM] 启动Bus-Off恢复流程…\\n");
    printf(" [CanSM] 停止CAN控制器…\\n");
    printf(" [CanSM] 等待128次总线空闲…\\n");
    g_channel.state = CANSM_COMM_FULL_WAIT_BUS_OFF;
    g_channel.state_entry_ms = g_sim_time_ms;
    g_channel.bor_start_ms = g_sim_time_ms;
    g_channel.bor_attempts++;
    can_sm_print_state();
    } else if (g_channel.state == CANSM_COMM_FULL_WAIT_BUS_OFF) {
    uint32_t wait_time = g_sim_time_ms g_channel.bor_start_ms;
    if (wait_time >= g_channel.bor_timeout_ms) {
    if (g_channel.bor_attempts < 3) {
    printf(" [CanSM] Bus-Off恢复成功!(尝试%d)\\n",
    g_channel.bor_attempts);
    g_channel.state = CANSM_COMM_FULL_READY;
    g_channel.comm_active = true;
    g_channel.state_entry_ms = g_sim_time_ms;
    } else {
    printf(" [CanSM] Bus-Off恢复失败!已达最大尝试次数\\n");
    printf(" [CanSM] 上报Dem: CAN_E_BUS_OFF\\n");
    g_channel.state = CANSM_COMM_NO_COMM;
    g_channel.comm_active = false;
    g_channel.state_entry_ms = g_sim_time_ms;
    }
    can_sm_print_state();
    }
    }
    }

    static void *simulation_loop(void *arg)
    {
    (void)arg;
    int cycle = 0;

    while (1) {
    if (cycle == 0) {
    printf("\\n=== 初始化CanSM ===\\n");
    printf("[CanSM] UNINIT → INIT\\n");
    g_channel.state = CANSM_INIT;
    g_channel.state_entry_ms = g_sim_time_ms;
    can_sm_print_state();
    }

    if (cycle == 2) {
    can_sm_request_mode(REQ_FULL_COMM);
    }

    if (cycle == 5) {
    can_sm_trigger_bus_off();
    }

    if (cycle >= 6 && cycle <= 12) {
    can_sm_process_bus_off();
    }

    if (cycle == 15) {
    can_sm_request_mode(REQ_SILENT_COMM);
    }

    if (cycle == 18) {
    can_sm_request_mode(REQ_FULL_COMM);
    }

    if (cycle == 21) {
    can_sm_request_mode(REQ_NO_COMM);
    }

    usleep(300000);
    cycle++;
    g_sim_time_ms += 300;

    if (cycle >= 25) break;
    }

    return NULL;
    }

    int main(void)
    {
    printf("========================================\\n");
    printf(" AUTOSAR CanSM 状态机模拟程序\\n");
    printf("========================================\\n");
    printf("展示 CanSM 的完整状态机:\\n");
    printf("- 初始化与启动\\n");
    printf("- Bus-Off 检测与自动恢复\\n");
    printf("- 模式切换 (FULL / SILENT / NO_COMM)\\n");
    printf("========================================\\n");

    memset(&g_channel, 0, sizeof(g_channel));
    g_channel.state = CANSM_UNINIT;

    simulation_loop(NULL);

    printf("\\n========================================\\n");
    printf(" 模拟结束\\n");
    printf("========================================\\n");
    return 0;
    }

    Makefile:

    CC = gcc
    CFLAGS = -Wall -Wextra -O2 -std=c99
    LDFLAGS = -lpthread
    TARGET = can_sm_demo
    SRCS = can_sm_demo.c
    OBJS = $(SRCS:.c=.o)

    .PHONY: all clean run

    all: $(TARGET)

    $(TARGET): $(OBJS)
    $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

    %.o: %.c
    $(CC) $(CFLAGS) -c -o $@ $<

    clean:
    rm -f $(OBJS) $(TARGET)

    run: $(TARGET)
    ./$(TARGET)

    编译与运行:

    make clean && make
    make run

    预期输出:

    ========================================
    AUTOSAR CanSM 状态机模拟程序
    ========================================
    展示 CanSM 的完整状态机:
    – 初始化与启动
    – Bus-Off 检测与自动恢复
    – 模式切换 (FULL / SILENT / NO_COMM)
    ========================================

    === 初始化CanSM ===
    [CanSM] UNINIT → INIT
    [CanSM] 当前状态: INIT | 通信活跃: 否 | 时间: 0ms

    [ComM → CanSM] 请求: FULL_COMM
    [CanSM] INIT → FULL_COM_READY
    [CanSM] 启动CAN控制器…
    [CanSM] 配置CAN收发器为正常模式…
    [CanSM → ComM] 网络已就绪
    [CanSM] 当前状态: FULL_COM_READY | 通信活跃: 是 | 时间: 600ms

    *** [模拟] CAN总线Bus-Off事件发生! ***
    [CanSM] 检测到发送错误计数达到255
    [CanSM] FULL_COM_READY → FULL_COM_BUS_OFF
    [CanSM] 当前状态: FULL_COM_BUS_OFF | 通信活跃: 否 | 时间: 1500ms

    [CanSM] 启动Bus-Off恢复流程…
    [CanSM] 停止CAN控制器…
    [CanSM] 等待128次总线空闲…
    [CanSM] 当前状态: FULL_COM_WAIT_BUS_OFF | 通信活跃: 否 | 时间: 1800ms

    [CanSM] Bus-Off恢复成功!(尝试1)
    [CanSM] 当前状态: FULL_COM_READY | 通信活跃: 是 | 时间: 3000ms

    [ComM → CanSM] 请求: SILENT_COMM
    [CanSM] FULL_COM_READY → SILENT_COM_READY
    [CanSM] 停止所有发送I-PDU组…
    [CanSM] 当前状态: SILENT_COM_READY | 通信活跃: 否 | 时间: 4500ms

    [ComM → CanSM] 请求: FULL_COMM
    [CanSM] SILENT_COM_READY → FULL_COM_READY
    [CanSM] 重新启动所有发送I-PDU组…
    [CanSM] 当前状态: FULL_COM_READY | 通信活跃: 是 | 时间: 5400ms

    [ComM → CanSM] 请求: NO_COMM
    [CanSM] FULL_COM_READY → NO_COMM
    [CanSM] 关闭CAN控制器…
    [CanSM] 收发器进入休眠…
    [CanSM] 当前状态: NO_COMM | 通信活跃: 否 | 时间: 6300ms

    ========================================
    模拟结束
    ========================================

    结果解读:

  • 初始化:CanSM从UNINIT进入INIT状态,等待ComM的指令。
  • 完全通信:ComM请求FULL_COMM,CanSM执行启动序列,硬件就绪后通知ComM。
  • Bus-Off故障:模拟总线故障,CanSM自动检测并进入恢复流程。恢复成功后自动回到完全通信状态,应用层完全无感。
  • 静默模式:ComM请求静默,CanSM停止所有发送I-PDU组,接收仍保持。
  • 恢复通信:ComM重新请求完全通信,CanSM重新启动发送。
  • 关闭通信:ComM请求关闭,CanSM按正确时序关闭控制器和收发器。
  • 第九章:总结——SM,通信栈的秩序守护者

    朋友,通过今天的深度解析,我们完整地走过了SM的设计理念、状态机、四大职责、与ComM/NM的三角协作、以及对COM的控制。

    维度总结
    本质 SM是通信通道状态的管理者,是ComM的“执行代理”
    核心状态机 UNINIT → INIT → COMM_FULL / COMM_SILENT / NO_COMM,含Bus-Off子状态
    四大职责 启动控制、关闭控制、PDU与超时管理、Bus-Off自动恢复
    与ComM的关系 ComM决策“要不要通信”,SM执行“怎么启动/关闭硬件”
    与NM的关系 共用CanIf,NM负责协同休眠唤醒,SM负责硬件状态管理
    核心价值 将通信硬件的复杂控制封装在SM内部,对上层完全透明

    SM是AUTOSAR通信栈中的“秩序守护者”。它用精确的状态机管理着每一个通信通道从生到死的完整生命周期,用自动化的Bus-Off恢复机制保障着CAN通信的健壮性,用标准化的接口将ComM的宏观决策翻译成微观的硬件操作。

    正是有了SM的存在,ComM才能保持简洁和总线无关,NM才能专注于休眠唤醒协同,COM才能信赖通信通道的稳定可用。它是通信栈中最不显眼、但又最不可或缺的基石之一。

    赞(0)
    未经允许不得转载:171主机测评 » 通信服务的“幕后指挥”:深入理解SM(状态管理器)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址