ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

功能安全架构设计:失效可运行、双冗余与决策延迟的工程实践

功能安全架构设计:失效可运行、双冗余与决策延迟的工程实践 1. 从失效可运行说起功能安全架构到底在解决什么问题很多人第一次接触功能安全注意力都放在怎么把失效率算到 ASIL D上结果真正做架构评审的时候被问的第一个问题往往是这个模块失效了车还能不能安全地停下来——这就是**失效可运行Fail-Operational和失效安全Fail-Safe**的分水岭。功能安全的架构设计本质上不是让系统不出故障而是让系统在出故障之后仍然处于一个可控的安全状态。这句话听起来像废话但它决定了你后面所有的冗余策略、降级逻辑、监控机制怎么摆。传统工业控制里失效安全就够了——继电器一断机器停机安全。但放到自动驾驶场景情况完全变了一辆时速 100 公里的车如果因为某个传感器失效就直接停机那不是安全那是事故。所以自动驾驶对功能安全架构提出的核心诉求从失效即停升级成了失效可运行——系统必须带着故障继续工作一段时间把控制权平稳交出去或者维持最低限度的安全行驶能力。这就引出了本篇要拆解的几个关键词冗余、双冗余、失效可运行、决策延迟。它们不是孤立的概念而是一条链上的不同环节。冗余是手段失效可运行是目标决策延迟是约束条件而功能安全架构设计就是把这些东西捏合到一起的那套方法论。我见过不少团队一上来就堆双冗余双电源、双 MCU、双 CAN、双传感器硬件成本翻倍结果软件层面根本没做故障切换的仲裁逻辑两个通道各算各的最后输出打架反而制造了新的失效模式。这就是典型的为了冗余而冗余。架构设计的第一步永远是想清楚哪些失效必须容忍容忍到什么程度容忍多久。这三个问题答不上来后面所有的冗余设计都是空中楼阁。这篇文章适合谁看如果你正在做域控制器、线控底盘、智驾域的功能安全架构或者你在写 ISO 26262 相关的技术安全概念TSC和技术安全需求TSR再或者你只是想知道双冗余到底怎么落地那接下来的内容应该能给你一些可以直接抄作业的思路。我会尽量把原理讲透把踩过的坑摊开把参数和取舍逻辑摆到台面上。2. 失效可运行的三层架构从停得下来到跑得下去2.1 Fail-Safe 与 Fail-Operational 的边界在哪里先把概念钉死。Fail-Safe指的是系统检测到故障后进入一个预设的安全状态这个状态通常是停止输出或输出归零。电梯的抱闸、工业机器人的急停回路都是这个逻辑。它的前提是停止本身是安全的。Fail-Operational则要求系统在故障后继续提供部分或全部功能。注意是部分或全部不是全部。这里有个常见的误解以为失效可运行就是坏了也要跟没坏一样跑那不可能也不经济。真实的失效可运行是有降级等级的降级等级系统能力典型场景架构要求全功能100% 性能无故障单通道即可降级运行限速/限区域单点失效双通道热备最小风险状态靠边停车多点失效独立安全通道安全停车紧急制动严重失效纯机械/液压备份这张表是我自己在做架构评审时常用的一个抓手。你会发现失效可运行不是二值状态而是一个连续谱。架构设计的核心工作就是定义清楚每一级降级对应的触发条件、切换时间和可接受的功能损失。举个具体的例子。某 L3 域控的电源架构主电源来自整车 12V备份电源是一组超级电容。超级电容能撑多久假设域控满载功耗 40W超级电容组容量 25F电压从 12V 掉到 9V 可用那么能量 E 0.5 × C × (V1² - V2²) 0.5 × 25 × (144 - 81) 787.5J。按 40W 算理论支撑时间约 19.7 秒。但实际要考虑 DC-DC 转换效率假设 85%和电容老化余量按 80% 容量实际可用时间约 13 秒。这 13 秒就是你的失效可运行窗口——所有降级动作必须在这个窗口内完成。这个计算过程就是架构设计里必须写进 TSC 的东西而不是拍脑袋说加个电容就行。2.2 决策延迟 32.8 毫秒意味着什么热搜词里有个决策延迟 32.8 毫秒是否能够支持自动驾驶这个数字很值得掰开讲。32.8ms 是什么概念如果车以 120km/h 行驶33.3m/s32.8ms 内车移动约 1.09 米。如果以 60km/h 行驶16.7m/s移动约 0.55 米。这个延迟能不能接受取决于它在感知-决策-执行链路里的位置。完整的链路延迟包括传感器曝光与读出摄像头约 10-30ms、感知算法推理10-50ms、融合与预测5-20ms、规划决策10-50ms、控制指令下发1-5ms、执行器响应20-100ms。把这些加起来端到端延迟轻松超过 100ms。所以单看 32.8ms 这个数字它可能只是决策环节的延迟而不是端到端延迟。对功能安全架构来说延迟的意义在于它决定了你的安全裕度还剩多少。假设系统要求在最坏情况下 150ms 内完成从故障检测到安全状态切换而你的决策链路本身就占了 32.8ms那留给故障检测、仲裁、执行的时间就只有 117ms。这个预算必须提前分配好每个环节分多少谁超了谁负责。我在实际项目里踩过一个坑感知模块的故障检测用了看门狗超时阈值设了 50ms结果因为一次 GC垃圾回收停顿看门狗误触发系统进入降级。后来把阈值调到 80ms同时给感知线程加了实时优先级才稳定下来。这件事的教训是故障检测的时效性和误报率是一对矛盾阈值不能拍脑袋定要基于实测的延迟分布来定。我们当时统计了 10 万帧的推理延迟P99 是 42msP99.9 是 68ms所以 80ms 是一个既能覆盖极端情况、又不会频繁误报的值。2.3 冗余不是复制粘贴同构冗余与异构冗余的取舍说到冗余很多人的第一反应是搞两份一样的。这叫同构冗余优点是开发成本低、维护简单缺点是共因失效Common Cause Failure风险高——两份一样的东西遇到同样的环境干扰、同样的软件 bug可能同时挂掉。异构冗余则是用不同的实现方式做同一件事比如一份用规则算法、一份用神经网络或者一份用 C 写、一份用模型生成。它的核心价值是降低共因失效概率。但代价也很明显两套逻辑的输出可能不一致仲裁逻辑变得复杂开发工作量翻倍。我的经验是不要一刀切。关键的安全相关信号比如制动指令、转向角度用异构冗余非关键的舒适性功能用同构冗余甚至单通道就够了。具体怎么分看 ASIL 等级ASIL D 的安全目标建议异构冗余 独立监控通道ASIL C同构冗余 多样性监控ASIL B单通道 完善的诊断覆盖ASIL A/QM单通道 基础诊断这里有个容易被忽略的点冗余通道之间的独立性。如果两个通道共享同一个时钟源、同一路电源、同一块 PCB 上的相邻走线那它们的失效相关性就很高冗余效果大打折扣。ISO 26262 里有个独立性的要求具体到架构上就是物理隔离、电气隔离、时序隔离三件事。物理隔离好理解不同芯片、不同板子电气隔离指的是电源和地要分开避免一个通道短路拖垮另一个时序隔离指的是两个通道不能同时访问同一资源否则一个卡死可能阻塞另一个。3. 双冗余架构的落地细节从电源到通信的完整链路3.1 电源冗余超级电容、双电池与理想二极管电源是失效可运行的根基。主电源掉了后面所有冗余都是空谈。常见的电源冗余方案有三种方案一双电池并联 理想二极管。两组独立电池通过理想二极管或 ORing 控制器并联输出。优点是切换无延时缺点是电池本身也是共因失效源比如温度、老化而且两组电池的荷电状态需要独立管理。方案二主电源 超级电容备份。正常时主电源供电并给电容充电主电源掉电时电容放电维持。优点是电容寿命长、充放电快缺点是储能有限只能支撑秒级到十几秒。前面算过25F 的电容组大概撑 13 秒。方案三主电源 独立小电池备份。备份电池容量比超级电容大能撑几分钟但充放电管理复杂低温性能差。我参与过的一个项目用的是方案二但踩了个坑超级电容的均压电路设计不当导致单体电压不均衡用了半年后一组电容鼓包。后来改成主动均压 每季度自检才解决。电容组的均压和健康监测是电源冗余里最容易翻车的地方因为它不像电池有成熟的 BMS很多人以为电容免维护其实不然。理想二极管的选择也有讲究。普通二极管有 0.3-0.7V 压降在大电流下损耗可观。理想二极管用 MOSFET 替代压降可以做到几十毫伏。但要注意反向恢复时间和关断速度否则主备切换时会有电压跌落。实测下来好的 ORing 控制器切换时间可以做到微秒级对下游电路几乎无感。3.2 通信冗余双 CAN、双以太网与时间同步通信冗余的经典做法是双 CAN 总线但现在域控架构里越来越多用双以太网比如 100BASE-T1 或 1000BASE-T1。两种方案的核心诉求是一样的一条链路断了另一条能顶上且切换过程不能丢关键报文。双 CAN 的切换相对简单因为 CAN 本身是广播式、非确认的两条总线同时发就行接收端做去重。但要注意总线负载——两条都发负载翻倍如果原本负载就 60%翻倍就爆了。所以实践中常用主备模式而非双发模式主链路正常时备链路只发心跳。双以太网的切换复杂一些因为涉及 IP 地址、MAC 地址、VLAN 配置。常见的方案是链路聚合LAG或者冗余协议如 PRP/HSR。PRP 的做法是每个报文打两个标签从两条链路同时发接收端取先到的、丢弃重复的。它的优点是零切换延时缺点是带宽利用率只有 50%。HSR 则是环形拓扑报文绕环一圈任何一个节点故障都不影响但延迟会随节点数增加。时间同步是通信冗余里最容易被忽视的一环。如果两个通道各自有自己的时钟切换时时间戳可能跳变导致融合算法出错。所以要么用统一的 gPTP通用精确时间协议同步要么在切换时做时间戳平滑。我们当时的做法是主通道用 gPTP 同步到全局时钟备通道跟踪主通道的时间偏移切换时用偏移量做补偿实测时间跳变控制在 100 微秒以内。3.3 计算冗余锁步核、双核对比与异构 SoC计算单元的冗余主流有三种锁步核Lockstep两个核执行同样的指令每个周期对比结果不一致就报错。优点是检测延迟极低周期级缺点是只能检测随机硬件故障对系统性故障比如软件 bug无能为力而且两个核跑一样的代码共因失效风险高。典型芯片如英飞凌 AURIX 的锁步核。双核对比Dual-Core Comparison两个核跑同样的软件定期对比输出。比锁步核灵活可以跑不同版本的软件但对比粒度粗检测延迟大。异构 SoC比如一个 MCU 做安全监控一个 SoC 做高性能计算。MCU 负责监控 SoC 的心跳、输出范围、时序一旦异常就接管或降级。这种架构在智驾域控里很常见因为 SoC 性能强但功能安全等级低MCU 性能弱但可靠性高两者互补。我个人的偏好是异构 SoC 独立安全 MCU的组合。原因很简单SoC 的算力是刚需但它的功能安全能力比如锁步、ECC往往不如专用 MCU。用一个 ASIL D 的 MCU 做安全岛监控 SoC 的关键输出既保证了性能又满足了安全目标。代价是增加了通信开销和软件复杂度MCU 和 SoC 之间的接口需要精心设计。这里有个实操细节MCU 监控 SoC 时不能只看心跳还要看输出的合理性。比如 SoC 输出的转向角度指令MCU 要检查它是否在物理可行范围内、变化率是否超限、是否与车速匹配。这叫 plausibility check合理性检查是安全监控的核心手段。我们当时定义了十几条合理性规则每条都有明确的阈值和触发后的降级动作写进 TSR 里逐条验证。4. 故障检测、仲裁与降级架构里最烧脑的部分4.1 故障检测的覆盖率和误报率怎么平衡功能安全里有个指标叫诊断覆盖率Diagnostic Coverage, DC衡量的是有多少比例的故障能被检测出来。ASIL D 通常要求 DC ≥ 99%ASIL C 要求 ≥ 90%。但覆盖率不是越高越好因为提高覆盖率往往意味着更灵敏的检测而更灵敏意味着更高的误报率。误报的代价是什么如果误报导致系统降级用户体验受损如果误报导致安全停车可能引发后车追尾。所以误报率必须作为一个设计指标来管理而不是事后再说。我的做法是把故障分成三类分别设定不同的检测策略。第一类危险且可检测。比如电源电压超限、通信超时、计算结果越界。这类必须高覆盖率检测误报率控制在每千小时一次以内。第二类危险但难检测。比如传感器缓慢漂移、内存软错误。这类用周期性自检 冗余对比覆盖率可以低一些但要有趋势监控。第三类安全相关但非危险。比如舒适性功能失效。这类可以只做基础诊断甚至不检测。这个分类的逻辑是检测资源是有限的要花在刀刃上。把所有故障都按最高标准检测成本会失控而且误报率会飙升。4.2 仲裁逻辑谁说了算什么时候说了算冗余系统里两个通道的输出不一致时谁来仲裁这是架构设计里最烧脑的问题。常见的仲裁策略有主从仲裁一个通道是主另一个是从正常情况下听主的主失效了切到从。优点是逻辑简单缺点是从通道平时不输出它的健康状态难以验证。表决仲裁三个或更多通道投票多数决。优点是容错能力强缺点是需要至少三个通道成本高。优先级仲裁每个通道有优先级高优先级的输出优先采纳但低优先级通道可以否决高优先级通道如果检测到高优先级通道异常。这种策略在双通道系统里很常见。我参与的一个线控转向项目用的是优先级仲裁 交叉监控。主通道ASIL D负责正常转向监控通道ASIL B负责监控主通道的输出合理性。如果监控通道发现主通道输出异常它可以触发降级把转向切换到备份的机械/液压路径。这里的关键是监控通道不能直接接管转向它只能否决和触发降级因为它的安全等级不够。这个设计决策背后是 ISO 26262 的安全等级继承原则——低等级的东西不能直接控制高等级的安全目标。仲裁逻辑的另一个难点是切换时机。切早了可能误判切晚了可能来不及。我们的做法是引入确认窗口检测到异常后不立即切换而是在一个短窗口内比如 10ms持续观察如果异常持续存在才执行切换。这个窗口的长度要基于故障的最坏传播时间来定不能拍脑袋。4.3 降级策略从全功能到最小风险状态的平滑过渡降级不是啪一下从全功能跳到停车那样乘客体验极差而且可能引发二次事故。好的降级策略是分阶段、可逆、有提示的。分阶段的意思是先降性能比如限速再降功能比如关闭变道辅助最后才进入最小风险状态靠边停车。每个阶段都有明确的触发条件和持续时间。可逆的意思是如果故障是瞬态的比如一次通信干扰系统应该能自动恢复到更高等级而不是一旦降级就锁死。我们当时的做法是降级后持续监控如果故障消失且持续一段时间比如 30 秒就尝试恢复一级恢复失败则退回。有提示的意思是降级必须告知驾驶员通过仪表、声音、震动让驾驶员知道系统能力受限需要接管。这是 L2/L3 的强制要求也是功能安全架构里人机接口的一部分。这里有个血泪教训我们早期版本降级时只改了内部状态忘了通知 HMI结果驾驶员以为系统还在正常工作差点出事。后来把HMI 通知作为降级流程的强制步骤写进状态机里任何降级都必须先发通知再执行。状态机的设计要保证通知和执行的原子性不能出现通知失败但执行成功的情况。5. 从架构到代码那些文档里不会写的实操经验5.1 安全机制不能只写在文档里ISO 26262 要求把安全机制Safety Mechanism写进 TSC 和 TSR但文档写了不等于代码实现了代码实现了不等于验证过了。我见过太多项目TSC 写得漂漂亮亮代码里却找不到对应的实现或者实现了但参数和文档对不上。我的建议是每个安全机制都要有唯一的 ID从 TSC 到 TSR 到代码到测试用例全程可追溯。比如 SM-001 是电源电压监控那代码里就要有对应的函数、对应的配置参数、对应的测试用例。评审的时候随机抽几个 ID看能不能一路追到底。追不到就是漏洞。这个追溯链还有个好处需求变更时能快速评估影响范围。比如把电压监控阈值从 9V 改成 8.5V通过追溯链就能找到所有受影响的代码和测试不会漏改。5.2 故障注入测试不测不知道一测吓一跳故障注入Fault Injection是验证功能安全架构的终极手段。方法有很多硬件层面可以拔线、短接、注入电压软件层面可以 hook 函数、篡改内存、模拟超时。我强烈建议在架构设计阶段就规划故障注入测试而不是等到最后。因为很多架构缺陷只有注入故障才能暴露。比如我们曾经设计了一个双通道对比机制理论上能检测所有单点故障结果注入测试发现如果两个通道的对比逻辑本身有 bug同时失效系统就完全检测不到。这就是共因失效文档评审根本发现不了。故障注入的覆盖范围要包括单点故障、多点故障、瞬态故障、永久故障、边界条件。每个安全目标至少要有对应的注入用例且用例要通过。测试结果要记录在安全案例Safety Case里作为证据。5.3 工具链的坑编译器、RTOS 和认证功能安全项目对工具链有要求通常要求工具本身经过认证比如 TCL 等级。但现实是很多开源工具和商业工具都没有认证怎么办我的经验是工具认证不是目的工具输出的可信度才是。如果工具没认证就要做工具鉴定Tool Qualification证明它的输出是可信的。鉴定的方法包括验证测试、错误注入、与其他工具对比。编译器是个典型。GCC 没有功能安全认证但很多项目在用。怎么办要么换认证编译器比如 Tasking、Green Hills要么做编译器鉴定——用大量测试用例验证编译器输出的正确性特别是优化选项下的行为。我们当时做了几千个测试用例覆盖各种优化等级和边界情况才说服评审。RTOS 也是。AUTOSAR OS 有认证版本但贵。如果预算有限可以用经过验证的开源 RTOS比如 FreeRTOS 的安全版本但要做详细的静态分析和动态测试。关键不是用了什么而是能证明什么。6. 写在最后一些个人体会功能安全架构设计这件事做久了会发现技术难点往往不是最难的最难的是沟通和取舍。硬件团队想省成本软件团队想省工作量项目经理想赶进度而功能安全工程师要守住底线。怎么在各方压力下做出合理的架构决策比写代码难多了。我的原则是安全目标不能妥协实现方式可以商量。比如 ASIL D 的要求必须满足但用锁步核还是双核对比可以基于成本和场景来选。把必须和可以分清楚沟通就顺畅多了。另外别迷信标准。ISO 26262 是框架不是答案。它告诉你要做什么但不告诉你怎么做。具体的架构方案还是要基于你的场景、你的失效模式、你的成本约束来设计。我见过太多项目为了符合标准而做了一堆没用的冗余反而增加了复杂度和失效风险。标准是底线不是天花板。最后说个小事。有次评审一个年轻工程师问我怎么判断一个架构是不是足够安全我想了想说当你把所有能想到的故障都注入一遍系统都能进入安全状态而且没有误报那大概就够了。他问那想不到的故障呢我说那就是你下一步要做的功课。功能安全没有终点只有不断逼近的过程。
返回列表