WinCE5.0的USB Camera流接口驅動開發

 引 言
   

        WinCE5.0是一個32位、多任務、多線程的實時嵌入式操作系統。USB Camera 以其良好的性能和低廉的價格得到廣泛的應用,同時因其靈活、方便的特性,易於集成到嵌入式系統中。

       通過採用USB Camera可以在WinCE5.0下方便地得到實時圖像。但是由於嵌入式硬件環境的多樣性以及WinCE5.0對USB設備驅動開發只提供了一些底層支持,攝像頭廠商尚未提供WinCE5.0下USB攝像頭的驅動,因此開發出WinCE5.0下USB攝像頭驅動具有實際的意義和價值。本文正是針對這一情況,對WinCE5.0下USB設備驅動開發進行研究,並設計出基於流接口驅動模型的USB攝像頭驅動程序。現在已經開發出來的驅動適用於Zc030x PLUS這一系列的攝像頭。Samstmg 2410爲實驗的硬件平臺。


      1 WinCE5.0下USB總線驅動框架
   

       USB系統由USB主機、一個或多個USB設備和物理總線組成。主機上又分兩層:較高的包含USB設備驅動程序的軟件層和主機控制器硬件層,也稱作“適配層”。主機的主要任務是控制對USB設備的雙向數據傳輸。物理總線是一組USB電纜,用來將控制器和外圍設備連接起來。WinCE5.0的USB系統軟件由兩層組成:USB設備驅動程序層和底層的由WinCE5.0實現的USB函數層。

      USB設備驅動程序使用USB函數來建立與它們所控制設備的連接,並對這些設備進行配置和通信。較低的USB函數層本身又由兩部分組成——較高的通用串行總線驅動程序(USBD)模塊和較低的主控制器驅動程序(HCD)模塊。HCD提供了抽象的主機控制器,且對主機控制器所見到的USB系統的數據傳輸進行抽象。USBD提供一個抽象的設備,且對USBD客戶和USB設備功能部件之間的數據傳輸進行抽象。USB設備驅動程序使用USBD接口函數與外圍設備進行通信。
   

      IHV和USB設備製造商利用USBD提供的函數來實現USB設備的驅動程序。OEM負責給基於WinCE的平臺提供HCD模塊,這樣相應的硬件才能與USBD模塊進行交互。圖1說明了與主機的USB硬件和外圍設備相對應的軟件的各個層。

      2 WinCE5.0下流驅動模型
   

      基於WinCE5.0平臺的兩種專用的驅動模型爲:本機設備驅動程序和流接口驅動程序。本機設備驅動程序適合於集成到WinCE 5.0 平臺的設備;而後者則是一般類型的設備驅動程序,適用於大部分外圍設備,如調制解調器、打印機等。對大多數USB外圍設備來說,適用於採用流接口驅動程序模型來開發驅動程序。
   

      流接口驅動程序是一種可以定製接口的驅動模型,一般由設備管理器負責管理。它把設備管理器和應用程序的命令轉換成所控設備的適當動作所需信息。流接口驅動程序需要實現一組固定的流接口函數,供給WinCE5.0系統內核使用。

       USB設備的流接口驅動程序和WinCE5.0系統其他部件間的關係如圖2所示。流接口驅動程序通過系統提供的文件系統API與應用程序交互;而系統通過設備管理器完成對流接口驅動程序的加載、卸載等管理工作;流接口驅動程序通過調用USBD模塊提供的接口函數實現與底層USB設備通信。

       本文使用的流接口函數方法如表1所列。

      USB設備驅動程序必須輸出的函數有:
   

        ①USBDeviecAttach()。當USB設備連接到計算機上時,USBD模塊就會調用此函數。這個函數主要用於初始化USB設備,取得USB設備信息,配置USB設備,並且申請必需的資源。
        ②USBInstallDriver ()。主要用於創建一個驅動程序加載所需的註冊表信息,例如讀/寫超時、設備名稱等。
        ③USBUninstallDriver ()。主要用於釋放驅動程序所佔用的資源,以及刪除UsbInstallDriver ()函數創建的註冊表等。
   

       上述3個函數接口是所有的USB驅動程序必須提供的,缺一不可。
   

       另外較爲重要的是USB設備驅動程序的註冊表配置。一般的USB設備驅動程序的註冊表配置在[HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\口]下,每個驅動程序的子鍵都有Group 1_ID\Group2_ID\Group3_ID\DriverName 格式,設備的子鍵由供應商、設備類和協議信息通過下劃線組成。表2列出了允許的組合。

        以本實驗所採用的USB Camera爲例,該USB Cam-era的供應廠商ID爲0X046d,設備ID爲0x08a2,那麼它的加載註冊表應該寫爲:

       需要注意的是,註冊表的構成都是以十進制數值來標識的,也要注意十進制和十六進制之間數的轉換。

       3 WinCE5.0下USB攝像頭驅動程序
   

       實驗使用的USB Camera是中星微公司的301芯片組的Zc030x,它的Vid/Pid爲0x046d、0x08a2。由於實時圖像數據傳送量比較大,很多USB Camera產品在圖像傳輸之前已進行了數據壓縮處理,如果不知道解碼算法,是沒有辦法在WinCE上獲得圖像的。在開發的時候主要使用SnoopyPro,它是一款可以分析USB通信數據的軟件,輔助進行Zc030x的驅動開發工作,最後成功開發出Zc030x在WinCE5.0下的驅動程序。下面結合USBCamera驅動開發說明驅動中的數據流向和必要的函數使用。首先是具體的註冊表信息:


   

       其中,hDevice是由系統提供的當前外設的句柄,通過它可以獲取外設的信息,如VID、PID等;UsbFuncs是系統提供的指向USBD函數的函數指針,通過它可以調用USBD函數,如GetlsochResult、IssuelsochTransfer等;AcceptControl指針指向的bool值需要我們確定,如果可控,令其爲TRUE,否則爲FALSE。
   

       在這個函數裏面,要做的工作包括確定外設是否可控,分配和填寫設備的上下文內容,調用ActivateDevjce()函數在“Drivers\USB\ClientDrivers\Camera_Class”鍵值中註冊分配到的設備上下文的指針(其中Camera_Class是對USB Camera的命名),同時ActivateDevice在註冊表[HKEY_LOCAL_MACHINE\Drivers\Active\N]中登記設備上下文的指針,其中N爲整數,它是系統自動分配給此驅動的數字。系統在調用ActivateDevice()過程中,又會自動調用CAM_Init函數。
   

       DWORD CAM_Init(LPCTSTR pContext,LPCVOIDIp VBusContext)
   

       其中,pContext是系統自動傳入的字符串內容,也是上面的鍵名,即[HKEY_LOCAL_MACHINE\Drivers\Active\N];CAM_Init要完成的就是在此鍵下讀出設備上下文的指針,將其作爲DWORD返回;IpvBusContext不用考慮。
   

       在USBDeviceAttach()中,最後要完成的工作是在此函數內調用USBD模塊的RegisterNotificationRoutine函數登記註冊DeviceNotify函數。這個DeviceNotify函數是必需的,在設備被移走後,系統調用這個函數完成相應的善後工作。
   

       BOOL WINAPI DeviceNotify(LPVOID lpvNotifyPa-rameter DWORD dwCode.LPDWORD dwInf01.LPDW0RDdwlnfo2.LPDWORD dwlnfo3.LPDWORD dwlnfo4)
   

       其中,IpvNotifyParameter是設備的上下文句柄,在RegisterNoticationRoutine中作爲參數傳入;dwCode是系統調用此函數的原因,如設備被移走,dwcode的值就爲USB_CLOSE_DEVICE,相應的,用戶進行卸載DLL工作;dwInfol,…,dwInfo4沒有使用。
   

       自此,系統在USBDeviceAttach中完成對所加USB外設的驅動加載。當有用戶調用CreateFile函數,系統會將用戶填入CreateFile()的參數值,直接傳到CAM_Open()。
   

       DWORD CAM_Open(DWORD hDeviceContext,DWORDAccessCode,DWORD ShareMode)
   

       其中,hDeviceContext是驅動上下文句柄,由系統自動填充;AccessCode是訪問模式,ShareMode是共享模式,均由CreateFile()傳遞過來;CAM_Open的工作是將hDe-viceContext以DWORD的形式返回,再作爲CreateFile()的句柄值返回給用戶。當用戶調用CloseHandle()時,系統將直接調用CAM_Close(),用於關閉一個驅動程序。
   

       B00L CAM_Close(DWORD hOpenContext)
   

       其中,hOpenContext是設備驅動的引用事例句柄,由CAM_Open創建。本驅動中,所有對USB Camera的操作均通過IOControl()映射到CAM_IOControl來完成。下面是CAM_IOControl的部分源碼分析:


       由於本驅動是針對USBCamera的,因此CAM_Write、CAM_Read、CAM_PowerUp、CAM_PowerDown並沒有內容;但是隻要用戶調用WriteFile,系統就將映射到CAM_Write。其他函數類似。通常,Camera對圖像的壓縮採用標準是MJPEG算法。在Zc030x上正是採用這一算法完成對數據壓縮的。只要在驅動上增加MJPEG的解碼算法,還原壓縮數據,就可以正確顯示圖像了。至此,整個USB Camera的驅動編寫工作完成。經過實驗驗證,已經實現了最高爲25幀/s,大小爲320×240的圖片的傳輸。

       結 語
   

       本文介紹了WinCE5.0下USB設備驅動框架,結合USB Camera的驅動開發實例說明了在USB驅動框架中驅動數據的流動方向,並已在中星微公司的301PLUS和303這兩個系列的攝像頭上得到成功運用和實踐。所採用的程序設計方法及思想,對其他類似嵌入式系統軟件的設計也有較高的參考價值。

發佈了16 篇原創文章 · 獲贊 0 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章