浅谈I2C总线的死锁恢复
2018-12-06
1 引言
I2C总线是Philips公司推出的一种二线制同步串行总线,它由时钟线(SCL)和数据线(SDA)两根传输线组成。I2C总线具有接口线少、控制简单、器件封装形式小、兼容性好、通信速率较高等优点,使它成为很多器件的标准接口和标准功能模块。它成为近年来微电子通信控制领域广泛采用的一种总线标准。I2C总线虽然简单,但在实际使用过程中出现的问题还不少,其中最为常见的问题就是I2C总线死锁。当出现I2C总线死锁时,总线上的设备无法正常工作,整个总线陷入瘫痪状态,这对于一些要求高可靠性和高安全性的自动控制系统而言,是无法接受的。
2 I2C总线的工作原理及特性
I2C总线的标准数据帧由主设备发出的开始信号(START)作为起始标志,再是包含读/写操作标志位的从地址信号,紧跟其后的是与从地址匹配的从设备的应答信号(ACK),接着是由从设备(读操作)或主设备(写操作)发出的数据信号,紧跟每一个字节数据信号(以8位数据为例)之后是接收设备的应答信号(ACK)。当数据信号传输完毕后,最后是主设备发出的结束信号(STOP)作为数据帧的结束标志。
I2C总线的特性可概括为:
(1)接入I2C总线的器件,SCL和SDA都必须是双向开漏结构的,通过总线上的上拉电阻拉到逻辑高电平,这样的结构可以实现线与(&)功能;
(2)一般情况下,I2C总线的SDA只有在SCL为低电平的时候才能改变,SCL为高电平的时候SDA需要保持;
(3)例外的,由主机发出的起始信号START(SCL为高时,SDA由高变低)和停止信号STOP(SCL为高时,SDA由低变高);
(4)由于I2C总线的线与结构特性,只要总线上任何一个器件拉低了SDA或SCL,其他器件都无法拉高它们。如果有器件不释放总线,则整个总线上的通讯都会被暂停。
3 I2C总线死锁产生的原因
3.1 总线电平被拉低的原因分析
根据I2C总线的特性,SDA或SCL被拉低后,I2C总线将出现死锁的情况。对于SCL,一般标准I2C从设备不会影响到SCL,只有是MCU作为I2C从设备时出现程序错误,或在多主的情况下出现控制冲突,而导致SCL被拉低,但一般可以通过程序优化或添加防冲突机制加以避免。因此在此重点讨论单主控制下SDA被拉低的情况。
主设备主动拉低SDA不会导致I2C总线死锁,因为可以通过复位I2C来重新进行I2C总线的控制。而I2C从设备一般不具备复位引脚,如果其将SDA拉低,将导致死锁的发生,即使主设备复位都无法解除。
根据I2C总线的工作原理,以下两种情况会出现从设备拉低SD A:
(1)主设备向从设备写数据或地址时,从设备如果发出ACK应答,则会在第9个CLK的期间拉低SDA;
(2)主设备读数据的时候,从设备会在数据位为0时对应的CL K期间拉低SDA。
根据I2C的特性,SCL为高的时候,SDA的电平应保持,而等到SCL变低后,SDA电平才能发生改变。如果在SCL的前半个周期变为高电平后,主设备因某些原因不再拉低SCL,则从设备将持续拉低S DA,I2C总线将一直处于被占用状态。
3.2 主设备突然复位导致I2C总线死锁
在主设备进行写数据或地址操作,当从设备发出ACK应答信号拉低SDA时,如果主设备突然复位,将导致时钟信号不完整,进而引起从设备持续拉低SDA。复位后的主设备也就无法给出启动信号或停止信号来使从设备释放对总线的占用,这样就出现了I2C总线死锁。
在主设备进行读数据操作,当从设备发出的数据位为0而拉低S DA时,如果主设备突然复位,类似的,因从设备收不到完整的时钟信号,导致持续拉低SDA,进而出现I2C总线死锁的情况。
3.3 主设备给出错误的ACK信号导致I2C总线死锁
在主设备进行读数据操作过程中,当接收完最后一个数据时,正常情况应该给出NACK信号告知从设备不再读取新的数据。但如果主设备错误地设置了的读取数据长度寄存器值,或因外部干扰等因素导致错误地发出了ACK信号。于是从设备将继续发送新数据,若数据的第一位恰巧为0,从设备将对应地拉低SDA。而对于主设备而言,其已完成所有数据的接收,准备给出停止信号STOP,但由于从设备拉低了SDA,导致主设备无法发出停止信号,这样主从设备相互等待,陷入死锁的境地。
4 I2C总线死锁恢复的方法
解决I2C总线死锁问题的方法较多,大致有以下几种:
(1)选用自带防止I2C总线死锁的从设备;
(2)选用带复位输入的I2C从设备;
(3)从设备的电源由主设备控制;
(4)I2C总线上增加一个额外的总线恢复设备;
(5)在I2C总线上串入一个具有死锁恢复功能的I2C缓冲器;
(6)在I2C主设备中增加死锁自恢复程序。
在这些解决方法中,“增加死锁自恢复程序”相对比较方便和实用,获得了较广泛的现场应用。但使用这个方法的前提条件是,主设备的SDA和SCL可以配置为普通的GPIO功能。
死锁自恢复程序的工作原理为:用GPIO在SCL上模拟时钟信号,同时检测SDA的状态有没有被释放(变为高电平),一旦检测到SDA被释放,重新将SDA和SCL配置为I2C功能,发送停止信号ST OP,告知从设备前次被中断的通信结束了,至此I2C总线死锁被解除恢复。
5 结语
分析了I2C总线产生死锁的原因和出现死锁的不同情况,着重描述了“死锁自恢复程序”的实现原理。设计者可根据上述分析的原因,采取对应的措施加以避免,同时可采用“死锁自恢复方法”有效解决I2C总线死锁带来的影响,使系统的可靠性和安全性得到提高。