I2C總線死鎖

原文:http://blog.sina.com.cn/s/blog_72605ba50102vl66.html


現象

最近發現訪問I2C設備時,主設備復位可能會引起i2C死鎖,表現爲SCL爲高,SDA一直爲低,後發現是從設備拉死i2c總線,從設備斷電之後,SDA變高,上電後通信正常。後來通過拉低SCL信號線,SDA就會自動變成高電平,i2c總線恢復。

原因

在正常情況下,I2C總線協議能夠保證總線正常的讀寫操作。但是,當I2C主設備異常復位時(看門狗動作,板上電源異常導致復位芯片動作,手動按鈕復位等等)有可能導致I2C總線死鎖產生,下面詳細說明一下總線死鎖產生的原因。

詳細分析

在I2C主設備進行讀寫操作的過程中.主設備在開始信號後控制SCL產生8個時鐘脈衝,然後拉低SCL信號爲低電平,在這個時候,從設備輸出應答信號,將SDA信號拉爲低電平。如果這個時候主設備異常復位,SCL就會被釋放爲高電平。此時,如果從設備沒有復位,就會繼續I2C的應答,將SDA一直拉爲低電平,直到SCL變爲低電平,纔會結束應答信號。而對於I2C主設備來說.復位後檢測SCL和SDA信號,如果發現SDA信號爲低電平,則會認爲I2C總線被佔用,會一直等待SDA信號變爲高電平。這樣,I2C主設備等待從設備釋放SDA信號(等待SDA變高),而同時I2C從設備又在等待主設備將SCL信號拉低以釋放應答信號(等待SCL變低),兩者相互等待,I2C總線進人一種死鎖狀態。同樣,當I2C進行讀操作,I2C從設備應答後輸出數據,如果在這個時刻I2C主設備異常復位而此時I2C從設備輸出的數據位正好爲0,也會導致I2C總線進入死鎖狀態。

解決辦法:

(1)儘量選用帶復位輸人的I2C從器件。
(2)將所有的從I2C設備的電源連接在一起,通過MOS管連接到主電源,而MOS管的導通關斷由I2C主設備來實現。
(3)在I2C從設備設計看門狗的功能。
(4)在I2C主設備中增加I2C總線恢復程序。
a.方法一
每次I2C主設備復位後,如果檢測到SDA數據線被拉低,則控制I2C中的SCL時鐘線產生9個時鐘脈衝每次I2C主設備復位後,如果檢測到SDA數據線被拉低,則控制I2C中的SCL時鐘線產生9個時鐘脈衝(針對8位數據的情況,“9個clk可以激活”的方法來自NXP的文檔,NXP(Philips)作爲I2C總線的鼻祖,這樣的說法是可信的),這樣I2C從設備就可以完成被掛起的讀操作,從死鎖狀態中恢復過來。
這種方法有很大的侷限性,因爲大部分主設備的I2C模塊由內置的硬件電路來實現,軟件並不能夠直接控制SCL信號模擬產生需要時鐘脈衝。
b.方法二
發送I2C_Stop條件也能讓從設備釋放總線,如果是GPIO模擬I2C總線實現,那麼在I2C操作之前,加入I2C總線狀態檢測 I2C_Probe ,如果總線被佔用,則可嘗試恢復總線,待總線釋放後,再進行操作。要保證I2C操作最小單元的完整性,不被其他事件(中斷、高優先級線程,等)打斷。
(5)在I2C總線上增加一個額外的總線恢復設備,用於監視I2C總線
當設備檢測到SDA信號被拉低超過指定時間時,就在SCL總線上產生9個時鐘脈衝,使I2C從設備完成讀操作,從死鎖狀態上恢復出來。總線恢復設備需要有具有編程功能,一般可以用單片機或CPLD實現這一功能。
(6)在I2C上串人一個具有死鎖恢復的I2C緩衝器
如Linear公司的LTC4307是一個雙向的I2C總線緩衝器,並且具有I2C總線死鎖恢復的功能。LTC4307總線輸入側連接主設備,總線輸出側連接所有從設備。當LTC4307檢測到輸出側SDA或SCL信號被拉低30ms時,就自動斷開I2C總線輸入側與輸出側的連接.並且在輸出側SCL信號上產生16個時鐘脈衝來釋放總線。當總線成功恢復後,LTC4307會再次連接輸入輸出側,使總線能夠正常工作。


總結:

從設備準備迴應ACK,此時SDA低,主設備準備拉低SCL以便接收ACK,突然主設備異常復位導致SCL變高SDA仍然低,此時主設備會重新檢測總線發現SDA低會等待從設備釋放,而從設備看到SCL爲高等待主設備拉低SCL接收ACK迴應,兩者相互死等,導致總線死鎖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章