尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AutoSar FiM功能抑制管理器:从原理到配置与故障排查

AutoSar FiM功能抑制管理器:从原理到配置与故障排查 去年处理过一桩让人挠头的售后疑难杂症一台新能源车在高速上开着开着突然加速踏板踩下去没反应了动力被明显限制好在还能维持巡航速度开到服务区。熄火重启后仪表正常去4S店用诊断仪读一个DTC都读不到。这种诡异现象很多人第一反应是偶发故障但真正的原因往往藏在AutoSar诊断协议栈里——ECU报过故障FiM模块Function Inhibition Manager功能抑制管理器悄悄把功能给限制住了。这篇文章就把FiM从原理到配置再到排查从头到尾讲透。它适合正在做AutoSar BSW集成、应用层功能开发或者调试整车疑难故障的工程师。看完之后你会明白那些灯灭了功能却回不来的投诉绝大部分都不是硬件问题而是FiM按配置执行了一次你没预料到的功能阉割。1. 从一次动力神秘消失的售后案例说起1.1 仪表盘没亮灯DTC也读不到谁来背这个锅售后工程师最怕的就是这种问题客户报障时信誓旦旦说车坏了可工程师一接诊断仪一个DTC都读不到仪表盘所有报警灯都是灭的。如果连故障码都拿不到维修工单根本没法往下走最后大概率以偶发故障建议观察收场。但客户不答应问题反复出现就成了疑难件。我当时介入之后第一步不是去看CAN报文也不是去复现故障而是先翻历史数据。结果发现这辆车在动力受限之前仪表盘上曾经短暂亮起过红色报警灯持续了不到一两秒就灭了客户自己都没太注意。这个细节是破局关键说明ECU确实检测到了故障并且上报给了诊断管理层只是因为某些原因这个故障没被确认所以最终没有形成DTC。这就牵扯出AutoSar诊断协议栈里一个特别容易被忽视的模块——FiM。FiM的全称是Function Inhibition Manager中文对应功能抑制管理器。它不做故障检测不存故障码也不处理UDS诊断请求它只干一件事根据诊断事件的当前状态决定某个功能是放行还是抑制。而抑制的意思就是它悄无声息地把原本应该正常工作的功能给关掉了关完之后还不留痕迹。1.2 完整诊断协议栈里FiM是最后一公里的决策者很多人聊AutoSar诊断眼睛只盯着Dcm、Dem和UDS那套东西这是不够的。一个故障从发生到真正影响整车行为中间要跨过一整条链路我习惯把它分成两段来看。通信链路是这么走的物理层的CAN或者CANFD收到诊断请求如果是多帧报文由CanTp负责分包、重组和流控然后经过PduR路由到DcmDcm解析UDS服务比如19服务读故障码、14服务清故障码再往下就是Dem的事。这条链路解决的是诊断报文能不能通、故障码能不能读出来的问题。决策链路则是另外一条逻辑应用层SWC或传感器驱动检测到异常调用Dem接口把诊断事件状态上报Dem维护这个事件的状态位比如TestFailed、ConfirmedDTCFiM周期性去读这些状态位结合外部输入条件电压、温度、时间等做一次布尔计算输出抑制/不抑制的结果。这个结果再往下可能直接被应用层使用也可能先交给BswM做模式仲裁最后才决定执行器怎么动作。两条链路一对比就清楚了Dcm和Dem处理的是故障怎么记、怎么读、怎么清FiM处理的是故障到底影响了哪个功能、要不要对这个功能下手。整车上的动力降级、跛行回家、部件保护、安全功能退出很大一部分背后都是FiM在推动。所以排查功能莫名其妙就没了这类问题光会读DTC远远不够必须把FiM的抑制逻辑一并纳入排查范围。2. 先把角色分清楚DEM负责记账FiM负责拍板2.1 DEM诊断事件的病历本在AutoSar架构里DemDiagnostic Event Manager诊断事件管理器负责给每个诊断事件建立一份完整的病历。每个事件有一个唯一的Event ID在ECUC配置里跟DTC编号绑定比如0x123456对应某个传感器信号不合理。这个ID一旦发布后面所有跟它相关的Debounce参数、老化参数、存储属性、FiM关联全部围绕它展开。Dem给每个事件维护了一堆状态位本质上是一个位掩码。最常用的几个状态位TestFailed本次检测结果为失败是一个瞬态状态下一次检测可能就变了TestFailedThisOperationCycle本次上电运行周期内发生过失败注意发生过三个字TestFailedSinceLastClear自上次执行过清DTC操作后该事件是否失败过PendingDTC故障具备成为历史故障的候选资格ConfirmedDTC故障已经确认常规诊断仪能读到的当前故障码主要看这个位看起来很简单对吧真正的工程难点在于什么条件下才置位。这个条件分两部分前半部分由SWC或传感器驱动决定比如检测到IGBT结温超过120°C就调用Dem_SetEventStatus上报后半部分由Dem内部的Debounce机制决定防止短时抖动直接形成故障。两个部分缺一不可。2.2 FiM拿着病历本做决策的家庭医生FiM做的事儿其实不复杂甚至简单得有点笨它周期性检查一组预设的抑制条件每个条件对应一个输出标志标志表示对应功能是否被抑制。但正因为简单它上面的映射关系才是工程上最需要花心思的地方怎么定义条件、拿什么事件去关联、关联哪个状态位才是真正的技术含量所在。一个典型的FiM抑制条件通常包含三类要素关联的Dem事件以及该事件需要达到的状态比如ConfirmedDTC外部输入条件比如系统电压、冷却液温度、环境温度这一类量多个子条件之间的逻辑组合是AND还是OR还是NOTFiM做决策时把这些输入拿过来按照配置算出一个布尔结果。为TRUE就抑制为FALSE就放行。应用层通过RTE接口或者BSW接口拿到这个结果然后决定执行器怎么动作。这里有个容易误解的地方FiM自己并不会直接去关压缩机、限扭矩它只输出允许/禁止的标记真正动手的是应用层软件。所以排查时如果发现功能被限制了不能只改应用层代码得往上追FiM为什么给了这个标记。2.3 状态位选择决定故障好了功能回不回来FiM配置里最容易被忽略、也最容易出问题的参数是抑制条件和Dem事件状态位的对应关系。同一个Diagnostic Event你可以让它在ConfirmedDTC时才抑制功能也可以让它只要TestFailedThisOperationCycle就抑制。这两个选择在故障瞬态下表现差别非常大。举个例子。某个电池包过温事件如果FiM关联的是ConfirmedDTC那么Debounce还没完成之前短时过温不会触发抑制如果关联了TestFailedThisOperationCycle情况就完全不一样了——只要本次上电周期内这个事件曾经失败过一次哪怕现在温度已经恢复正常、TestFailed位已经清零抑制依然保持到下电。这就是某些故障消失了、功能却没恢复的根本原因。你说FiM有毛病吗它没毛病它就是严格按照配置执行问题出在当初配置状态位时没有想清楚瞬态故障和确认故障的差别。以后遇到功能回不来的问题先查状态位往往会有惊喜。3. 一条功能抑制指令的完整旅程从传感器超阈值到执行器降功率3.1 故障进入DEM的两种方式要真正理解FiM跟着一条真实的抑制链路走一遍是最直观的方式。我用最常见的电驱动系统过温限制功率来做完整演示。第一步是故障进入Dem。AutoSar里应用层可以通过两种途径上报故障一种是在SWC里直接调用Dem_SetEventStatus比如电机的控制SWC检测到IGBT结温超过120°C就调用这个接口把对应Event ID置为FAILED另一种是通过硬件信号或者Com模块间接上报。无论哪种方式Dem只关心事件状态请求到了没有它自己不做阈值判断。阈值判断逻辑在哪做在被监控的SWC里做在传感器驱动里做反正不在Dem里做。这里就有一个特别常见的误解有人以为Dem本身会对传感器信号做阈值判断。不是的。Dem只做事件状态的管理和维护你给它喂什么状态它就维护什么状态。Debounce逻辑在Dem内部但什么情况下报故障的判断逻辑在上层。这个边界理清楚后面看问题会少走很多弯路。3.2 Debounce故障不能你说有就有事件请求进了Dem之后马上进入Debounce阶段。AutoSar支持两种Debounce策略计数器型CounterBased和时间型TimeBased。计数器型适合容易抖动的信号比如转速超速。每次检测到超速计数器加1没超速计数器减1计数器的值累加到门限才判定为故障。这样做的好处是抗干扰能力强一个两个毛刺根本翻不起浪花。时间型适合相对稳定的模拟量比如过温要求持续超过阈值多长时间才上报。Debounce存在的意义至少有两个一是滤除噪声和毛刺防止瞬时干扰造成误报二是给自恢复留出机会很多故障根本不用停掉功能抖动结束就没事了。所以FiM真正看到TestFailed状态时这个故障大概率已经持续了一段时间不是空穴来风。这也是为什么我不赞成把FiM的抑制条件放到TestFailed瞬态位上Debounce没完成的状态本来就不该拿来当抑制依据。3.3 抑制输出FiM怎么把决定交给应用层当Dem的状态位稳定置位后FiM在下一个周期到达时就会读到这个状态变化。FiM本身是周期运行的配置里会给每个Function设置一个执行周期10ms、20ms或者50ms都有可能。周期设置是个平衡点设太短BSW负载上升没必要设太长从故障确认到功能抑制的响应时间就太长安全性过不了。FiM算完的结果存放为一个内部标志应用层有两种方式拿这个标志直接调用BSW接口Fim_GetFuncStatus传入FunctionId通过RTE配置好的Sender-Receiver Port把抑制状态发给SWC第二种方式在量产项目里更常见原因也很实际应用层工程师不需要在代码里包含BSW头文件的依赖所有的接口关系通过RTE配置自动生成可读性和可维护性都好得多。拿到抑制标志后应用层才真正动手把扭矩目标值从100%降到30%把空调压缩机请求清零或者把最高车速限制到某个值。执行器看到的是应用层的降级策略但触发这个降级的总开关在FiM。3.4 恢复过程灯灭了功能为什么没回来抑制之后的恢复过程是生产现场最容易吵起来的话题。故障已经没有了温度也正常了为什么功能还不恢复原因至少要拆成三层来看。第一层Dem的TestFailed状态虽然清零了但ConfirmedDTC不会立刻清零它要经历老化Aging周期。确认故障要连续若干次测试通过才会被老化掉老化周期由AgingCycleCounter参数控制。所以故障恢复后历史故障码还会存在一段时间这是正常的。第二层FiM的抑制状态如果被配置成锁定或者从NvM恢复那么即使事件状态已经恢复FiM仍然输出抑制直到执行一次初始化或者满足解锁条件。这个行为不是Bug是功能专门用于那些不能因为故障闪烁就立刻恢复的安全场景。第三层如果抑制条件里还带了外部输入量比如温度必须低于某个值才能解除抑制那功能恢复还要等温度降到那个值以下跟DTC清没清没有直接关系。所以灯灭功能回只是一个理想期望。在做功能安全和售后策略时得提前把这种延迟恢复写入用户手册或者维修说明否则它就会变成新一轮的投诉点。4. 在ECUC里搭一个FiM功能抑制核心配置项与参数选择逻辑4.1 DEM侧的关键配置配置FiM之前得先确保Dem侧的Event配置是健康的。我见过太多FiM表现诡异的案子追到根儿上其实是Dem的Event配置没做对FiM只是在替Dem背锅。Dem侧这几个参数值得重点关注Event ID和DTC编号的绑定关系一个Event ID对应一个DTC绝对不能复用Debounce策略及门限计数器型要定义计数器上限时间型要定义持续时间老化策略AgingCycleCounter设成多少直接决定故障确认后多久能被清除存储属性事件状态存不存NvM存的话清除DTC后会不会留下尾巴其中跟FiM关联最大的是老化策略。如果某个功能抑制的解除条件是ConfirmedDTC需要清零那老化周期越短功能恢复越快但故障出现的次数会被更快遗忘不利于售后追溯。量产项目里老化参数的设置一定要跟功能安全目标和售后策略一起评审不应该是软件工程师拍脑袋定的。4.2 FiM侧的关键配置FiM侧最重要的配置对象我逐一列一下FimFunction一个被抑制的功能定义功能编号和计算周期FimInhibitionCondition一个抑制条件关联Dem事件和/或外部输入FimBlockingCondition逻辑组合告诉FiM多个抑制条件之间是AND还是OR实际配置界面里一个FimFunction下面可以挂多个FimInhibitionCondition每个条件有自己的状态掩码。比如冷却液温度事件系统电压低于9V两个条件都满足才抑制这就是AND关系另一个电机控制器过温事件只要满足就抑制和前面那组再做OR整体形成一条完整的抑制策略。这里强烈建议把每个抑制条件的含义、触发状态位、对应功能逐条列成矩阵表拿到评审会上逐条审核。不要觉得写文档浪费时间后面排查问题的时间会成倍还给你。我自己踩过这个坑项目前期的配置文档写得越潦草实车阶段排查越痛苦。4.3 上电初始化和NvM恢复最容易翻车的环节FiM模块上电后要经历Fim_Init初始化然后从NvM恢复上次存储的抑制状态。如果NvM里存的还是上次车辆处于抑制状态那本次上电之后应用层查FiM拿到的依然是被抑制的结果——就算这个循环里所有故障都是正常的也白搭。这正是换了一个ECU还是不行的原因。ECU换了但NvM块从旧件备份恢复过来了或者新ECU刷过EOL之后根本没有执行一次FiM数据初始化历史抑制状态原封不动地跟着新件继续服役。量产阶段EOL下线或者更换ECU后通常要执行一次诊断服务来清除FiM的存储数据在某些项目里会单独定义一个DID或者调用特定的例程控制服务。如果你遇到硬件是好的、软件也是新刷的、但功能就是被锁的反馈第一件事去查NvM里FiM的存储块是否被正确初始化这比查时序、查CAN报文都有效。NvM相关的坑绝大多数项目都躲不过早查早安心。4.4 配置评审别把所有判断都塞给FiM最后聊一个设计边界的问题。FiM适合做的是事件状态到功能抑制的确定性映射不适合做复杂的策略仲裁。比如高压上电时、涓流充电模式下、且电池温度低于0°C才允许充电这种逻辑它完全可以让充电管理SWC自己判断不需要经过FiM绕一圈。为什么因为FiM的能力边界就在抑制条件判断它的内部实现为快速计算布尔结果而设计在复杂条件组合下配置的可读性和可维护性会急剧下降。项目后期标定工程师想加一个环境温度低于-10°C时关闭自动泊车的条件如果放在BswM或SWC里改起来很直观如果堆在FiM里一层套一层改错了都不知道错在哪。我见过一个项目FiM里最多叠了六个抑制条件全都用AND和OR串在一起标定工程师改一版参数要对着文档核对半小时还经常改错。后面重构的时候把这套逻辑拆到了BswM状态机和SWC里问题一下子清爽了。所以配置评审时一定要问一句这个判断真的需要FiM来做吗5. 一次误阉割问题的排查链路复盘5.1 案例A定速巡航无法激活读不到任何DTC回到文章开头的场景。我当时的排查方式分了三步。第一步读所有DTC。结果是一个都读不到诊断仪界面干干净净。但注意此时我同时抓了CAN报文发现客户端发的19服务请求响应完全正常说明Dcm和Dem链路是通的故障确实不在存储层面。第二步用标定工具直接观测FiM相关变量。这里得益于手上有A2L文件能直接读FiM内部每个Function的抑制状态。结果发现定速巡航对应的那个FunctionReporting为BLOCKED其他功能全部正常。方向一下子锁定了故障不在功能层在FiM层。第三步反向查看抑制条件。展开这个Function关联的两个FimInhibitionCondition其中一个关联的是前向摄像头失准事件状态掩码配的是TestFailedThisOperationCycle。再看这个事件的历史状态发现它在两个驾驶循环之前短时失败过一次持续时间不到200ms远没有达到ConfirmedDTC的门槛但因为状态掩码包含了TestFailedThisOperationCycleFiM判断抑制条件成立定速巡航就一直被锁到现在。这种问题修复很简单把状态掩码改成ConfirmedDTC级别让瞬时失败不再触发抑制。但更重要的是这次排查暴露了系统工程师在定义什么故障该抑制什么功能时根本没有区分瞬态故障和确认故障。如果你的项目也遇到偶发一次故障功能就永久变砖的投诉去检查所有FiM抑制条件的状态掩码大概率能揪出一批配置过激的项。5.2 案例B更换ECU之后功能依然被锁另一个案例更有意思。某车型自动紧急制动功能报故障维修技师按常规流程更换了前视摄像头控制器重新刷写程序、做了标定结果AEB功能依旧不可用。一连换了两个控制器问题依旧客户直接投诉到厂家。参与排查后我先确认故障码状态读取到一个AEB禁用事件仍处于ConfirmedDTC。诡异的是硬件已经换了新件按道理不应该再报。看原始值才发现这个事件的老化计数器停在一个非常高的值上说明生命周期内曾经反复过温。问题出在清码流程上。维修工单执行了14服务清除DTC但这个事件配置了NvM存储老化计数和FiM的历史抑制状态都存在NvM块里。14服务把当前确认状态清了却没有把NvM里的历史老化计数清零FiM从NvM恢复后依然认为这个事件曾经确认过于是持续输出抑制。处理方案是更换控制器后额外执行一次专用的例程控制服务把FiM和Dem相关的NvM块恢复出厂默认值。经过这个案例之后我养成了一个习惯只要设计文档里出现更换控制器后需重新标定字样一定要让诊断工程师确认是否已经覆盖NvM恢复逻辑。这个坑几乎每个项目都会遇到提前确认能省一大笔售后费用。5.3 排查工具与方法清单这几个案例做下来我的体会是自动诊断FiM相关问题最快的手段是直接读内部状态变量而不是只靠诊断仪。常用的方法有这几种标定工具INCA CANape配合A2L文件直接观测Fim_GetFuncStatus、各抑制条件的内部信号CANoe的CAPL脚本周期性读取RTE变量记录功能抑制状态和Dem事件状态的时间戳用来判断是先有故障还是先有抑制XCP或者DET日志打开BSW模块的调试打印看FiM每次计算的输入和输出模拟注入用标定工具强行修改Dem事件状态位验证FiM响应是否符合预期这些手段组合起来可以在几分钟内把故障到状态到抑制到输出整条链路跑一遍。排查思路的核心原则只有一句话不要把FiM当黑盒。所有决定都来自配置所有配置都是可读的只是你还没找到读它的入口。6. 几个容易被忽略的设计细节与个人体会6.1 EventStatusMask的选择要跟功能安全目标挂钩量产项目里配置FiM时我最在意的是这个抑制条件选哪个状态位。如果被抑制的功能涉及安全比如助力转向、制动辅助我宁可配置成ConfirmedDTC级别让故障充分确认后再抑制防止瞬时扰动导致安全功能意外退出如果被抑制的功能只涉及舒适性比如自动空调、座椅加热那可以用更敏感的状态位早一点关掉避免故障扩大。这个取舍没有绝对的对错但必须有意识地去选。很多项目默认用工具链自动生成的掩码根本不去审视这个位背后的含义等到实车测试才发现传感器抖了一下空调就罢工了半天这时候再改配置涉及的面就非常大了。所以在ECUC评审阶段我会要求系统工程师在每个FimInhibitionCondition旁边用注释写清楚为什么这个事件选这个状态位。写不出来的请回去想明白再来评审。6.2 分级降级比一刀切更合人情FiM不只支持全有或全无的抑制它支持一个功能对应多个Function输出分别代表不同的降级等级。比如电池系统可以定义三个等级等级1正常等级2限制放电功率到70%等级3完全禁止放电。应用层根据这三个标志位做分级处理而不是拿一个BOOL值走到黑。这种分级设计的好处是用户对动力下降的感受远好于直接抛锚而且系统可以在故障恢复后更平滑地回到正常状态。从软件实现角度多定义两个Function和多写几行配置的代价非常小但对用户体验的改善是实打实的。经历过几个项目之后我现在做FiM配置时默认就会把降级等级拆出来而不是一上来就搞全禁止。6.3 我的配置习惯先做矩阵再动工具最后分享一个我个人长期坚持的工作习惯。每次接手带FiM的项目我不会急着打开配置工具而是先在Excel里建三张表。第一张是事件清单列出所有Event ID、DTC、Debounce参数、Aging参数这一张表管Dem侧的全局视图。第二张是抑制条件矩阵横轴是功能纵轴是事件和输入条件交点填状态掩码和动作类型这一张表管FiM的映射关系。第三张是恢复条件表写明每个被抑制功能在什么条件下解除抑制包括依赖的事件状态、外部输入和NvM恢复逻辑。三张表建完之后再对照ECUC配置逐项走查基本能挡住90%以上的配置低级错误。这个做法看起来慢实际上比上线、联调、标定阶段到处救火要快得多。我带过的开发人员只要坚持做过一个完整项目的矩阵后面基本不会再问FiM到底怎么配这类基础问题。FiM这个模块单看代码量不大代码逻辑也谈不上复杂但它处在BSW和应用层的交界处牵涉到Dem、NvM、BswM、RTE一堆模块的交互。任何一个环节的配置理解不到位最终都会在实车上变成功能莫名其妙消失的疑难杂症。把角色边界、配置要点和排查思路理清楚之后下次再遇到类似被阉割的故障你至少知道该从哪个模块、哪层配置开始动手。
返回列表