日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式硬件
[導(dǎo)讀]摘要: 介紹了Windows NT4.0內(nèi)核模式設(shè)備驅(qū)動(dòng)程序開(kāi)發(fā)中的一般性過(guò)程。通過(guò)提供一個(gè)最小化驅(qū)動(dòng)程序的核心代碼,解釋各組成部分的結(jié)構(gòu)功能和使用方法。在實(shí)踐中,結(jié)合自身的

摘要: 介紹了Windows NT4.0內(nèi)核模式設(shè)備驅(qū)動(dòng)程序開(kāi)發(fā)中的一般性過(guò)程。通過(guò)提供一個(gè)最小化驅(qū)動(dòng)程序的核心代碼,解釋各組成部分的結(jié)構(gòu)功能和使用方法。在實(shí)踐中,結(jié)合自身的開(kāi)發(fā)需要,可編寫(xiě)出具有實(shí)用價(jià)值的驅(qū)動(dòng)程序。

關(guān)鍵詞:Win32子系統(tǒng) 設(shè)備驅(qū)動(dòng) 系統(tǒng)注冊(cè)表 I/O請(qǐng)求包

Windows NT 以其安全、穩(wěn)定及界面友好等特性逐漸成為工業(yè)控制領(lǐng)域的前臺(tái)操作系統(tǒng)。面對(duì)工業(yè)控制中大量采用的串/并行通信及總線控制等技術(shù),要求用戶(hù)不斷開(kāi)發(fā)出滿(mǎn)足自身需要的硬件設(shè)備,同時(shí)又要求用戶(hù)應(yīng)用程序與這些硬件設(shè)備進(jìn)行通信,發(fā)送控制命令,讀取狀態(tài)信息等等。Windows NT出于安全性、穩(wěn)定性等考慮,不允許用戶(hù)應(yīng)用程序?qū)ξ锢碛布M(jìn)行直接訪問(wèn),這就需要使用設(shè)備驅(qū)動(dòng)程序跨越操作系統(tǒng)邊界對(duì)物理硬件進(jìn)行操作,并向上提供客戶(hù)應(yīng)用程序控制接口以供調(diào)用。

1 分層結(jié)構(gòu)與設(shè)備驅(qū)動(dòng)程序

Windows NT分層結(jié)構(gòu)(如圖1所示)包括運(yùn)行于用戶(hù)模式及內(nèi)核模式的各種部件,設(shè)備驅(qū)動(dòng)程序在圖1的左下角,處于內(nèi)核模式下I/O管理器之中。

 

2 驅(qū)動(dòng)程序工作方式

內(nèi)核模式驅(qū)動(dòng)程序與應(yīng)用程序之間的最大差別之一是驅(qū)動(dòng)程序的控制結(jié)構(gòu)。內(nèi)核模式驅(qū)動(dòng)程序沒(méi)有main或WinMain,而是由I/O管理器根據(jù)需要調(diào)用一個(gè)驅(qū)動(dòng)程序例程:

· 驅(qū)動(dòng)程序被裝入時(shí);

· 驅(qū)動(dòng)程序被卸出或系統(tǒng)關(guān)閉時(shí);

· 用戶(hù)程序發(fā)出I/O系統(tǒng)服務(wù)調(diào)用時(shí);

· 共享硬件資源對(duì)驅(qū)動(dòng)程序可用時(shí);

· 設(shè)備操作過(guò)程中的任何時(shí)候。

3 初始化過(guò)程

3.1 系統(tǒng)注冊(cè)表中有關(guān)設(shè)備驅(qū)動(dòng)程序的項(xiàng)目是系統(tǒng)加載設(shè)備驅(qū)動(dòng)程序的入口點(diǎn)

系統(tǒng)注冊(cè)表中用于系統(tǒng)加載設(shè)備驅(qū)動(dòng)程序的項(xiàng)目如下:

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesDriverName]

?

″Type″ = dword?00000001

″Start″ = dword?00000002

″Group″ = ″Extended Base″

″ErrorControl″ = dword∶00000001

其中Start含義如下:

SERVICE_BOOT_START (0×0) 操作系統(tǒng)裝入時(shí)

SERVICE_SYSTEM_START (0×01) 操作系統(tǒng)初始化時(shí)

SERVICE_AUTO_START (0×02) 服務(wù)控制管理器啟動(dòng)時(shí)

SERVICE_DEMAND_START (0×03) 服務(wù)控制管理器手工啟動(dòng)

SERVICE_DISABLED ?(0×04) 不啟動(dòng)

