在前面我们详细探讨了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需要
进入完全通信模式"
-
检查CAN控制器当前状态
-
配置CAN收发器进入正常模式
-
等待Bus-Off恢复?
-
确认网络稳定后通知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_OFF
Bus-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收发器 CanDrv CanIf CanSM ComM CAN收发器 CanDrv CanIf CanSM ComM #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收发器 CanIf CanSM ComM CAN收发器 CanIf CanSM ComM #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同意休眠了吗?" |
一个完整的上电到通信就绪的流程是这样的:
CanIf CanNm CanSM ComM SW-C CanIf CanNm CanSM ComM SW-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程序,展示其核心逻辑。
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:
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)
编译与运行:
bash
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才能信赖通信通道的稳定可用。它是通信栈中最不显眼、但又最不可或缺的基石之一。