WinCE6.0 USB Fubction驅動加載流程

    今天來看看WinCE6.0平臺下USB Function驅動部分加載流程,USB Function是指WinCE設備相對於PC機而講的,通常能夠支持Mass StorageRNDISPrinter或者Serial Class。在實際中用的最多的莫過於串口功能,做爲一個串口設備鏈接PC機,實現activesync的功能。
       在目錄WINCE600\PUBLIC\COMMON\OAK\DRIVERS\USBFN下面有微軟提供的關於USB Function的驅動程序,此目錄下的層次結構爲:
    在以前的博文中已經對該目錄的總體功能進行了說明,這裏就不重複了。
    CONTROLLER控制器文件夾是整個Function驅動的入口處,在該目錄下的MDD文件夾內實現並導出了總線接口,並利用該接口加載USB Function Client驅動。下面具體分析。
    注意在CONTROLLER目錄下面有一個NET2280的文件夾,它實現的NET2280控制器的PDD部分。可是在common.reg下面並無找到相關的註冊表信息,說明實際的設備平臺中並無使用微軟默認的控制器型號。
       本人使用的平臺是Android6410的開發板,在PLATFORM目錄下發現了USB Funtion ContrllerPDD部分,在 WINCE600\PLATFORM\SMDK6410\SRC\DRIVERS\OTG\Device的目錄下,這裏使用了OTG做爲了Function功能。該目錄下面的內容爲:
    同時在platform.reg文件中發現了關於控制器的註冊表信息,以下:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SC6410USBFN]
  "Dll"="s3c6410_usbfn.dll"
  "Prefix"="UFN"
  "Order"=dword:20
  "Priority256"=dword:64
  "Irq"=dword:60        ; USB OTG Virtual IRQ = 96 (0x60), Physical IRQ = 58
  "BusIoctl"=dword:2a0048
  "IClass"=multi_sz:"{E2BDC372-598F-4619-BC50-54B3F7848D35}=%b","{6F40791D-300E-44E4-BC38-E0E63CA8375C}=%b"
    因此係統加載的USB Function Controller驅動是s 3c 6410_usbfn.dll,由設備管理Device.exe從註冊表HKEY_LOCAL_MACHINE\Drivers\BuiltIn下面加載該驅動。
       看看s 3c 6410_usbfn.def文件導出了哪些接口函數:
LIBRARY                S3C6410_USBFN

EXPORTS
        UFN_Init
        UFN_Deinit
        UFN_Open
        UFN_Close
        UFN_PowerDown
        UFN_PowerUp
        UFN_IOControl
    在目錄WINCE600\PUBLIC\COMMON\OAK\DRIVERS\USBFN\CONTROLLER\MDD下面的ufnmdd.cpp文件裏,實現了流接口的入口函數DllEntry()函數,不過該函數並無具體的操做內容。
    接着來看看UFN_Init()函數。在初始化函數中首先建立PUFN_MDD_CONTEXT結構體,用來記錄驅動MDD層的一些信息,包括一些MDD層的接口函數。該信息將會在驅動接口之間經過參數進行傳遞。以後建立了CUfnBus類的一個實例,經過該類能夠加載Client層驅動,而且處理USB function controller驅動的IOCTLS。建立以後便調用CUfnBus::Init()函數完成總線的相關初始化。最後調用PDD層的初始化函數UfnPdd_Init(),完成硬件控制器的一些初始化設置,將PDD層的硬件操做函數封裝成函數列表結構體傳遞給MDD層。
    從上述的過程當中,始終沒有發現如何調用Client驅動的,從參考資料中發現,在建立CUfnBus類以後,會調用該類的成員函數PostInit(),而CUfnBus類是從DefaultBusDriver類繼承過來的,在這個裏面找到了啓動Client驅動的方式。
    PostInit()函數主要調用了四個函數:
函數CUfnBus::GetDefaultClientName用來獲取默認的Client名稱; CUfnBus::CreateChildDefaultBusDriver::InsertChild用來建立一個usb buschild,並添加到相應的list列表中;CUfnBus::ActivateChild則是用來啓動一個Client驅動的。
       在註冊表platform.reg中有一個默認的Client名稱選項,以下:
[HKEY_LOCAL_MACHINE\Drivers\USB\FunctionDrivers]
  "DefaultClientDriver"=-      ; erase previous default

IF BSP_USBFNCLASS == SERIAL
[HKEY_LOCAL_MACHINE\Drivers\USB\FunctionDrivers]
  "DefaultClientDriver"="Serial_Class"
ENDIF BSP_USBFNCLASS

IF BSP_USBFNCLASS == MASS_STORAGE
[HKEY_LOCAL_MACHINE\Drivers\USB\FunctionDrivers]
  "DefaultClientDriver"="Mass_Storage_Class"
ENDIF BSP_USBFNCLASS
    本文的硬件平臺是Android6410開發板,從註冊表中能夠看出,在該平臺下支持WinCE設備爲串口或者大容量存儲器兩種狀態,而微軟提供的能夠支持四種狀態。另外上面有一個環境變量BSP_USBFNCLASS決定了默認的Client驅動是哪一個?而平臺的環境變量定義在文件WINCE600\PLATFORM\SMDK6410\ SMDK6410.bat中,
CUfnBus::ActivateChild函數當中調用了父類的函數DefaultBusDriver::ActivateChild。在文件WINCE600\PUBLIC\COMMON\OAK\DRIVERS\BUSENUM\BUSDEF\defbus.cpp中有類DefaultBusDriver的實現。在父類的ActivateChild()函數中,又調用了類DeviceFolder的成員函數LoadDevice()。類DeviceFolder和類DefaultBusDriver在同一個文件中實現。在DeviceFolder::LoadDevice函數中根據驅動DLL的不一樣類型,調用::LoadLibrary(DevDll)或者::LoadDriver(DevDll),其中DevDll爲驅動的名稱。以後經過GetProcAddress()函數獲取到相應驅動的入口函數地址,並調用驅動的入口初始化函數。
今天就先分析一下加載流程,之後再進一步分析數據傳輸的流程。

參考資料:
Windows CE USB Function Driver驅動簡析(1)
WINCE6.0+S 3C 2443下的usb function(功能)驅動
相關文章
相關標籤/搜索