以文本方式查看主題 - 曙海教育集團論壇 (http://www.hufushizhe.com/bbs/index.asp) -- WinCE系統定制與驅動開發 (http://www.hufushizhe.com/bbs/list.asp?boardid=36) ---- wince下usb驅動攻堅戰 (http://www.hufushizhe.com/bbs/dispbbs.asp?boardid=36&id=1833) |
-- 作者:wangxinxin -- 發布時間:2010-11-26 14:08:26 -- wince下usb驅動攻堅戰 首先給出一個ED和TD的鏈表結構圖,相信有了這個圖對代碼的理解就容易多了! HeadPtr-->ED-->ED-->ED-->ED ED-->TD-->TD-->TD... 根據OHCI spec:每個ED(Endpoint Descriptor)描述USB設備的一個端點的所有數據傳輸,所有的ED被連接在一起;而TD(Transfer Descriptor)描述的才是最終要在USB總線上傳輸的數據包,屬于同一個USB設備端點的TD被連接在一起,并掛在相應的ED上。 1)ohcd.c
該文件在platform下,可替代wince自帶的system.c文件(在public/common/oak/drivers/usb/hcd/ohc/下)。該文件中的函數被hcddrv.c文件中的HCD_流形式接口函數調用。 2)hcddrv.cpp
該文件在public/common/oak/drivers/usb/hcd/common下面,文件中的具體設置函數: HcdMdd_CreateMemoryObject HcdMdd_CreateHcdObject HcdMdd_DestroyMemoryObject HcdMdd_DestroyHcdObject HcdMdd_PowerOn HcdMdd_PowerDown HcdMdd_SetCapability 又被ohcd.c中的函數調用 CUHcd-->CHW-->CHcd(繼承關系,CUHcd的實例被創建) 初始化函數調用流程
1)HCD_Init()[hcddrv.cpp] 2)HcdPdd_Init()[ohcd.c]
3)InitializeOHCI()[ohcd.c]
配置IOBASE,IRQ。可讀取注冊表,也可以通過程序自配 4)HcdMdd_CreateMemoryObject();HcdMdd_CreateHcdObject()[hcddrv.cpp]
HcdMdd_CreateMemoryObject()==>CPhysMem->InittedOK()[usb/hcd/common/cphysmem.hpp] HcdMdd_CreateHcdObject()==>CHcd->DeviceInitialize()[usb/hcd/ohcd2/cuhcd.cpp] CHcd::DeviceInitialize()過程
1)CDeviceGlobal::Initialize()[usb/hcd/common/cdevice.cpp] 加載usbd.dll,并調用其中的HcdAttach()[usb/usbd/usbddrv.cpp]用hcddrv.cpp中的gc_HcdFuncs來設置usbd層的功能函數[pHcd->pHcdFuncs] 2)CHW::Initialize()[usb/hcd/ohcd2/chw.cpp] 初始化硬件,控制器寄存器,并創建線程用于處理HC的IST,并調用SignalCheckForDoneTransfer()來偵聽傳輸的完成 3)CHCCArea::Initialize()[usb/hcd/ohcd2/cpipe.cpp] 初始化CPipe的靜態變量,建立一個禎鏈表的空調度,同時建立中斷Queue Head樹,創建線程用于處理傳輸完成。 IoPortBase = USB_BASE 以及Sys_Irq的初始化流程
1)HcdPdd_Init()[ohcd.c] 2)InitializeOHCI()[ohcd.c] 3)ConfigureOHCICard()[ohcd.c]:在此配置;HcdMdd_CreateHcdObject()[hcddrv.cpp] 4)CreateHCDObject()[cuhcd.cpp]:在此new CUhcd并初始化其父類CHW,在CHW初始化時初始化其成員變量m_portBase[chw.cpp] Transfer流程
所有的IssueTransfer最終都要調用CPipe::IssueTransfer()[cpipe.cpp] 1)new STransfer并配置 2)拷貝client buffer到out transfer 3)AddTransfer:設置TDs鏈表并加到相應的ED下 4)ScheduleTransfer 5)CHW::ListControl() [以下以bulk為例]
1)在CHW::Initialize()中有 CHW::m_pBulkHead = &m_portBase->HcBulkHeadED; 2)在各pipe類的::OpenPipe()中有 *(CHW::m_pBulkHead) = (pa)m_pED; 故此:傳輸過程由HC根據各ED值來讀寫指定內存,具體數據在各ED下的TDS鏈表中的各TD中,過程由HcControl和HcCommandStatus寄存器的各相應位來控制。
|