「無法識別的 USB 設備」,系統是如何識別的?
我的一個鍵盤插到筆記本電腦上,有時候正常,有時候提示「無法識別的USB設備」。
鍵盤本身不值錢,我想搞明白這其中的道理,為什麼時好時壞呢,如果壞了應該永遠不會好才對啊,為什麼偶爾還會好呢?已排除接觸不良,因為我就一動不動的盯著它看不碰它,10幾分鐘後也能識別出來,再過一會又自動滅燈又識別不出來了。請高手解答下,一個USB設備插上之後,需要經過哪些工作,這個USB設備算是識別成功。
@dss886 說的很好,我來補充一些:
寫在前面的是:這個問題的終極答案只能是去翻微軟的USB源碼,但這部分是閉源的,我查了一下reactOS,NT4,WDK的源碼里都沒有這部分的描述,所以只能猜。
USB設備的枚舉、連接、載入驅動、工作的過程是這樣的:
1. 最先有反應的是硬體層面,也就是USB控制器,USB設備是有一定電阻的,當控制器感應到有電阻變化時,會在數據線上嘗試發送一組信號(規範上一般叫JKJK之類的,不知道該怎麼翻譯),當設備有回應的時候,才開始下一步操作。如果這一步失敗,那麼主機是不會收到任何信號的。
這也是為什麼充電器之類的插上沒反應,因為這些設備的數據線上沒有信號或者沒有匹配的信號。
2. 一旦設備在數據線上有回應了,下一步就是發送更複雜的數據請求之類的,因為這部分過於複雜,我不展開說了,總之,主機會發一些東西,包括速度協商(是USB1.1還是USB2.0)等信息。
這個時候,會產生硬體中斷,上報device connect事件,同時一些硬體的寄存器也會發生變化,在此之前,都是硬體做的事情,跟軟體沒什麼關係。
3. 到這一步,USBD/Hub驅動(具體是哪個我也不清楚,因為要問微軟才知道)會發Port Reset/Clear Feature/Get Device Descriptor,按規範來說後面還可能會發Set Configuration等等,如果在這一部分出了錯,那麼表現就是「無法識別的USB設備」,對應微軟代碼里的DeviceFailedEnumeration這個錯誤。
4. 如果能得到設備描述符(Device descriptor),剩下的工作就是根據描述符里的內容去匹配驅動了,這一步如果失敗了,表現為「未知的設備」,注意未知和無法識別的USB設備是兩個不同的錯誤。
5. 最後一步就是載入驅動並工作了,如果驅動無法載入或者啟動失敗,就會在設備管理器里看到設備帶一個感嘆號,狀態應該是設備無法啟動。
以上是一般Windows上的USB設備的安裝流程。
所以題主你遇到的錯誤,其實就是代碼里里的DeviceFailedEnumeration這個錯誤(定義在enum USB_CONNECTION_STATUS里),問題是微軟的文檔里並沒有說這個錯誤是哪個位置返回的,所以究竟是出了什麼錯誤,只能猜。
通常來說,大多數人都認為DeviceFailedEnumeration是發生在獲得描述符失敗上,描述符是寫在firmware里的,正常的USB設備一般都是無法更改它的(用特殊軟體才行),這東西失敗了,就說明USB的那塊控制晶元有毛病,U盤裡,控制晶元是這個東西(紅圈):
註:旁邊的大的是快閃記憶體,圖片來自網路。U盤以及大多數USB設備損壞都是它壞了,Flash一般很難壞掉(除非故意寫壞,或者用質量較差的片子),因為USB控制晶元比較脆弱(也有不脆弱的,就是貴),USB插拔時的電流不是很穩定的,電流過大會燒壞它,所以影響USB設備壽命的最大原因是插拔。
題主你的現象是時好時壞,那就是這個小東西接觸不良(受潮、物理損壞),或者裡面有東西快要壞了(過去不穩定的電流衝擊導致工作不穩)。
解決方法,其實也沒什麼解決方法,把它拆了換一個就可以,但問題是拆它很麻煩,找一個一樣的換上去也很難,所以一般情況下就是壞了就壞了吧。
另外,部分設備供電不足也會有這個問題,但具體要看設備,有些設備在供電不足時返回的錯誤是供電不足,有些設備直接沒有返回直接失敗,所以也無法判斷是否真是供電不足。對於供電不足,WDK里倒是有錯誤碼:DeviceNotEnoughPower,但實際微軟用了沒就不知道了。
最後再強調一下,終極答案是翻微軟的源碼,否則這麼一個錯誤是無法判斷具體是哪一步出了問題的。不翻代碼的話,拿USB分析儀也可以,但分析儀幾十萬一個,普通用戶肯定沒幾個人買它。
Windows的USB部分完整的連接狀態代碼:
#if (_WIN32_WINNT &>= 0x0600)
typedef enum _USB_CONNECTION_STATUS {
NoDeviceConnected,
DeviceConnected,
DeviceFailedEnumeration,
DeviceGeneralFailure,
DeviceCausedOvercurrent,
DeviceNotEnoughPower,
DeviceNotEnoughBandwidth,
DeviceHubNestedTooDeeply,
DeviceInLegacyHub,
DeviceEnumerating,
DeviceReset
} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;
#elif (_WIN32_WINNT &>= 0x0501)
typedef enum _USB_CONNECTION_STATUS {
NoDeviceConnected,
DeviceConnected,
DeviceFailedEnumeration,
DeviceGeneralFailure,
DeviceCausedOvercurrent,
DeviceNotEnoughPower,
DeviceNotEnoughBandwidth,
DeviceHubNestedTooDeeply,
DeviceInLegacyHub
} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;
#else
typedef enum _USB_CONNECTION_STATUS {
NoDeviceConnected,
DeviceConnected,
DeviceFailedEnumeration,
DeviceGeneralFailure,
DeviceCausedOvercurrent,
DeviceNotEnoughPower,
DeviceNotEnoughBandwidth
} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;
#endif
USB設備插入後主要有三個階段:
一、主機一直在監聽所有的USB口電壓變化,設備插入後,電阻改變;
如果設備介面損壞,插入後電阻變化不正常,主機無法檢測到設備被插入,那麼系統不會有任何提示。二、主機發現有設備插入後,會試圖與設備通信,得到設備的基本信息(如字符集描述、產商、產品描述、型號等等);
如果設備損壞或介面接觸不良,導致不應答主機的部分或全部詢問,超時後系統會提示「無法識別的USB設備」,一段時間後主機會再次嘗試詢問。三、根據設備應答,主機判斷是否能夠提供該設備的驅動程序;
如果主機找不到設備的驅動程序,系統會提示「無法安裝XXX」或「無法找到設備的驅動程序」,但此時進入資源管理器能查看到該設備的基本信息。題主應該第二種設備介面接觸不良的情況,主機反覆重試詢問得到設備的信息後也有可能成功識別設備我是題主,自問自答。
補充信息:抱著死馬當活馬醫的想法,拆解了鍵盤,電路板看不到異常,牛屎晶元,也沒有其他辦法了。然後鍵盤再裝起來,插上再試,屢試不爽,完美修復,這段話就是這個鍵盤輸入的。雖然我不知道到底是什麼問題以及怎麼解決的,不過通過這個問題對系統識別USB設備增加了了解,謝謝各位。
謝謝底下的各位朋友的評論...
果然還是時間太久了...而且當時剛畢業只是應急,一知半解的寫過一點,試圖來回答一下果然被噴了...就當拋磚引玉吧...以下是原回答,基本是錯的...謝謝評論區的各位耐心看完...首先作為一個寫過單片機USB傳輸的人,我覺得可以勉強回答一下...(年輕不懂事瞎玩,玩得不精...就是網上各種代碼抄了以後拼一起...具體原理還有很多不懂的...)
不過那是好多年前了,現在記憶有點模糊...儘力而為吧...首先USB裡面有四根線...兩根電源線,兩根數據線...電腦的USB口電源線供電5V..額定電流好像是500mA...所以USB的負載最大只能到2.5W
這也就是手機充電的時候,插電腦比插充電器充得慢的原因...供電正常了...電源線搭上了,數據線也搭上以後...電腦會發一個詢問請求(或者是單片機主動發上去的?不太記得了...)這個詢問的數據包有自己的格式...大概包括設備類型,設備名,傳輸頻率,傳輸方式等等什麼的...設備類型好像包括四種還是幾種...一般鍵盤滑鼠就是PID類型還有一種類型是存儲類型,就是常見的U盤類型...設備名就是我們一般插了USB設備以後,windows右下角那個黃色氣泡裡面的文字...傳輸頻率和傳輸方式...
USB最高我記得好像可以達到48MHz傳輸頻率...但是高頻容易丟數據...好像有12,24,48可選...傳輸方式忘了...設備溝通完了以後...一般的操作系統都有裝一些默認驅動嘛...比如我的USB通過詢問請求返回給電腦告訴上位機,我是U盤,傳輸24MHz...那麼電腦就按照U盤的的解析方式解析我發上來的數據包...比如我說我是鍵盤,那麼上位機就按照鍵盤來解析數據包...默認的數據包格式是有國際規範的...你的設備是哪種USB設備,就得按照固定的格式編碼數據包...
但是數據包格式是可擴展的...比如多媒體鍵盤,多了一些非標準鍵盤的按鍵...按這些按鍵的時候,就寫了一些擴展協議包...電腦上如果安裝有特定的驅動,那麼這些擴展數據包就可以正常解析,否則的話就基本是被丟包的...所以特殊的鍵盤按鍵需要在電腦端安裝相應的驅動...最後回到樓主的問題我覺得可能兩種情況1,USB介面的電源線接觸不良,時斷時連...或者有可能就是USB老化了以後電壓供電不夠...比如USB標準電壓需要5V,可能4V也能勉強正常工作...可能你供電3.8V就只能工作一下,功耗大了,供電跟不上就斷了...就像你拉著一個很重的拖車...車太重了,你不能一直拉著走...可能你就是拉一段停下來休息一下...表現在電腦上就是連上一陣子工作一下...然後斷掉...過會兒再連上...
2,可能是USB設備的晶元老化壞了...這就相當於數據包傳輸不穩定...我沒記錯的話,USB好像有兩種傳輸方式...一種是存儲方式,USB只往上位機發數據,不管你接不接...另一種就是高保證傳輸數據...這種情況下,發的數據都是要上位機確認的,沒確認就要重發...貌似在這種傳輸下數據包如果老錯的話,電腦會錯誤斷開的...很久沒玩單片機了...有錯誤請輕拍...
如果鍵盤沒壞,可能是靜電造成的,關機取下電源線和電池,反覆按幾次開機鍵,就好了。很多複雜的我都試過了,只有這個成功。
USB 口的電壓不夠,多半是 USB 口銹了,少部分情況是電源供電不足。和驅動沒關係。
我的筆記本是這樣的,左邊有兩個usb,一個黑的,一個藍的,鍵盤插在黑的上面提示無法識別,鍵盤上的燈也不亮,插在藍的上面,馬上就能用了。
壞了並不等於徹底壞掉,由於故障是因為非電子器件徹底損壞,比如某個元件脫焊 或者接觸不良均會導致此種情況發生,而電子元件通電後可能由於熱量產生的微量熱脹冷縮會使某些可能暫時未能正常連接的焊點/接觸不良的位置可正常接觸。於是形成了這種通電一段時間後可能能正常工作的現象。此處僅僅列舉其中一種可能情況,並非絕對。個人認為接觸不良是最大可能。
推薦閱讀:
※求問滑鼠是如何做到一插USB就安裝驅動的?我應該怎麼找這方面的資料?怎麼找USB上的電路圖? ?
※滑鼠左鍵一點擊或者選定桌面文件就會顯示刪除這個文件是怎麼回事?
※如何看待樂視宣稱自己引領了Type-C的潮流?
※如何給樹莓派usb hub供電?
※安卓手機充電介面為什麼會壞掉?