Type含義如下:

SERVICE_KERNEL_DRIVER (0×1)

SERVICE_FILE_SYSTEM_DRIVER ?(0×2)

SERVICE_ADAPTER ?(0×4)

系統(tǒng)注冊(cè)表中用于設(shè)備驅(qū)動(dòng)程序加載后讀取的項(xiàng)目如下:

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesDriverNameParameters]

″Parameter1″ = dword∶00000001

″Parameter2″ = dword∶00000004

3.2 加載驅(qū)動(dòng)程序的裝入例程

I/O管理器調(diào)用驅(qū)動(dòng)程序的DriverEntry例程,執(zhí)行初始化。該例程完成:

· 初始化其它例程的入口;

· 創(chuàng)建命名設(shè)備對(duì)象;

· 讀取系統(tǒng)注冊(cè)表中相關(guān)項(xiàng)目并聲明必要的資源;

· 設(shè)置內(nèi)核驅(qū)動(dòng)程序名與Win32子系統(tǒng)名的聯(lián)接;

· 創(chuàng)建或初始化任意驅(qū)動(dòng)程序使用的對(duì)象、類(lèi)型和資源;

· 返回狀態(tài)值。

I/O管理器建立與設(shè)備關(guān)聯(lián)的Driver對(duì)象,并將其傳遞給DriverEntry例程。實(shí)際上Driver對(duì)象基本上是一個(gè)目錄,含有指向各個(gè)驅(qū)動(dòng)程序服務(wù)例程函數(shù)的指針,其結(jié)構(gòu)如表1所示。

表1 Driver對(duì)象域說(shuō)明

I/O管理器能夠找到DriverEntry例程,是因?yàn)樗幸粋€(gè)公認(rèn)的名字,而其他的例程則通過(guò)下列兩種方法查找:

·在Driver對(duì)象中有明確槽的函數(shù)?如DirverObject->DriverUnload;

·在Driver對(duì)象的MajorFunction數(shù)組中——Driver對(duì)象的MajorFunction支持兩種類(lèi)型的功能代碼。一種為標(biāo)準(zhǔn)的功能代碼,如IRP_MJ_CREATE。另一種是用戶(hù)自定義的功能代碼,如IRP_MJ_DEVICE_CONTROL。

所有驅(qū)動(dòng)程序必須支持IRP_MJ_CREATE功能代碼,這是因?yàn)閃in32子系統(tǒng)下的用戶(hù)程序調(diào)用CreateFile函數(shù)創(chuàng)建設(shè)備時(shí),產(chǎn)生該功能代碼。如果不處理這個(gè)功能代碼,Win32程序就不能得到設(shè)備句柄。

用戶(hù)自定義的功能代碼IRP_MJ_DEVICE_CONTROL只有在用戶(hù)模式下的客戶(hù)程序執(zhí)行自定義的功能時(shí)可用。

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)

