引言
虽然TTP/C通信协议在我国的嵌入式系统研究圈内讨论得很少,但是它已经应用到了空客A380和波音787梦想客机等系统中。我们正在选购、使用、维修他们的产品,在自主开发时也采用了这种协议。对这些陌生的技术领域,只有知己知彼,才能少走弯路,为此,本文分析它出错失效的可能性,供大家参考。
TTP/C是时分多路存取协议[1],它的最小存取时间单位是slot,一个slot只安排一个节点进行发送,其中可以发多个消息,包括事件消息。若干个slot 组成round,round内每个节点只占一个slot ,每个slot 的长度可以不同。若干个round构成cycle,各round的slot 分布及slot 被指定的节点是同样的,但是slot 里发送的消息及其长度可以是不同的。所有这些均离线调度好,并保存在每个节点的消息描述表(MEDL)里。
TTP/C用控制器组籍向量(Membership vector)表示节点的好坏,每一个节点在Membership vector中占一位,Membership vector是控制器状态Cstate的一个域,每一个节点在发送帧的时候将自己的Cstate以某种方式一起发出去,在初始帧(I帧)时,Cstate显式送出,在正常帧(N帧)时,Cstate以隐含方式送出,发送什么类型帧的信息会存在消息描述表里。初始帧用于有错节点的重新加入和组籍恢复。隐含方式是将Cstate串在正常数据之后一起求校验和CRC送出,Cstate本身并不送出。接收节点将收到的数据与自己节点的Cstate求校验和,再与收到的CRC比较。如果二者相同,则表示数据接收正确,且两个节点对Cstate的看法一样,它们属于同一个组。如果不同,可能是发送节点有错,或者是接收节点有错,就要修改组籍,这有一套复杂的规则。关于TTP/C的种种优点可阅读参考文献[1],不再重复。
1 总线拓扑时的问题
1.1 拜占庭错的出现
早期的网络往往以总线形式出现,TTP/C也不例外,尤其是线束空间与重量列入选用因素的场合,总线往往占优。TTP/C的组籍算法、发送节点的认可、小集团排除等关键算法完全依赖于故障假设,如果故障假设不成立,那算法就会出错。其中造成假设不成立的主要因素有出错频度以及拜占庭错。所谓拜占庭错就是一部分节点认为没错而收下,另一部分节点认为有错而丢弃,系统内有不一致的看法。TTP/C的组籍算法希望排除一部分有错的节点,在所有正确节点中取得一致。
TTP/C在故障假设分析中提到过拜占庭错,那是假设收发器出现了输出为1/2电平值的情况:一些节点把它读为0,而另一些节点把它读为1。这是一种略微超差的情况(Slightly Off Specification,SOS)。TTP/C研发者认为检错机制常常无法把它们全部查出来并适当地加以处理,唯一的办法是把它从系统里排除出去,例如用专门的中心单元星形耦合器[6]。如果按这种说法,总线拓扑就不行了,至少是未处理的了。显然1/2电平值极少发生,而且必要的话,可以添加总线电平的自诊断硬件来发现这种错误,即可以使它包含在诊断的覆盖面内,不管错误的结果是安全的还是灾难性的,都是可以检测出来的,从而在应用层添加功能安全设计。
但是另一种TTP/C未考虑的因素是总线上的干扰,它很容易形成拜占庭错。处于总线中间段的节点发信号时,将同时向总线的两端两个方向传送,干扰也是同样的,图1中节点4附近耦合的干扰将沿总线向两个方向传送,由于节点发送的数据流是单向的,节点4、5、6、7会收到相同的数据流加干扰的结果,可能大家都错,也可能大家都正确。而节点2、3看到的干扰是在不同的数据位置,可能有错误,也可能正确。这种拜占庭错情况是无法用硬件检测出来的,而且出现的可能性要高得多。总线上出现的拜占庭错如图1所示。
图1 总线上出现的拜占庭错
1.2 正常节点因拜占庭错而被冻结
TTP/C的小集团排除算法是这样的:从每个节点的发送slot 开始,到下一轮(round)这个slot之间,统计这个节点成功接收的次数,以及接收失败的次数,如果前者没有超过后者,这个节点就被冻结了。发送slot时,成功与失败计数器的初值为0,依发送自信原则预先把本slot的成功加1,而后转为接收节点处理,接收时按成败对相应计数器加1,在认可过程中也同样。
假定有A、B、C、D四个节点按顺序发送,初始均正常,组籍为(1,1,1,1)。节点A、B为正确节点,C、D为有接收故障的节点,在B节点发送时由于电干扰而C、D收错,它们就把B的组籍删去,变为(1,0,1,1),而A的组籍仍为(1,1,1,1)。轮到C、D发送时,因为组籍不同,A、B出错,A、B的组籍变为(1,1,0,0)。再轮到A发送slot时,因为A成功两次(A、B),失败两次(C、D),没有超过而冻结不发。再轮到B的slot,B成功一次(B),失败两次(C、D),A未发,所以冻结。再轮到C,成功两次(C、D),A、B未发,所以继续发送。轮到D时,成功两次(C、D),A、B未发,所以继续发送。于是有错的节点都留下来了,而真正无错的节点却都因冻结而离线。
1.3 有拜占庭错时的错帧漏检
TTP/C的N帧由Header、Data、Cstate、CRC4个域组成。当发生拜占庭错时,发送方与接收方的Cstate会有很多位不同,如果不同位的个数较全球多,就可能使CRC检验失效,形成错帧漏检。这个问题在参考文献[2]中早已提出,但是低估了其严重程度。
早期的TTP/C协议用的是16位CRC校验和,后来改为24位CRC校验和[5],按理来说它的海明距离可以达到HD=6,对于短帧(36位数据)更可以达到HD=8,由于Cstate本身就要占48位,所以理论上HD=6。
当系统节点较多,例如8个以上时,发生拜占庭错后尚未到下一round时,属于两个小集团的节点还在继续收发,它们的Cstate中的组籍向量就可能有6位差。将TTP/C的生成多项式G=(1,1100,0101,1010,0101,1110,0011)对xi求CRC校验和,然后选出校验和中1的个数最少的实例。例如x968的CRC校验和为(0000,0000,1001,0000,0100,0011),那么在前面数据部分有1位错,而组籍向量有5位不同时,这个错帧就会被收下来,这时相当于HD=1。
对于数据较短的情况,例如CAN的8字节数据这种应用,搜索i<112的情况,前面有两位错,而CRC校验和中有6个1的情况共计92种,其中这6个1处于16位之内的有15种。
这里要提及TTP/C组籍向量所占长度的规定,它以16位为增量,节点数小于16时占16位,17~32位占32位……直到64位,而且节点在组籍向量中的位置可以按系统集成人员的需要任意指定。
以x59+x21的CRC校验和=(0000,0000,0000,1011,1000,1001)为例,把(1011,1000,1001)视作两个小集团组籍向量的差,如果这个系统有16个节点,差的6位在组籍向量中可处的位置就很多。那么,在使用TTP/C传输很短的数据(即帧的数据部分仅3字节)时,有2位差就可以漏检。
错帧漏检属于残留差,即功能安全分类中的未检出错,它完全可能是未检测出的危险失效部分。对于这种残留差的发生情况,民用的过程工业中已经认为误码率为10-2是必须考虑的,例如PROFIsafe System(2010年版)中提到他们为了保证错帧漏检的贡献小于10-9/h,选择额外的CRC时要对付的误码率是10-2[3]。在误码率为10-2时,刚才分析的TTP/C帧的数据域有120位,可能有两个错,就可能漏检了。
错帧漏检有两个后果:第一,TTP/C通过两个通道传送数据,接收节点可能收到两个名义上合法有效的数据,由于没有进一步鉴别的依据,可能把真正有错的数据送到了应用,造成应用错误。第二,由1.1节可知,成功计数器和失败计数器是决定节点是否冻结的关键,漏检会使二者进退差2,很可能这是关键的一票,对簇内节点的去留有影响,从而也影响到哪些消息停发,哪些消息还在发,进而改变应用的状态。
2011年TTP/C升为SAE标准AS6003,其帧格式增加了扩展帧X帧,即传送数据内容的同时把组籍向量显式包含在帧内,从而可以避免上述组籍向量对CRC检验的不利影响。但是它并没有去掉N帧,仍用大量篇幅来介绍,不了解的用户仍然可能因它而出错。
2 故障假设的问题
2.1 TTP/C的故障假设
TTP/C的故障假设的详细内容,共有9条,其中关键的4条是:一个round只有一个错;只有前错不再影响时(那个节点或者已切除,或者已恢复)才能有新错;总线上只有全局错而没有局部错;在一个slot中只有一个通道会出错。它的发送节点组籍认可算法完全依赖于这些假设,而小集团避免算法又与它环环相扣,发送节点组籍一票之差就会使表决结果翻转过来,就可能使应用造成完全不同的结果。
2.2 两个通道同时出错
TTP/C在物理层上是每个节点通过两个通道同时传送一个帧,只要有一个帧正确收下便可以,而且为了避免共因失效,两个通道的传送电平是相反的。原则上讲,这已经考虑得比较周全,但是现场的情况比较复杂,容易发生突破上述故障假设的情形。图2是在CAN总线诊断中查出的干扰波形[4],来自耦合于电源的干扰使差分信号叠加了毛刺,这两个毛刺时间上有先后,单一的毛刺在两个通道上只使一个通道的帧出错,但是第二个毛刺有可能使另一个通道出错,如两个毛刺发生在同一位,那么两个帧在同一位出错,如两个毛刺在不同的位处,仍然有50%的机会使两个帧同时错。这样,虽然有双通道且电平反向的设计,来自电源的干扰仍可以使两个帧同时失效。所以TTP/C只有一个通道会出错的假设是不成立的。
图2 在现场观察到的干扰
2.3 为何不满足功能安全要求
那么一个round只有一个错的假设是什么含义呢?TTP/C可以工作到25 Mb/s,假定实际使用于10 Mb/s,一个round一般为数ms,假定为0.5 ms。那么一个round只有一个错的假设就是每0.5 ms容许一个错,而0.5 ms内TTP/C传送了5 000位,即误码率为1/5 000=2×10-4。
现在分析每5 000位出现超过一个错这件事的概率,据有关资料介绍,最好的通信系统物理层同轴电缆的平均误码率为ber=10-9,光纤系统为ber=10-12。
用组合公式C(n,m)=n!/(m!×(n-m)!)来分析ber=10-9时故障假设失效概率:误码可能发生在5 000个不同位置,假定出2个或3个错,如果出现多错时的贡献较小就忽略不计。
出现2个错的概率=ber2=2-18,组合数C(5 000,2)=1.2×107,所以不满足TTP/C假设的概率为p2=1.2×10-11。出现3个错不满足TTP/C假设的概率为p3=2×10-16,可以忽略。
虽然不满足TTP/C假设的概率不大,但是如果以每小时来计算,TTP/C假设失效率就很大了,以0.5 ms一个round,每小时有3 600×1 000/0.5=7.2×106个round,TTP/C假设失效率就是1.2×10-11×7.2×106=8.6×10-5/h。即使危险失效只占10%,也远远达不到功能安全的要求。这是平均ber=10-9假设下的结果,如果现场条件差,危险失效的概率就更大。
3 不要过高估计组籍算法的效用
组籍算法的目的是使所有正常工作的节点都能互相认可。这个组籍可以由应用读取,然后在出故障有节点失效时采取措施,即实现never give up(永不放弃)的故障安全策略。例如,4轮驱动或刹车的系统,不仅每个正常节点要正确接收命令,而且还要知道有没有不能正常接收的错误节点,当有一个轮子的节点失效时,可以重新分配驱动力或刹车力,尽量保持原有的方向和速度。
组籍算法可以得到一致性,但只限于存留节点有一致性。如1.2节所述,由于拜占庭错,留下来的节点可能正是有接收错误的节点。而且,节点能否幸存,是由正确收下次数与失败次数之间的关系决定的,与应用并无直接关系,通信的组籍并非应用的组籍。例如应用只与节点A、B、C有关,但是系统中A、C、D、E、F留了下来,B被冻结了,系统照常失效,组籍算法只是提供了发现这种失效的可能。
因此纠错是非常必要的,例如CAN的出错重发,可以在无故障的节点中建立一致性,但是在时间触发协议中要实现出错重发是非常困难的,TTP/C最快只能在下一round的slot中加以发送,比CAN要慢得多。TTP/C的组籍算法是以round为计时单位来获取组籍信息的,而且没有像CAN那样的出错自动重发,所以其最好效果是一个round之后才能在可能无故障的节点间建立一致性的正确消息传送,数个round之后才能实现应用级的功能安全措施。
结语
上面的讨论围绕的是通信系统出错时的组籍变化,从应用上讲,影响组籍的不仅是通信系统,还有节点host所发现的错误。TTP/C规定host可以通过3个机制来控制通信控制器的收发。第一个是通信网络接口CNI中的controller on直接由host开关通信控制器。第二个是host life sign,像一般watchdog一样,host必须周期性地将这一位翻转,如果没有翻转,TTP/C通信控制器就认为host有错,在中断状态寄存器里设host error位,并使自己处于Passive状态,由host控制恢复过程。第三个是模式改变,只有在启动阶段才允许模式改变,正常运行时是不容许的。所以host的组籍改变完全取决于host的响应速度,不再是通信部分的一个round检出错,下一个round再加入。