千错万错,都是中断和堆栈惹的祸!

  作者:光华居士 时间:2018-09-07来源:电子产品世界
      要命的故障

四月的重庆已然百花盛开,春回大地,大自然又恢复了勃勃的生机,燕子挥舞着银光闪闪的翅膀,在湛蓝而悠远的天空中无拘无束地飞翔着,时而快速扇动着翅膀冲上天空,时而展开双翼低低滑翔。在吸饱了四月新雨的潮气的湿润空气中,小草显得格外清新,绿油油地,就像一汪春水,在春风的吹拂下,荡起粼粼的水波。草地不远处的停车场上,两位面容憔悴、因睡眠不足而眼角发黑的工程师紧张而激烈地讨论着,在空旷而幽静的试验场里,他们的声音格外引人注目。

“是不是因为汽车行驶过程中,电磁环境的干扰造成CAN总线数据中某些位发生了变化,所以才造成无缘无故解锁车门的情况?”同事抬起肿胀的眼皮,带着询问的神情,小心翼翼地问我。

“不会的,CAN总线的协议里本身就有CRC校验,如果数据位出错,CAN报文中的CRC校验是通不过的,这时CAN控制器会提示错误的。”这次故障发生在产品功能验证已经通过,量产前的实车路试过程中,如果问题解决地慢,可能需要重新路试,第二次路试的所有费用都得我们来掏,所以我的心情怎么也好不起来,于是我口气生硬地回答他。

我们做的产品是车身控制器,俗称BCM,这次路试出现的故障现象极其明了,就是在开车过程中,没有任何操作的情况下,突然解锁或者突然闭锁,或者突然后背门解锁了,来了两天,一直没有找到引发故障的原因,弄得我茶饭不思,苦闷到了极点。

“找车厂路试人员,我再跟他上车跑一下,观察一下现象吧!”做为这次产品代码的开发主力人员,我的任务是解决问题,同事的任务是和车厂人员打交道,给我做好服务,所以我不客气地支使起这位同事来。

雨后新晴的空气显得格外清新,微风拂面,带来一丝丝凉意,停产场的坑洼处还有一些没有吹干的水窝,倒映着碎成一片片金箔的阳光。尽管倍感煎熬,目前仍处在水深火热之中,但是我坚信,正如冬去春来大地回春一样,我也会柳暗花明峰回路转的。

故障再现

路试人员是个年轻小伙儿,看着很精神,也颇为健谈,上车不久,便主动搭话和我谈了起来。

“前些天一直下雨,你们过来这两天才放晴。”他手握着方向盘,脑袋稍稍转向我这边,笑意随着他那年轻而又清脆的声音一起传了过来。

“你们发现故障的时候是在下雨天?”心思仍然扑在故障原因上的我,突然警觉起来。“是不是天晴的时候不发生这种故障?”

“大概是吧,记不太清了。”他淡淡地回应道。

‘是不是因为下雨,天气比较潮湿,机械锁那块密封性做得不好,造成机械解闭锁开关那里会出现解闭锁信号呢?’我的脑袋飞速运转着,默默在心里盘算着。‘应该不会,即便路试车的机械锁密封不好,也是只会误解锁,怎么会误闭锁呢?再说,后背门解锁信号来自于PEPS从CAN总线上发过来的指令,和天气也没啥关系。’我随即否决了这种判断。

前方路口红灯,路试小伙儿娴熟地减速、停车,按下了电子手刹,我看了看这辆车,随口问起这辆车的配置来,EPS、自动挡、电子手刹、PEPS、阳光雨量传感器、自动天窗、车窗防夹,‘比我们当时测试BCM时的试验车配置高。’我不禁暗暗想到。

‘咯噔’,一声清脆的解锁声,划破空气直冲我的耳膜,“你按中控那里的解锁键了?还是按遥控钥匙上的解锁键了?”一股热血冲上了我的胸膛,爬上了我的脸庞,我带着紧张的神情,急切地问道。

“没有啊,我什么都没动,”路试小伙儿脸上挂着意味深长的微笑,“之前就是这样子的,莫名其妙就解锁了,有时是莫名其妙闭锁,有时开着开着车,就听到后背门打开了,当时吓了我一跳!”他盯着我的眼睛,加重语气说道。

问题复现了!我的心砰砰跳着,现在可是个大晴天,艳阳高照,这下怪不到下雨天气头上了吧。骄傲的太阳高高在上,透过前挡风玻璃,慷慨地将金线似的阳光洒满在我的身上。

车辆又缓缓开动了,路试小伙儿显然知道我在沉思,所以没有打扰我。宜人的春风透过车窗,抚摸着我的头发,我茫然地望着窗外,恍惚间,竟似不知身在何处。