{

?

//聲明設(shè)備對(duì)象

PDEVICE_OBJECT DeviceObject,

//生成函數(shù)接口指針

DriverObject->MajorFunction[IRP_MJ_CREATE]=XxSelfDispatch;

DriverObject->MajorFunction[IRP_MJ_CLOSE]=

XxSelfDispatch;

DriverObject->MajorFunction[IRP_MJ_READ]=

XxReadDispatch;

DriverObject->MajorFunction[IRP_MJ_WRITE]=

XxWriteDispatch?

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=XxSelfDispatch?

DriverObject->DriverUnload=XxUnload?

//生成Windows NT Executive知道的設(shè)備名

RtlInitUnicodeString(&NtDeviceName,? SelfDeviceName);?

//生成自己的設(shè)備

Status=IoCreateDevice(?

DriverObject,? // Driver對(duì)象

sizeof(SELF_DEVICE_INFO),? // Device對(duì)象

Extension結(jié)構(gòu)大小

&NtDeviceName,

DeviceType,

0,

FALSE,? // 不執(zhí)行

&DeviceObject //Device對(duì)象指針

);

? //生成Win32子系統(tǒng)下的用戶(hù)程序可識(shí)別的設(shè)備名[!--empirenews.page--]

RtlInitUnicodeString(&Win32DeviceName,? SelfWin32Name);

//聯(lián)接內(nèi)部設(shè)備名與Win32子系統(tǒng)下的設(shè)備名

Status = IoCreateSymbolicLink( &Win32DeviceName, &NtDeviceName);

//利用RtlQueryRegistryValues函數(shù)讀出注冊(cè)表中Parameters下的參數(shù)值,初始化自己的硬件

...

?

4 驅(qū)動(dòng)程序服務(wù)例程

驅(qū)動(dòng)程序初始化之后,始終等待發(fā)自用戶(hù)的命令或由其它事件源引起的事件。一旦命令或事件發(fā)生,I/O管理器就調(diào)用相應(yīng)的服務(wù)例程提供服務(wù)。而幾乎所有的I/O都是通過(guò)I/O請(qǐng)求包?IRP驅(qū)動(dòng)的。所謂IRP驅(qū)動(dòng),就是I/O管理器負(fù)責(zé)在非分頁(yè)的系統(tǒng)內(nèi)存中分配一定空間,當(dāng)接受用戶(hù)發(fā)出的命令或由事件引發(fā)后,將工作指令按一定的數(shù)據(jù)結(jié)構(gòu)置于其中,傳遞到驅(qū)動(dòng)程序服務(wù)例程。換言之,IRP包含了驅(qū)動(dòng)程序服務(wù)例程所需要的信息指令。表2、表3為IRP的一些數(shù)據(jù)結(jié)構(gòu)。

同時(shí),I/O管理器和驅(qū)動(dòng)程序都需要在所有時(shí)候知道一個(gè)I/O設(shè)備所進(jìn)行的情況。系統(tǒng)提供Device對(duì)象以滿(mǎn)足此要求。該對(duì)象在DriverEntry例程中生成設(shè)備時(shí)由系統(tǒng)創(chuàng)建后,分配給驅(qū)動(dòng)程序,并在整個(gè)驅(qū)動(dòng)程序生存期內(nèi)有效。當(dāng)I/O管理器調(diào)用驅(qū)動(dòng)程序服務(wù)例程時(shí),傳遞該對(duì)象。表4為Device對(duì)象的外部可見(jiàn)域。

表2 IRP標(biāo)頭中外部可見(jiàn)的域

表3 IRP堆棧單元的一些內(nèi)容

表4 Device 對(duì)象的外部可見(jiàn)域

其中,DeviceExtension域是一個(gè)重要的數(shù)據(jù)結(jié)構(gòu)。它是由I/O管理器創(chuàng)建并自動(dòng)掛接到Device對(duì)象的非分頁(yè)池,是保存驅(qū)動(dòng)程序任意全局變量的最好辦法。因?yàn)镈eviceExtension是驅(qū)動(dòng)程序特定的,要自定義它的數(shù)據(jù)結(jié)構(gòu)。

下面是一個(gè)驅(qū)動(dòng)程序服務(wù)例程利用Device對(duì)象和IRP的片段:

NTSTATUS XxSelfDispatch?(IN PDEVICE_OBJECT pDO? IN PIRP pIrp);?

