4. Stateflow状态机基础
Stateflow 是 Simulink 中用于描述事件驱动逻辑与模式切换的图形化建模工具。在 AUTOSAR 组件建模中,它通常被放在 SWC 内部的可运行实体(Runnable)中,用来实现模式管理、状态仲裁、故障降级、初始化序列等控制逻辑。要能正确建模并生成符合 AUTOSAR 规范的 C 代码,必须先掌握 Stateflow 的八个基础要素:状态、转移、事件、条件、动作、默认转移、历史节点和状态层次结构。它们共同决定了“什么时候进入哪个状态、进入后做什么、离开时又做什么”。
一、状态:逻辑驻留的最小单元
状态(State)表示系统在某一时刻所处的稳定模式。在 Stateflow 中,状态用圆角矩形表示,内部可以写 entry、during、exit 三类动作。例如一个简单的“运行/停止”状态机中,Run 状态的 entry 动作可以写 MotorCmd = 1;,exit 动作写 MotorCmd = 0;。状态是否处于激活(active)状态,由 Stateflow 的语义自动维护,不需要用户手动置位。
状态还带有 en、du、ex 等动作标签,分别对应进入、驻留和退出。AUTOSAR 代码生成时,这些动作会被映射到 Runnable 内部的 C 语句,因此动作中应尽量只使用 SWC 的端口变量、内部参数和局部变量,避免直接访问全局硬件寄存器。
二、转移、事件与条件:状态切换的三要素
转移(Transition)是连接两个状态的有向箭头,表示状态切换的路径。一条完整的转移通常由三部分组成:事件(Event)、条件(Condition)和动作(Action),书写形式为 event[condition]{action}。例如 EvStart[Speed > 0]{Mode = 1;} 表示:当事件 EvStart 发生且条件 Speed > 0 成立时,执行动作 Mode = 1; 并沿该转移迁移到目标状态。
事件分为输入事件、本地事件和广播事件。在 AUTOSAR SWC 中,输入事件通常来自 RTE 端口或定时触发,本地事件由状态机内部产生。条件是一个布尔表达式,只有为真时转移才可能被触发。动作则是在转移被选中后、进入目标状态之前执行的语句。需要注意:转移动作先于目标状态的 entry 动作执行,这一点在初始化序列中非常关键。
三、默认转移:状态机的入口
默认转移(Default Transition)是从状态框外指向某个状态的箭头,表示状态机首次激活或父状态首次进入时默认进入哪个子状态。每个层次结构都应有明确的默认转移,否则代码生成时可能产生未初始化路径。例如在一个 Supervisor 父状态下,默认转移指向 Init 子状态,保证上电后先进入初始化。
四、历史节点:记住上次离开的位置
历史节点(History Junction)用于记录父状态上次退出时所处的子状态。当父状态再次被进入时,如果使用历史节点,状态机会回到上次离开的子状态,而不是重新走默认转移。历史节点分为浅历史(Shallow History)和深历史(Deep History)。浅历史只恢复父状态直接子层的状态,深历史则递归恢复到最内层。在 AUTOSAR 模式管理中,历史节点常用于“故障恢复后回到故障前的运行模式”这类需求。
五、状态层次结构:父子状态与并行状态
状态可以嵌套,形成父子层次结构。父状态的 entry 动作先于子状态执行,exit 动作后于子状态执行。这种层次关系让公共动作可以上提到父状态,减少重复。Stateflow 还支持并行(AND)状态,即同一父状态下多个子状态同时激活,用虚线分隔。并行状态适合描述“控制模式”和“诊断监控”同时运行的场景。
下面这张图把本节的核心要素放在同一个状态机结构中:Supervisor 父状态包含 Init、Run、Fault 三个子状态,默认转移进入 Init,历史节点记录 Run 与 Fault 的切换位置,转移上标注了事件、条件和动作。
六、动作的执行顺序与代码生成映射
理解动作执行顺序是避免 AUTOSAR 代码生成错误的关键。当一次转移被触发时,Stateflow 按以下顺序执行:先执行转移上的动作,再执行源状态的 exit 动作,然后执行目标状态的 entry 动作,最后进入目标状态的 during 动作。如果目标状态还有子状态,则继续按默认转移或历史节点进入相应子状态,并执行其 entry 动作。
在 AUTOSAR 代码生成中,Stateflow 状态机通常被封装为一个 Runnable,例如 RE_ModeMgr。状态变量会被生成为静态局部变量或 SWC 内部变量,事件则通过 RTE 的 Rte_Read 或 Rte_Switch 接口获取。因此,建模时应确保事件来源明确、条件表达式不依赖未初始化变量、动作中不出现阻塞调用。
七、建模实践中的常见问题
- 缺少默认转移:父状态没有默认转移时,首次进入可能停留在父状态而不进入任何子状态,导致输出未定义。
- 历史节点与默认转移混用不当:如果希望每次上电都从 Init 开始,就不应在 Init 所在层级使用历史节点。
- 转移条件重叠:同一源状态的多条转移条件同时为真时,Stateflow 按从上到下的优先级选择第一条,容易造成逻辑歧义,应通过互斥条件或优先级顺序明确。
- 动作中直接访问硬件:AUTOSAR SWC 应通过端口访问外部信号,动作中直接写寄存器会导致代码无法通过 RTE 集成。
掌握这八个要素后,就可以用 Stateflow 描述从简单的模式切换到复杂的多级故障降级逻辑。下一阶段需要进一步理解状态机的执行语义,包括事件广播、并行状态的同步以及状态动作与转移动作的精确时序,这些将直接影响生成代码的行为是否符合 AUTOSAR 组件的设计意图。