我们给企业做的样机出现了一种随机故障:多数情况下,仪器工作正常,先进行不定长度的噪音检测,然后开始正式采集,噪音很小,采集信号也正确。但是,偶然的,噪音检测信号突然变得很大。关机再开机,一切又正常了。
让故障重复发作,需要足够的耐心。找到重复发作的规律,又需要足够缜密的思维。反正,谁遇到这种随机故障,都是头大。
我们先对异常的信号进行了分析,很快就找到了异常的表象原因:我们的每个样点数据都是32位的,其中高8位(简称A)是通道号标记,有规律,低24位(简称B/C/D)是实际数据。通过简单的分析就能发现,异常的原因是高16位和低16位颠倒了。如果原始噪音数值密布在低8位D上,那么新的数据格式是C/D/A/B,显然,数据就变得庞大且混乱。
但是,是谁让高16位和低16位发生了颠倒,却让我们伤透了脑筋。
学生们做了很多实验,试图找到故障出现的规律,但是结果比较混乱,越到后面,就越混乱,像索马里的内乱,无可收拾了。今天我让他们把整个结构讲了一遍,用概率分析方法,基本找到了故障源。
先陈述一下我们的设计:上位机是PC机,中间级是DSP,底层是FPGA和ADC。上位机发出两种工作模式,第一是噪音检测,就是在**爆炸前,先检测背景噪音,如果太大,就不引爆**,如果合适,就进入正常采集模式,也就是第二种工作模式。注意,第二种工作模式,全套流程都是确定性的,但第一种模式,隐含着随机性,测试员观察背景噪音,觉得噪音不大,他随时都可以终止目前的噪音检测,而进入正常采集。
这个终止的时刻,就是随机的根源。
ADC每125us吐出一次数据交给FPGA,是32位的。FPGA把他们摆放成高16位,低16位两个寄存器中,同时DSP实施一次读操作,FPGA自动将高低计数器HL实施0、1转换。注意,DSP成功读取全部数据,需要10us~23us,一旦读完,高低计数器自然归零。因此,如果在DSP不读取数据的时刻,终止程序进入第二模式,就不会发生任何问题。在DSP读取了偶数次,HL也归零,也不会出问题。问题在于,如果DSP刚好读取了奇数次,接到了高级中断,迫使其退出读取,准备实施第二模式(正常采集)时,HL仍处在1状态。
此时,DSP向FPGA发出了复位信号,按说可以对HL进行清零,但是问题就出现在这里。我们的学生设计的流程中,DSP虽然接到高级中断,请求进入第二模式,也向FPGA发出了复位命令。但是,FPGA没有清零HL计数器。
这样,启动正常采集后,DSP读取的第一个数据,不是应该的高16位,而是低16位,数据就乱套了。
我们随后分析了出现概率,125us一次中,如果高级中断发作于10us~23us之外,不会出问题。发作于10us~23us之内,也只有刚好读取了奇数个数据时,才会出问题。因此故障概率为(5~11.5us)/125us,大约是1/25~1/10.8。
事实证明,我们的实验,有时第一次就出错,有时七八次,但是绝大多数情况下,30次之内必然出错。这与我们的分析完全吻合。
我猜测,在错误的情况下,继续实施噪音检测,肯定会在相同的概率下,由错误再回归到正确。我提出了若干估计,要求学生大量实验去验证:
1)任何错误的出现,此前一次的模式一定是噪音检测。噪音检测的终止时刻不合适,是造成出错的本质原因。
2)出错概率大约为1/20附近。
3)出错后继续实施噪音检测,将会出现正确回归。
学生大量实验告诉我,与我估计完全相同。
解决问题的方法其实很简单,就是FPGA对DPS发出的复位信号,实施一个有效的动作:将HL计数器清零即可。
事实证明,这么修改后,再也没有出现过任何故障。
从这个故障排查的历程,我想告诉大家。
第一,随机故障一般都有随机性事件引起,找寻随机性事件,有助于发现故障根源。
第二,随机故障一般都有随机性概率,这个概率一般可以从时序上分析得来。
第三,只有分析概率与事实概率吻合,才说明找到了故障源。
第四,只有找到了故障源,且证明两者概率相同,才能一针见血排除故障。
上面文字在人人中发表。补充一句,为什么要搞概率分析。随机故障让人头疼的地方,就是你解决了,心里还是不踏实。除非持续的,大量的,无休止的实验,能让你放心一些。这谁都受不了。但是,如果找到了概率,且实验与概率相同,一般情况下,我们就能彻底放心了。
pentral0311_880012608 2013-7-3 09:59
用户1431660 2012-10-31 18:27
用户1545371 2012-9-7 08:28
用户1510143 2012-9-6 08:58
tamkay_819533976 2012-9-5 18:50
这个可不可以说是数据完整性出了问题?或者数据处理的“同步性”出了问题?
这个事例很有典型性!
类似的“问题”往往会令人束手无策、困惑不解好几天。我觉得,只有举一反三、触类旁通,上升到用规范性的方法来工作,才能更好的避免“问题”重演。
比如,(1)凡是数据会被分割的成更小的单元进行处理的,都必须考虑如果只有部分的单元被处理、整体数据没有被完整处理的时候是否会有不良影响。如果你不能确定是否有不良影响,那么就必须保证数据是“不可分割”的。
(2)对于可以被分割的函数或者模块等执行流,也要进行相同的考虑。
用户1558680 2012-9-3 19:33
用户1510143 2012-8-29 16:28
用户1078441 2012-8-29 15:07
用户1470025 2012-8-27 14:21
用户1510143 2012-8-25 10:25