2011年10月3日 星期一

USB HID 技術散記(三) --- 系統干擾問題

 

這又是一個在USB 市面上相關書籍裡不會教您卻又是一個很重要的USB 系統應用問題的事!

---------------------------------

關於USBHID 的應用在一般人的眼中是認為他在 M$ 的作業系統中會提供標準的

驅動程式,所以可以免去許多人對於視窗作業系統底層的畏懼,而可以簡單輕鬆上手。

但USBHID 在規格上還有一個好處是:他提供了Interrupt In Token (Pipe Interface)介面。

再搭配作業系統的驅動程式,可以讓視窗應用程式來隨時讀取USB 裝置的內容或狀態。

(其實是作業系統一直在幫您把USB Device 提供的資料數據取回PC 端,讓您自己的

系統應用軟體程式可以很方便的從作業系統端讀取所需的資料!)

所以,之前就有人請版主幫忙提供一些平台,可以讓USB 這一種Plug and Play 的介面

輕鬆的建立在工業控制上...

理論來說:當然是可行的。但事情總不是像學校老師教的或學生作專題這麼簡單...

這些東西要用在工業控制上,他所要面臨的惡劣環境就是我們搞系統的不得不去面對

的棘手問題。

在工業上所常用的通訊介面是:RS485 ,他是一種差動訊號的方式,這一種差動訊號

對於環境的干擾會有比較好的抗雜訊能力;而理論上,USB 其實也是差動訊號傳輸方式,

(D+/D-) 構成一組類似交流訊號的傳輸方式...所以,USB 的傳輸在某種程度上也是

有一定的抗干擾能力。但是USB 的傳輸並不像RS485 這麼簡單,因為USB 除了硬體

定義規格外,其實他還是有定義了傳輸介面複雜的通訊協定,每一組傳輸的數據都會

有PID ,SNYC...Data and CRC 等等...所以,在USB的傳輸線上,其實時時刻刻一直

充斥著資料傳輸內容,所以相對來說:USB 的傳輸是更有機率被環境因素所干擾的。

所以,當老師或您的老闆長官交代您來學USB時,您總以為只要把市面上買到的USB

開發平台買一塊回來寫寫  8051 韌體就可以交差了事了。

當然啊...當您從完全不懂USB 開始學,可以學到寫USB 韌體程式時,其實也已經

誠屬不易,搞不好,能拗到這個階段的...也幾乎令人刮目相看了,在學校實驗室裡或許

已經可以被尊稱學長師兄的...甚至到達所謂達人境界了。但實際上,真正要用一個規格

能做到許多當初規格所設想的許多情況,其實還有許多努力的空間的。

我們現在就舉這一個例子 ---萬一在USB 傳輸過程中『遭逢』惡劣外在環境干擾時,

他會發生什麼狀況?!這是在許多工業規格環境中常會遇到的情況。

-------------------
 

上圖就是一個USB HID 的Interrupt In Token 的傳輸過程,這是一個系統上一直Polling 的

使用情況....結果,在這個過程中,很不幸的發生傳輸錯誤,有可能是某一個 CRC 錯誤,

或是一個簡單的USB Bus Disturbance...造成USB Controller 的錯誤發生。

(也有可能造成PID 或SYNC 值不對...因為您永遠不知道環境干擾的發生點!)

結果:我們可以發現此時PC Host USB 會發出一個 Reset 訊號。其實,USB Reset

訊號對於USB Host 或USB Device ...都有資格或有機會發出Reset訊號,但一般來說:

大部分都由USB Host 發出比較多,因為重點是:當您發出Reset 訊號之後,您緊接著要

做什麼事是比較重要的。所以,我們可以上圖中,可以發現PC Host 在Reset 之後,

馬上作一個簡單的類似Get USB Device Description 的動作來確認您這個USB Device 還

有沒有還活著?!

如果是的話,他就會重新啟動您的傳輸介面設定:Clear Feature Endpint 1。

這代表在之前您的Endpoint 1 的傳輸有發生錯誤,我剛剛提到的有可能只是一個CRC 錯誤,

您不要以為在USB 規格裡那些CRC 檢查機制只是定義著好玩而已,他們也是有一定的

目的的...只是一般USB 書籍也不太會告訴您而已...因為這些參考書籍總不能過渡的打擊您的

學習信心而影響他們參考書籍的銷售量吧。

在完成Clear Feature (Endpoint 1)之後,理論上您的 Endpoint 1 就應該要恢復之前的正常

狀態,然後再繼續的往PC 端送出資料。----這一部份您的上層應用程式是不知道這件事的

-----

問題就來了,如果您的上層應用程式不知道這一件事,那有沒有可能造成資料傳輸錯誤?!

Of Course...當然啊。而且您USB Device端韌體程式也可能會因這個過程影響您原本正常的

資料擷取與資料傳輸,甚至打亂您原本規劃好的韌體控制流程...進而造成USB device 端的

韌體程式在執行上的錯誤。譬如:不再傳輸了...對USB Protocol 來說:有沒有錯?!沒有。

