發表文章

目前顯示的是有「USB」標籤的文章

救火奇兵之 Android USB Host API 反應遲緩

圖片
話說,Android 在某個版本後,開始提供了 USB Host API,這代表開發者可以不必再用 NDK 和硬梆梆的 C 語言去開發 USB 裝置的驅動程式,而可以完全用 Java 來開發。但是,現實往往沒有這麼美好。 日前,就協助了一個案子,解決了一個 USB 裝置驅動程式的問題,起因就是客戶用了 Android USB Host API 去控制 USB 裝置,但發現 USB 裝置的回應一直不如預期,有時像是掉資料,有時像是沒反應。而同樣的控制邏輯,用純 C 開發的驅動程式配上 libusb 就完全正常,所以我們相信肯定不是控制邏輯上的問題。 剛開始,大家都懷疑是 Java 本身的問題,懷疑是不是 JVM 執行驅動程式太慢,而造成接收 USB 裝置的資料時來不及。但我一直保持著懷疑,因為 USB 裝置回傳的資料並不多,如果 JVM 本身的效能連處理這幾 KB 的資料量都如此差,就實在是太可笑了,我無論如何不相信。 還好最後還是解決了,雖然過程曲折。 USB Request Block 的 16KB 限制 事實上,每次最多傳送 16KB 資料,是一個 bulk transfer 的 URB 限制,使用 Android USB Host API 就會直接遭遇到這個問題,所以不管用什麼方法,怎麼收資料,只要資料太大,你最多一次就只能收到 16KB。 多次收資料所發現的延遲問題 當然,既然一次最多只能收 16KB,我們可以分多次向 USB 裝置要求收資料,但就會發現會莫名掉資料。從 USB 的分析器上來看,該有的命令都有,但就是有掉,後續的資料不管怎麼取都是 0。 後續資料為 0,在這個案子的 USB 裝置設計上是可以理解的狀況,因為該 USB 裝置只會保留資料一小段時間,然後就會清空,所以若之後跟它要任何資訊,他都會回傳空的東西回來。這很明顯,就是我們要資料的過程時間,已經超過了該 USB 裝置正常的情況。 而從收到的資料來看,有收到的資料,經驗證過後發現是斷斷續續的,中間有漏資料。經過測試,發現是每個命令之間的間距時間太長,因為該 USB 裝置會不斷復寫一段緩衝區,如果我們太慢去要資料,那段緩衝區就會被新的資料蓋掉,理所當然的,我們就會漏掉一些資料。 經過各種測試紀錄,很明顯的,Android USB Host API 並沒...

淺談 USB 通訊架構之定義(二)

圖片
之前『 淺談 USB 通訊架構之定義(一) 』已經提過 USB 大致上的概念和一些特性,以及如何從 Linux 上去嘗試驗證 USB Device 上的 Information,但還尚未談及 USB Device 是如何與 USB Host 做溝通。而且,初始化的過程也很重要,該過程會讓一個 USB Device 描述自己的『模式(Configuration)』和『介面(Interface)』以及更多配置上的關鍵訊息。雖然這些初始化過程和定義繁雜,但是拜 OS 優良的包裝所賜,一般驅動程式都可以假設已知或是透過簡單的 API 去取得這些資訊以進行開發,因為大多數初始化動作會自動由 OS Kernel 和 Firmware 所完成。 簡單的 USB Device 初始化流程 插上 USB 裝置 Host 請 裝置 報告 『 裝置 描述資訊 (Device Descriptors )』 (此過程又稱為 Enumeration ) 由 Device Descriptors 得知 『 模式的數量 (bNumConfigurations) 』 Host 請 裝置 回報 『 模式的描述資訊( Configuration Descriptors) 』 由 Configuration Descriptors 得知 『 介面的數量( bNumInterfaces ) 』 Host 請 裝置 回報 『 介面 的描述資訊( Interface Descriptors) 』 由 Interface Descriptors 得知 『 端點的數量( bNumEndpoints ) 』 Host 請 裝置 回報 『 端點 的描述資訊( Endpoint Descriptors) 』 由 Endpoint Descriptors 得知 『 該端點的 資料傳輸模式( bmAttributes ) 』等訊息 等待驅動程式進行後續處理 整個 USB Device 的描述結構可以圖表示: 當然,若不是 USB Device 設計者或是 USB Host Controller 晶片的 Firmware/Driver 開發人員,可以不用知道這麼多過程細節,因為無論是 Linux 還是其他作業系統,它們都會將這些最低階的過程包裝起來,等著驅動程式去使用,而 Linux Kernel 上負責此任務的就被稱為...

淺談 USB 通訊架構之定義(一)

圖片
USB(Universal Serial Bus) 的應用範疇以及價值已經不需要再多做說明,其身影從 HID(Human Interface Device)、隨身碟(USB Stick、Flash drive、Pen drive)到各種類比式或非連續訊號接收器(如: Webcam、Microphone、DVB Receiver),更進一步可以講到各種通訊裝置或外接設備,甚至是取代和模擬舊式通訊傳輸線(Serial Port)。USB 所有的 Spec 和相關資訊 ,可參考 http://www.usb.org/ 。 USB 整體運作模式 一般來說 USB 的通訊結構有如 Server/Client,以 PC 上的情形為例,位於主機上的 USB 裝置稱為『USB Host』,我們可以在上面外接上數個裝置(與 USB Host 相連的裝置通常被稱為 USB Device 或 USB Client)。 底層上,『Host 負責主導整個 USB 結構的通訊』,它會輪詢所有的 USB Deivce 以檢查是否有裝置需要傳送資料,所有 USB Device 都必需要等待 Host 的命令,唯有 Host 同意時,USB Device 才可以開始傳送資料。 Host 的行為通常是由 USB Host Controller 在做控制,其控制器是一組控制晶片,而對於現代 PC ,USB Host Controller 的晶片通常都被 Layout 在主機板上,以 PCI Bus 的形式存在供作業系統控制,我們可以使用 lspci 看到它的存在: 00:1a.0 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI Controller #4 (rev 03) 00:1a.1 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI Controller #5 (rev 03) 00:1a.2 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI Controller #6 (rev 03) 00:1a.7 USB Controller: Intel Corporati...