FS-C5 — Silent Data Corruption:静默误算如何击穿 FMEDA 的 DC/LFM 假设,以及为什么它是"重审每个 DC 值"而不是"再加一个安全机制"
本质与导读
专家养成 · 模块一(功能安全)· C 阶第 5 讲。上一讲 FS-C4 把 SEooC 的 ASIL 声明还原成一个条件命题「ASIL D | AoU 成立」,并留下一个没被质疑的乐观假设:只要安全机制 enable 了、数字算对了,芯片就真在按 FMEDA 说的那样工作。今天拆穿这个假设最阴的一种反例——芯片算错了却不报错:ALU 偶发位翻转恰好没触发任何诊断,算出一个合法但错误的结果,顺着数据流一路流进刹车/转向决策。这类**静默数据腐蚀(Silent Data Corruption, SDC)**不改变任何代理信号,却能同时击穿 FMEDA 里 DC 与 LFM 两个隐含前提。它是本课程第一次遇到"错误本身不可观测"的故障类,处理它的方法论也因此和前面所有 SM 讲不同。
开篇:硬约束——FMEDA 的全部数学押在两个隐含前提上,SDC 同时违反两个
功能安全的定量体系(SPFM / LFM / PMHF)看似复杂,但它成立只靠两个从不写在公式里、却处处默认的前提:一个危险失效发生后,要么被某个安全机制在 FTTI 内抓到并进安全态(→ 计入 DC),要么它本身概率低到可忽略(→ 计入残余/潜伏但量级极小)。 换句话说,FMEDA 默认"危险 = 可观测的危险 + 罕见的危险",没有第三类。
SDC 恰恰是那个不存在的第三类:它既不被抓到、概率也不低。 Meta 在数百万机时的车队级扫描里得出约每 1000 颗硅器件就有 1 颗带 SDC 缺陷(远高于宇宙射线软错误历史上约 1/百万的量级,据 Dixit et al., arXiv:2203.08989);Google 同期把这种"间歇算错的单个核"命名为 mercurial core,其错误叫 CEE(Corrupt Execution Error),并强调这些缺陷逃过出厂测试、运行数月后才显形(Hochschild et al., HotOS 2021)。两个前提被同时打穿,后果不是 FMEDA 少算一项,而是它给计算逻辑填的每一个 DC 值都可能是虚的——纸面过 ASIL D,实物不过。
这对汽车是直接威胁而非数据中心专属:AD/ADAS 域控用的是同一代高算力 SoC(同制程节点、同设计方法学、同测试覆盖逻辑),继承同样的 SDC 风险,却要扛车规 15 年、 到 、振动与电压瞬态带来的加速老化;而数据中心能"多机投票 + 重算"兜底,车上一帧感知误算可能直接变成错误的刹车决策。下面从第一性原理推:它为什么静默、为什么三大 SM 都有盲区、以及为什么解法是重审 DC 而不是叠 SM。
中段一:第一性原理——"静默"的根因是故障落在逻辑里,不在存储里
要理解为什么 SDC 无法被常规手段观测,先把一个计算单元(ALU、乘法器、地址生成、datapath)在故障下的三种结局钉清楚,区别只有一句话:系统是否知道自己错了。
- 算对(correct):无事。
- 报错停(DUE, Detected Unrecoverable Error):故障落在有 check logic 的电路(存储位、总线),ECC/parity/trap 抓到,触发机器检查异常,系统能停或重算——这是"好"的失效,它至少可观测、可进安全态。
- 静默错(SUE / SDC):故障落在没有 check logic 的电路部分,所以电路照常输出,只是输出是错的。系统不知道,错误结果继续流。
SDC 的内核是第三种,关键词是 wrong-but-alive(算错但活着)。它为什么静默,答案在物理层:SDC 的源头是计算逻辑/datapath 上的边缘晶体管(marginal transistor),而不是经典 EDAC 模型关注的存储位翻转。先进制程把工艺涨落放大,总有一小撮单元处在"刚好能工作"的边缘,在特定数据模式、特定电压/频率/温度组合下才给出错误逻辑值——这解释了为什么 SDC 既间歇又数据相关(同一个核,某些 bit pattern 错、另一些对,换温度又变),也正是它躲过确定性出厂测试的原因。老化(BTI/HCI 使最低工作电压 Vmin 上漂)让原本有裕度的路径在运行数月后变成关键路径,违反"早期失效后进入低故障率平台"的浴盆曲线假设。
记住这条因果:错误产生于"计算之后、写回之前"的组合逻辑里,而所有护存储的手段都在"写回之后"才介入。 这一时序错位是下一节所有 SM 盲区的共同根源。
中段二:为什么三大安全机制各有一块 SDC 钻得过去的盲区
ASIL D SoC 引用得最多的三个 SM——ECC、lockstep、看门狗——对 SDC 的覆盖不是"低",是在特定失效模式上系统性趋近于零。三个盲区根因不同,必须分开看,否则会误以为"我三个都上了就够了"。
ECC 只护存储,护不到计算。 ECC 的作用域是数据"静止或搬运"时(SRAM/DRAM/cache/总线),读出时校验冗余位。但 SDC 的错值是 ALU 交出来的——ECC 完全相信计算单元的输入,给一个错值算出"正确"的校验位一起写进存储。ECC 校验的是"存进去有没有被翻位",不是"算出来对不对"。对 datapath SDC,ECC 的 DC 近似为 0。
Lockstep 抓单点、对共因无效。 双核锁步逐周期比对,只要两核缺陷不同,错核与对核一比就露馅——它确实能覆盖一大类 SDC。但两个核是同一版图、同制程、紧邻布局、共享电压/时钟/温度域,若缺陷源于设计/工艺共性(同一 marginal 路径),在相同输入下两核同时算出同一个错值,比较器看到"一致",判为正确。这是共因失效(CCF)对 lockstep 的经典攻击面。所以 lockstep 的 SDC 覆盖高但不等于 1,残余项正是 因子那部分,必须在 FMEDA/DFA 里显式计入,不能默认 lockstep 。
看门狗只抓死机,抓不到"算错但活着"。 看门狗假设故障会让程序卡死或跑飞,从而停止喂狗。SDC 的致命之处恰恰是核没死、没跑飞、按时喂狗,只是某次乘法结果错了。Q&A 看门狗能抓控制流错误,但对一次纯数据流误算(感知特征图某像素算错),狗照样按时被喂,DC 近似为 0。这是看门狗作为 SM 的固有边界,也呼应 FS-C3 里看门狗覆盖不到的那一类。
三个盲区拼在一起就是一个洞:wrong-but-alive 的纯数据流误算,三大 SM 全部趋近 0 覆盖。 下一节把这个洞代回 FMEDA,看数字怎么虚高。
中段三:核心推导——DC 虚高如何把 SPFM/LFM 算过线(worked example)
FMEDA 把危险失效率 按 SM 覆盖拆成被检测部分与残余部分,残余失效率是:
单点故障度量的定义:
问题的杠杆全在 这个因子上。DC 越接近 1,残余项对 DC 误差越敏感:DC 从 掉到 , 从 变 ,残余项直接 。这就是 SDC 的破坏力——它不是让某个 DC 略降,而是让一个填着 的格子真实值趋近 。
走一个具体的账,以双核锁步安全岛的一个 CPU 单元为例(参数取 Infineon AURIX 典型值,示意,非逐一实测):
- 单元危险失效率 ()
- 锁步间共因因子 ,于是 CCF 片段
错误做法(把 CCF 也算进锁步的 99%):FMEDA 一行写 覆盖全部 ,则这 的 CCF 残余被记为
但锁步对 CCF 的真实 DC 是 (两核同错,比较器判"一致")。若此外没有任何针对 CCF SDC 的手段,真实残余是
即被低估 倍——这 会漏进 SPFM 分子却没人记,SPFM 纸面达标、实物不达标。
正确做法(给 CCF 片段配专用 SM):CCF SDC 唯一够得着的手段是周期在线自检——LBIST(冷启结构扫描,典型结构覆盖约 )+ SBST/STL(运行间隙功能自检)。把 CCF 片段单独列行、用 LBIST 的 DC 算:
注意:修正后的残余 仍是错误声明 的 倍——不是因为多算了,而是因为原来那 是假的。这 就是"把 SDC 盲区诚实入账"要在 SPFM 分子上多背的债;背不动就得加手段,而不是把它抹平。
LFM(潜伏故障度量)更隐蔽:SDC 的本质就是 latent——它静默存在,直到某次被它污染的计算决定了一个安全动作。若系统没有针对 SDC 的周期性在线自检,这些模式在 LFM 里应记为"未覆盖";很多 FMEDA 却默默算成被 lockstep/ECC 覆盖,于是 LFM 也虚高。关键区分:LBIST 是上电跑一次的结构扫描,只覆盖启动瞬间的潜伏故障;满足 LFM 的周期检测必须靠 SBST 在运行间隙分片重复跑。
而 SBST 分片受一条硬时序约束(接 FS-A3 的 FTTI 总账):
以 LKAS 安全函数为例,、,则自检必须在 内跑完一轮。AURIX STL 典型分 120 段、每段占 任务周期的 (CPU 占用 ,不阻塞实时调度),完整一轮:
余量 (约 6 帧 @ 帧)。这一步把"有 SBST"从文字声明变成了可验证的时序数——SBST 分片一旦被高优先级任务抢占、实际 FDTI 漂到 之外,LFM 覆盖就是空头支票。
落到工程结论:SDC 是"重审每个 DC",不是"再加一个 SM"
把上面拼成可执行的纪律。SDC 与前面所有 SM 讲最大的不同是:它没有银弹 SM——任何单一手段都有盲区,正确做法是让每一类 SDC 失效模式都落在至少一个有实测 DC 的正交手段下(异构空间冗余 / 时间冗余+软件多样性 / SBST+LBIST 周期自检 / fault injection 实测 DC / fleet 监测管老化),缺口在 FMEDA 里诚实记为残余风险,而非用虚高 DC 抹平。带走四条准则:
- DC 值默认有罪,直到 fault injection 证明。 凡是声称覆盖计算逻辑的 DC,审查时专问一句:"这个 SM 在 FTTI 内怎么感知到 wrong-but-alive?"答不出即是 SDC,把该 DC 打到接近 。故障注入是唯一能把 DC 从"假设"变"实测"的手段。
- 锁步 DC 必须拆出 CCF 片段。 比例单独列 CCF 行、DC 归 、进 DFA,配 LBIST+SBST 的实测 DC;混进单点行的 会让残余低估约 (甚至 ,若根本没配自检)。
- LBIST ≠ SBST,冷启 ≠ 周期。 LBIST 冷启一次喂不饱 LFM;运行期 latent SDC 靠 SBST 周期调度,且分片时序必须过 timing analysis(),不能只凭"有 STL"。
- 软件多样性 ≠ 异构硬件。 同源代码换编译器仍跑同一 datapath 微架构,共因缺陷不降;真正异构是不同微架构(主 SoC 感知 + 独立安全岛合理性校验),CCF 才显著下降。且监督者自身也会 SDC——安全岛需要一个制程正交的独立物理层(如 BCD 工艺 SBC)兜底,防"静默误算的裁判宣判一切正常"。
承上启下:今天我们看清 SDC 是本…
承上启下:今天我们看清 SDC 是本课程第一个"错误不可观测"的故障类——它让 FMEDA 的两个隐含前提(危险要么可检测、要么罕见)同时失效,把填着 的 DC 悄悄变成接近 ,SPFM/LFM 纸面过实物不过;解法不是加一个 SM,而是重审每个覆盖计算逻辑的 DC、让每类失效模式落在有实测 DC 的正交手段下。但 SDC 讲的是"一个核算错自己的结果";更普遍的一类静默污染是一个功能损坏了另一个功能的资源——低 ASIL 任务写飞指针踩了 ASIL D 任务的内存、抢了它的 CPU 时间、堵了它的总线,而后者毫不知情。下一讲 FS-C6 拆 Freedom From Interference(无干扰):混合关键性系统里时间/空间/资源三类隔离怎么证,以及为什么"没有干扰"和"检测到干扰"是两条不同的论证路线。预热可读 无干扰(FFI)。
延伸阅读
- Silent Data Corruption 安全深度 — 本讲的完整版:故障分类学、三大 SM 盲区因果链、5 类防御栈覆盖矩阵、TC397 AURIX 安全岛量化 worked design、7 条 gotcha + 3 个 corner
- 共因失效(CCF)深度 — lockstep 的 SDC 盲区本质是 CCF,残余项由 因子决定
- FMEDA 深度 · 诊断覆盖率分级 — SDC 让计算逻辑的 DC 被系统性高估,需重审
- Fault Injection 测试深度 — 把 DC 从"假设"变"实测"的唯一手段
- FS-C4 SEooC 接口闭合 · FS-A3 FTTI 时间预算 — 本讲"芯片按 FMEDA 工作"的假设来源,与 SBST 时序约束的 FTTI 总账
- 功能安全工程师指南(模块 hub)