http://www.cnblogs.com/harber/archive/2008/01/19/1045606.html
原文:: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1334401
1、基礎知識:
1)系統調用是作業系統核心和應用程式之間的接口,裝置驅動程式是作業系統核心和機器硬體之間的接口。裝置驅動程式為應用程式屏蔽了硬體細節,在應用程式看來硬體隻是一個裝置檔案,應用程式可以像操作普通檔案一樣對硬體裝置進行操作。裝置驅動是核心的一部分。
2)驅動程式完成以下功能:
——對裝置初始化和釋放;
——把資料從核心傳送到硬體和從硬體讀取資料;
——讀取應用程式傳送給裝置檔案的資料和回送應用程式請求的資料;
——檢測和處理裝置出現的錯誤。
3)上層應用程式運作在使用者模式(非特權模式,Ring 3),代碼被嚴格限制執行。如不能執行硬體IO指令。所有的這些被阻止的操作如果想運作必須通過陷阱門來請求作業系統核心。
4)作業系統核心運作在核心模式(特權模式,Ring 0),可以執行所有有效的CPU指令。包括IO操作,可通路任何記憶體區。
5)整個硬體系統資源在驅動程式面前是赤裸裸的,驅動可以使用所有系統資源,編寫驅動程式時我們必須格外小心驅動代碼的邊界條件,確定它們不會損壞整個作業系統。
2、Windows支援的驅動:
1)虛拟裝置驅動程式(Virtual Device Driver):Windows3.1(Windows95/98/Me)
2)核心模式驅動程式(Kernel Mode Driver):Windows NT
3)Win32驅動程式模型(Win32 Driver Mode):從Windows98開始使用。
其中WDM是目前主流,然而在WinCE系統中,由于硬體資源有限和嵌入式系統的特點,對其的支援非常有限。
3、WinCE系統驅動簡介:
1)WinCE畢竟是一個嵌入式系統,有其自身的特殊性,為了提高運作效率,所有驅動皆為動态連結庫,驅動實作中可以調用所有标準的API。而在其他Windows系統中可能的驅動檔案還有.vxd, .sys和動态連結庫。
2)WinCE驅動從結構上講分為本地驅動(Native Driver)和流接口驅動(Stream Driver)。
——本地驅動主要用于低級、内置的裝置。實作它們的接口并不統一,而是針對不同類型的裝置相應設計。是以開發過程相對複雜,沒有固定的模式,一般做法是通過移植、定制現有的驅動樣例來實作。
——流接口驅動是最基本的一種驅動結構,它的接口是一組固定的流接口函數,具有很高的通用性,WinCE的所有驅動程式都可以通過這種方式來實作。流接口驅動程式通過檔案系統調用從裝置管理器和應用程式接收指令。該驅動程式封裝了将這些指令轉換為它所控制的裝置上的适當操作所需的全部資訊。
流接口驅動是動态連結庫,由一個叫做裝置管理程式的特殊應用程式加載、管理和解除安裝。與本地驅動程式相比,所有流接口驅動程式使用同一組接口函數集,包括實作函數:XXX_Init、XXX_Deinit、XXX_Open、XXX_Close、XXX_Read、XXX_Write、XXX_PowerUp、XXX_PowerDown、XXX_Seek、XXX_IOControl,這些函數與硬體打交道。使用者函數:CreateFile、DeviceIoControl、 ReadFile、 WriteFile,這些函數友善使用者使用驅動程式。
3)WinCE下驅動的加載方式:
——通過GWES(Graphics, Windowing, and Events Subsystem):主要加載與顯示和輸入有關的驅動,如滑鼠、鍵盤驅動等。這些驅動一般為本地驅動。
——通過裝置管理器:兩種結構的驅動都加載,加載的本地驅動主要由PCMCIA Host Controller,USB Host Controller driver,主要是總線類的驅動;流接口驅動主要有音頻驅動,串并口驅動。
——動态加載:前兩者都是系統啟動時加載的,動态加載則允許裝置挂載上系統時将驅動調入核心,主要有外接闆卡驅動,USB裝置驅動等。
4、流接口驅動函數介紹:
1)DWORD XXX_Init(LPCTSTR pContext, LPCVOID lpvBusContext);
pContext:指向一個字元串,包含系統資料庫中該流接口活動鍵值的路徑
lpvBusContext:
該函數是驅動挂載後第一個被執行的。主要負責完成對裝置的初始化操作和驅動的安全性檢查。由ActiveDeviceEx通過裝置管理器調用。其傳回值一般是一個資料結構指針,作為函數參數傳遞給其他流接口函數。
2)BOOL XXX_Deinit(DWORD hDeviceContext);
hDeviceContext:XXX_Init的傳回值。
整個驅動中最後執行。用來停止和解除安裝裝置。由DeactivateDevice觸發裝置管理器調用。成功傳回TRUE。
3)DWORD XXX_Open(DWORD hDeviceContext, DWORD AccessCode , DWORD ShareMode);
hDeviceContext:XXX_Init的傳回值。
AccessCode:通路模式标志,讀、寫或其他。
ShareMode:驅動的共享方式标志。
打開裝置,為後面的操作初始化資料就夠,準備相應的資源。應用程式通過CreateFile函數間接調用之。傳回一個結構指針,用于區分哪個應用程式調用了驅動,這個值還作為參數傳遞給其他接口函數XXX_Read、XXX_Write、XXX_Seek、XXX_IOControl。
4)BOOL XXX_Close(DWORD hOpenContext);
hOpenContext:XXX_Open傳回值。
關閉裝置,釋放資源。由CloseHandle函數間接調用。
5)DWORD XXX_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count);
hOpenContext:XXX_Open傳回值。
pBuffer:緩沖區指針,接收資料。
Count:緩沖區長度。
由ReadFile函數間接調用,用來讀取裝置上的資料。傳回讀取的實際資料位元組數。
6)DWORD XXX_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count);
hOpenContext:XXX_Open傳回值。
pBuffer:緩沖區指針,接收資料。
Count:緩沖區長度。
由WriteFile函數間接調用,把資料寫到裝置上,傳回實際寫入的資料數。
7)BOOL XXX_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut);
hOpenContext:XXX_Open傳回值。
dwCode:控制指令字。
pdwActualOut:實際輸出資料長度。
用于向裝置發送指令,應用程式通過DeviceIoControl調用來實作該功能。要調用這個接口還需要在應用層和驅動之間建立一套相同的指令,通過宏定義CTL_CODE(DeviceType, Function, Method, Access來實作。如:
#define IOCTL_INIT_PORTS \ CTL_CODE(FILE_DEVICE_UNKNOWN,0X801,METHOD_BUFFERED,FILE_ANY_ACCESS)
8)void XXX_PowerDown(DWORD hDeviceContext);
hDeviceContext:XXX_Init的傳回值。
負責裝置的上電控制。
9)void XXX_PowerUp(DWORD hDeviceContext);
hDeviceContext:XXX_Init的傳回值。
負責裝置的斷電控制
10) DWORD IOC_Seek(DWORD hOpenContext, long Amount, WORD Type)
hOpenContext:XXX_Open傳回值。
Amount:指針的偏移量。
Type:指針的偏移方式。
将裝置的資料指針指向特定的位置,應用程式通過SetFilePointer函數間接調用。不是所有裝置的屬性上都支援這項功能。
5、流接口驅動的加載和系統資料庫設定:
系統啟動時啟動裝置管理程式,裝置管理程式讀取HKEY_LOCAL_MACHINE\Drivers\BuiltIn鍵的内容并加載已列出的流接口驅動程式。是以系統資料庫對于驅動的加載有着關鍵作用。下面是一個例子:
【HKEY_LOCAL_MACHINE\Drivers\BuiltI\IOControler】
“Prefix”=”XXX”
“Dll”=”drivername.dll”
其中,“Prefix”=“XXX”中的XXX要和XXX_Init等函數中的一樣。CreateFile建立的驅動名字首也必須和它們一緻。
6、驅動程式的編寫、編譯及其相關目錄、配置檔案的格式和修改:
1)首先必須在PB相應平台的的driver目錄下建立要建立的驅動所在的目錄。如在x:\Wince420\platform\smdk2410\drivers目錄下建立一個IOCtrol目錄。
2)修改Drivers目錄下的dirs檔案。
3)建立驅動源檔案XXX.c,在該檔案中實作上述流接口函數。并且加入DLL入口函數:
BOOL DllEntry(HINSTANCE hinstDll,
DWORD dwReason,
LPVOID lpReserved
)
4)建立Makefile和Sources和.def檔案,控制編譯。
5)使用CEC Editor修改cec檔案,編譯添加的新特性。
6)複制新生成的4個檔案到Release目錄下,修改系統資料庫檔案platform.reg和platform.bib檔案。
7)Make Image。
8)DownLoad Image。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
/
其他的驅動知識:
http://hi.baidu.com/yinan1989lu/blog/item/a44446f28c2aca44342acc63.html
http://hi.baidu.com/yinan1989lu/blog/item/c252752544fdfb3fd507425b.html
基于WinCE的I2C驅動程式設計
http://www.cnblogs.com/harber/archive/2008/09/17/1292922.html