因為您原本的USB 韌體的認知是:每固定時間要把擷取的資料往USB 的Endpoint 1 送,

後來被這一個USB Protocol的流程給打亂了...造成Endpoint 1 的NAK 產生...(因為一般

USB Controller 在硬體上會自動保護自己,避免資料傳輸衝突而被USB Host 給踢掉!)

我講過了 :在USB 傳輸上您要用NAK 擋一輩子,沒有人說您不對!---這不是當機。

所以,當這一種問題產生與發生時,您的USB Device 端的韌體程式一定要做一定的

防護與重新啟動的機制,讓整個系統重新回復正常。

----

對我來說:原本的原廠提供的範例程式當然沒有這一個防護機制,所以當如此問題發生時,

不是資料終止傳輸就是從此資料內容發生錯誤...當我們好好的把這樣子的過程利用USB

Device 端的韌體程式修正之後,就會回歸正常了。如下圖:

看到沒有:在重新Clear Feature 之後,Endpoint 1的Interrupt In Token 又正常的傳輸資料。

(但您有沒有注意到:其實我們USB Device 的Address 已經從原來Address =0x06 變成

Address = 0x08 了!)

----

小結論:系統面臨外在環境干擾是在所難免的,硬體的防護措施還是有一定的極限,

與不可預期的結果。但有時軟體一定的自我保護與自我回復能力也是很重要的。

其實,在這一個實驗過程中,我本身發現:其實韌體的所能貢獻的是比硬體對策措施

還來的有效...因為畢竟硬體能做的不多,也比較沒彈性。譬如:在硬體上您無非只能

加抗干擾或保護元器件,或是增加硬體防護遮蔽(shield)機制等 ---

這些也都會增加硬體成本(當然啊這些硬體保護還是有一定效能的,是可以有效降低

類似問題發生的機率的!)。

所以啦,搞系統嘛!總不能設限是韌體或硬體工作嘛!把問題釐清與系統調整到最佳狀態

其實就是一個好的系統產品。尤其是講求高品質的工業規格要求的品質啊。

您說:對不對?!

 

 

 

2 則留言:

  1. 你好,關於上述提到的問題,真是心有戚戚焉。我也是因長官的要求用USB2.0做工業控制,也是會遇到偶爾Open_Device失敗的情況,再加上這是公司新開發的產品,沒有人熟悉,甚至連協定分析儀都沒有,當初也只能硬著頭皮接下來,真是OOXX......
    我現在遇到這種USB溝通失敗的時候,我會在回傳給host端command之後打開計時器,假定若太久都沒收到host端持續送command進來,就當成是host與裝置溝通失敗,就把目前的工作狀態的設定值存到ROM之後,自動重新啟動韌體,再載入之前的設定。我知道這樣的解法不是正規的USB protocol處理方式,所以看到您的文章時真的是令人感動啊。
    針對您的文章有些不解的地方,當收到reset訊號時,clear feature for endpoint1,請問所謂的"clear feature for endpoint1"到底做了哪些事情??是只有把endpoint1的內容清掉而已嗎?或是還有做其他動作??可否請您分享一下您的做法,謝謝,拜託了。
    我的Email:byron0921@gmail.com

    回覆刪除
    回覆
    1. 挖哩耶~您這樣子突然問我這個剛好一年前的東西,我還真的一時
      得要回頭讀讀我自己寫的內容耶。才能搞清楚相關問題。
      ---
      您目前的作法,當然鐵定是拿狗皮膏藥在貼的,沒關係~老闆覺得可以就好了。
      只要您每一次"自動重新啟動韌體,再載入之前的設定。..."能解問題時,
      您的長官或老闆也搞不清楚的啦。沒關係啦。習慣就好了。
      ---
      我真的懶得在去翻我當初寫的程式了...不過就從我自己文章中,我也都
      可以解讀出我大概應該怎麼解的吧!很簡單啦...我不是說:人家USB Host
      不是對我USB 韌體發出Reset 了嗎?!那我的USB Device Controller 肯定
      知道這件事的啦...(您的PC 端上層應用軟體不一定知道...怎麼讓上層
      AP 應用程式知道?!我想應該要研究作業系統吧?!可能也有方法吧!)
      既然您的USB Device Controller 知道...您也知道人家來清
      " clear feature for endpoint1"...那當然您應該也知道您原本的Endpoint
      傳輸介面的Transfer pipe 應該還在不在吧?!(他應該還會繼續來要
      資料吧!)...那這樣子您就可以利用USB Controller  韌體解了嗎?!
      應該很容易吧?!...除非您真的搞不定USB Controller 的韌體?!
      那也就沒辦法了....因為這是唯一的方法了。否則,您就得去研究我剛剛
      提到的可不可以問M$ 的作業系統,可以不可以讀得到USB  RESET 狀態?!
      ----
      我發現我寫USB 的DIY 內容還蠻容易悟得到一些技巧的嘛! :))

       

      刪除