‘为什么之前测试那么多次,都没有出现这种偶发的故障呢?’我烦恼地思考着。‘之前的测试还是很充分的,我测完让同事测,同事测完又让测试人员测,最后又找车厂的技术人员来测,测的次数够多了吧,我每次都在现场观察,也没出现过这种摸不着头脑的现象啊!’

‘要说测试条件有什么区别的话,那就是之前车停在那里,而现在是开了起来。可是,这款BCM的功能和车开还是车停基本没关系,难道车开起来和停在那里真有什么区别吗?’想到这里,我不禁有些着急起来。

“把车靠边停一下,接上OBD,我看看总线数据吧。因为之前测试BCM时,车厂不让我们自己开车,我们基本上都是停着车测试的。我突然想到,是不是开起来总线上报文数据比停车状态要多?”我给路试小伙儿解释道,同时又因为和无关人员解释而感到懊恼。

故障定位

车辆打着右转向,缓缓地停在了路边,我在方向盘下面摸索着找到OBD口,接上OBD线,另一边接上我的笔记本,打开监控软件,把两路CAN总线和一路LIN总线都监控起来。

‘恩,比之前的报文好像是多了一些!’我模模糊糊地想到,‘也难怪,这辆车的配置全,CAN节点多,之前那辆车没有ESP,是手动挡,也没有TCU,而且不带天窗。’我突然感觉,被诡异故障尘封的大门正在缓缓开启。

“开起来吧,小伙儿,”我的心情突然明朗起来,带着轻松而明快的语气对他说。“我看看总线报文。”

路边的景色迅速向后退去,汽车已经驶上了高速,我的大脑也开始高速运转起来。

‘之前的测试车配置低,CAN/LIN节点少,在固定的时间内触发中断的次数也少,现在这个路试车,CAN/LIN节点多,触发中断次数多,这就是测试条件的真正区别!’由于胜利在望,我的心开始安定下来,有条不紊地分析着问题。‘单位时间内中断次数越多,对CPU而言负荷就越重,中断服务例程的执行时间是一定的,中断次数越多,就越可能出现中断嵌套的问题,而中断嵌套时会消耗堆栈,嵌套层级越深,堆栈消耗越大,由于堆栈大小是固定的,而且堆栈空间和变量空间都是在RAM的线性空间里,一旦堆栈越界,就会改变它所临近的变量空间中的内容!这些内容发生了不应该发生的变化,当然会导致诡异的故障,也许这次无故解锁和闭锁只是表现比较明显的故障,还有一些隐患已经埋下,只是没有暴露出来而已!’

‘问题就在这里,’我继续欣喜地思考着,越来越感觉到喜悦在内心激荡不已。‘路试车中断次数多,造成了堆栈越界,堆栈越界,造成了无故解锁闭锁的故障!Perfect,这逻辑链条,完美!’

故障解决

回到停车场,同事正端着平板电脑等在那里,带着耳机,笑意盈盈,显然正在沉浸在电影的世界里。看到我回来了,他迎上来,张口就问:“测到故障了吗?你感觉可能是什么原因?”

“嗯,故障复现了,而且已经找到原因了。”

“哦?什么原因?”他两眼放光,不自然地笑着。

“以后再说吧,我先把问题解决了再说。”我有些懊恼怎么把这个同事也带来了,还得浪费我的时间和他解释这些事情,全然忘记了住宿、吃饭、找车厂人员都是这位老兄干的。

我打开源码,仔细阅读了各个中断的服务程序,却觉得无从下手,因为每个中断服务程序里都没有冗余代码,没办法进行精简,所以,降低中断服务程序的执行时间这条路是走不通了。

此路不通,我迅速转向,仔细分析了各个中断的优先级,这些中断的优先级都是在之前写代码的过程中按照添加代码的顺序随手设定的,由于之前测试没出过岔子,所以尽管是“随手设定”,也没爆过雷。现在回头一看,问题就出在这里。

我这款BCM里用了不少中断,像定时中断、CAN中断、LIN中断都是经常发生的,而且CAN中断的频率最为频繁,但是我之前却把它的中断优先级设置得很低,结果就导致CAN中断被各个优先级更高的中断随意抢占,由于它频繁发生且被随意抢占,导致CPU大量时间都用在中断服务程序的切换导致的堆栈入栈和出栈上,不仅实际效率降低,而且会导致堆栈越界问题。如果把CAN中断优先级调高,这个频繁发生的中断就不会被抢占,不仅提高了CPU的执行效率,而且避免了堆栈越界。

按照这个思路,我调整了CAN中断的优先级,再次上车测试了两天,故障消失了。。。

由于问题解决地还算及时,描述故障原因和解决方案的文档写得也清晰明确,因此这次路试继续进行,不用再里程清零重新路试了。在回程的途中,笔者百感交集,在这些复杂难名的情感中,竟有一种寂寞感在心底滋生,我突然想起《美人鱼》中邓超唱的那句歌词:“无敌是多么,多么寂寞~”

关键词: CAN 中断 堆栈

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版