USB 韌體解析-1

Nov 1, 2007 2 分鐘 900 字 #USB

回想去公所辦事的狀況:當一踏進大門,義工媽媽就馬上問"帥哥,請問要來辦什麼事情?"(純屬事實,絕無虛構)並且引導我去抽號碼牌。然後坐著等待叫號之後再去櫃台填表辦事。這就是一個典型的官僚系統。

原始的USB界面(也就是非OTG的USB)就像現實世界的官僚系統一樣,全部都是PC(host 端)主導一切的動作,甚至連上傳資料都不能裝置端自己要傳就傳,一定要host叫你傳才能傳。所以實作上就非常簡單,不會發生其他網路界面那種搶頻寬的問題。

接下來的解說需要去usb.org下載USB2.0規格書配合來看。

裝置插入

我們可以看看剛才下載的USB_20.pdf 的7.1.5.1。根據USB 2.0的規範,USB的裝置端需要如下圖所示依裝置的速度並聯一個電阻在D+或D-與3.3V間。

分辨USB全速/低速裝置

看到這裡,我們就可以知道在自製USB滑鼠裡畫的電路圖是一個低速的USB裝置,也知道PC怎樣知道有個有個"帥哥"進來而該派"義工媽媽"去幫忙抽號碼牌了。可是電阻的接法好像跟上面的圖不太一樣也跟USB 2.0規範不太一樣耶?這個部份先保留,等到USB高級心法再詳細解說。

Device Request

再來也跟現實狀況一樣,在抽號碼牌前都是由義工媽媽來服務,等到抽完號碼牌後就要等到叫到號碼後才去櫃台由小姐服務。USB裝置在剛被RESET或是接到PC時都是固定為0號,等到PC下了一個Set Address的Request後變成由HOST指定的號碼了。

在USB的世界裡一切就是很官僚,一切都只有填充題。所有要填的表格和該填什麼都在USB_20.pdf的9.3和9.4裡。

韌體解析-1

經過前面的解說和參考資料的研讀後,我們可以知道USB韌體最重要的部份就是在處理request表格。以我們一直當範例的EasyLogger來說,在usbdrv.c的347行附近像下面這樣就是在處理request表格。

}else if(rq->bRequest == USBRQ_SET_ADDRESS){    /* 5 */
usbNewDeviceAddr = rq->wValue.bytes[0];
}else if(rq->bRequest == USBRQ_GET_DESCRIPTOR){ /* 6 */
flags = USB_FLG_MSGPTR_IS_ROM | USB_FLG_USE_DEFAULT_RW;
if(rq->wValue.bytes[1] == USBDESCR_DEVICE){ /* 1 */

//
//
//

不過這個程式不太好閱讀,有興趣者可以參考Silicon Labs的USB Firmware Programmer’s Guide 第34頁開始的程式碼,這份文件寫得很工整很容易閱讀。

今天就暫時在這裡告一段落。

`