{

?

PLOCAL_DEVICE_INFO pLDI;

PIO_STACK_LOCATION pIrpStack;?

PULONG pIOBuffer;?

//得到全局信息

pLDI = (PSELF_DEVICE_INFO)pDO->DeviceExtension;?

pIrpStack = IoGetCurrentIrpStackLocation?(pIrp);

?

//得到由用戶(hù)應(yīng)用程序發(fā)來(lái)的用戶(hù)數(shù)據(jù),并在需要時(shí),將結(jié)果通過(guò)此變量返回給用戶(hù)

pIOBuffer=?PULONGpIrp->AssociatedIrp.System

Buffer;?

// 由IRP攜帶的信息決定驅(qū)動(dòng)程序的執(zhí)行

switch (pIrpStack->MajorFunction)

{

case IRP_MJ_CREATE:?

case IRP_MJ_CLOSE:?

Status = STATUS_SUCCESS;?

break;

case IRP_MJ_DEVICE_CONTROL:

//由Parameters進(jìn)一步解釋控制代碼含義

switch ?(pIrpStack->Parameters.DeviceIoControl.IoControlCode)

{

case IOCTL_Function1:?

//執(zhí)行功能代碼

Field1 = pLDI->SelfField1;?

...

break;?

case IOCTL_Function2:?

//執(zhí)行功能代碼

...

break;?

}?

break?

?

// 返回I/O操作的狀態(tài)

pIrp->IoStatus.Status = Status;

IoCompleteRequest(pIrp? IO_NO_INCREMENT); ?

return Status;

?

5 驅(qū)動(dòng)程序終止例程

Unload例程負(fù)責(zé)取消由DriverEntry例程所做的任何事情,包括解除屬于該驅(qū)動(dòng)程序的任何硬件資源的分配,以及刪除屬于驅(qū)動(dòng)程序的任何內(nèi)核對(duì)象。通常這僅在系統(tǒng)關(guān)閉時(shí)需要。

VOID XxUnload(PDRIVER_OBJECT DriverObject)

{

?

PLOCAL_DEVICE_INFO pLDI;

UNICODE_STRING Win32DeviceName;

// 得到全局?jǐn)?shù)據(jù),根據(jù)全局?jǐn)?shù)據(jù)進(jìn)行清理工作

pLDI=?PLOCAL_DEVICE_INFODriverObject->Device

Object->DeviceExtension?

if (pLDI->Field2 == TRUE)

{

...

?

// 刪除分配的設(shè)備名及設(shè)備

RtlInitUnicodeString(&Win32DeviceName, SelfWin32 Name);?

IoDeleteSymbolicLink(&Win32DeviceName);?

IoDeleteDevice(pLDI->DeviceObject);?

?

6 用戶(hù)層應(yīng)用程序與驅(qū)動(dòng)程序間的接口

驅(qū)動(dòng)程序完成后,將在系統(tǒng)重新引導(dǎo)時(shí)裝入并初始化(由DriverEntry例程完成)。此時(shí),驅(qū)動(dòng)程序處于可用狀態(tài),等待用戶(hù)層應(yīng)用程序使用。用戶(hù)層應(yīng)用程序可以:

·打開(kāi)該設(shè)備文件(由IRP_MJ_CREATE功能代碼完成)

·讀出數(shù)據(jù)(由IRP_MJ_READ功能代碼完成)

·寫(xiě)入數(shù)據(jù)(由IRP_MJ_WRITE功能代碼完成)

·執(zhí)行用戶(hù)自定義的功能代碼(由IRP_MJ_DEVICE_CONTROL功能代碼完成)

·關(guān)閉該設(shè)備文件(由IRP_MJ_CLOSE功能代碼完成)

以下是部分實(shí)現(xiàn)代碼:

void main()?

{

HANDLE hndFile; // 由CreateFile得到

union ?{

ULONG LongData;?

USHORT ShortData;?

UCHAR CharData;?

? }DataBuffer;? //從設(shè)備驅(qū)動(dòng)程序中得到的數(shù)據(jù)

LONG IoctlCode;? //功能代碼

ULONG DataLength;?

LONG Parameter1;?

//調(diào)用IRP中的IRP _MJ_CREATE功能

hndFile = CreateFile(?

″\\.\SelfWin32Name″,? // 打開(kāi)設(shè)備文件″ SelfWin32Name″[!--empirenews.page--]

GENERIC_READ | GENERIC_WRITE,?

FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

0,

NULL

if (hndFile == INVALID_HANDLE_VALUE)

{

printf(″Unable to open the device.n″);?

exit(1);

}?

IoctlCode = IOCTL_Function1; //自定義功能代碼

Parameter1 = 1;

DataLength = sizeof(DataBuffer.CharData);?

IoctlResult = DeviceIoControl(

hndFile? //設(shè)備文件句柄

IoctlCode?//功能代碼,對(duì)應(yīng)IRP中的Parameter.

//DeviceIoControl.IoControlCode域

&Parameter1,//傳遞到驅(qū)動(dòng)程序的參數(shù)緩沖區(qū),對(duì)應(yīng)

//IRP中的AssociatedIrp.SystemBuffer

sizeof(Parameter1)? //參數(shù)緩沖區(qū)長(zhǎng)度

&DataBuffer,? //從驅(qū)動(dòng)程序傳出的數(shù)據(jù)緩沖區(qū)

DataLength,? //緩沖區(qū)長(zhǎng)度

&ReturnedLength,? //返回的實(shí)際緩沖區(qū)長(zhǎng)度

NULL //等待,直到操作完成

);

if(!CloseHandle?hndFile)) //關(guān)閉設(shè)備

?

{

printf(″Failed to close device.n″);?

??}

以上介紹了Windows NT4.0設(shè)備驅(qū)動(dòng)程序開(kāi)發(fā)中的一般性過(guò)程。用戶(hù)可利用NT SDK 及DDK開(kāi)發(fā)工具包,并根據(jù)自身需要,對(duì)以上核心代碼進(jìn)行擴(kuò)充完成所需任務(wù)。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶(hù)體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(chē)(EV)作為新能源汽車(chē)的重要代表,正逐漸成為全球汽車(chē)產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車(chē)的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車(chē)的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車(chē) 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車(chē)場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周?chē)娮釉O(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