微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 高速PCI信号采集卡设计与实现综合实例之:PCI卡的驱动程序设计

高速PCI信号采集卡设计与实现综合实例之:PCI卡的驱动程序设计

时间:06-04 来源:互联网 点击:

息。

在DriverEntry例程中通常要完成如下步骤。

·DriverEntry找到它将要控制的硬件。那个硬件是经过分配的,即被标志为由该驱动程序控制。

·通过声明另一个驱动程序入口点,初始化驱动程序对象。通过把函数指针直接保存到驱动程序对象中完成声明工作。

·如果成功,DriverEntry应该把STATUS_SUCCESS返回给I/O管理程序。

DriverEntry的函数原型为:

NTSTATUSDriverEntry(

PDRIVER_OBJECTpDriverObject,

PUNICODE_STRINGpRegistryPath

)

它接收一个指向它本身的驱动程序对象的指针,DriverEntry例程必须对它(指针)初始化。它还接收一个UNICODE_STRING,它包含注册表中驱动程序服务键的路径。内核模式驱动程序根据该字符串从系统注册表中提取任何驱动程序专有的参数。注册表字符串采用如下形式:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\DriverName

下面是驱动程序的DriverEntry例程的部分代码,里面定义了将要用到的回调函数。

NTSTATUSDriverEntry(

PDRIVER_OBJECTpDriverObject,

PUNICODE_STRINGpRegistryPath

)

{ …

//回调函数

pDriverObject->DriverUnload =DriverUnload;

pDriverObject->MajorFunction[IRP_MJ_CREATE] =Dispatch_Create;

pDriverObject->MajorFunction[IRP_MJ_CLOSE] =Dispatch_Close;

pDriverObject->MajorFunction[IRP_MJ_READ] =Dispatch_Read;

pDriverObject->MajorFunction[IRP_MJ_WRITE] =Dispatch_Write;

pDriverObject->MajorFunction[IRP_MJ_CLEANUP] =Dispatch_Cleanup;

pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]

=Dispatch_IoControl;

pDriverObject->MajorFunction[IRP_MJ_PNP] =Dispatch_Pnp;

pDriverObject->MajorFunction[IRP_MJ_POWER] =Dispatch_Power;

pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL]

=Dispatch_System Control;

pDriverObject->DriverExtension->AddDevice =AddDevice;

returnSTATUS_SUCCESS;

}

2.AddDevice例程

大多数的WDMPDO都是在PnP管理器调用该程序入口点时被创建的。插入新设备后,系统启动时,总线枚举器会发现总线上的所有设备会自动寻找并安装设备的驱动程序,并由驱动程序中的处理PnP功能模块自动处理AddDevice例程及其他的PnP消息。

AddDevice例程使用IoCreateDevice函数创建设备对象,再使用IoCreateSymbolicLink函数将设备组成为一个特定的设备接口,供Win32使用。

其函数原型为:

NTSTATUSAddDevice(PDRIVER_OBJECTpDriverObject,PDEVICE_OBJECTpdo)

必须在DriverEntry入口函数中进行声明,下面是该函数的部分代码:

NTSTATUSAddDevice(

PDRIVER_OBJECTpDriverObject,

PDEVICE_OBJECTpdo

)

{…

//建立设备名称并创建它

for(i=0;i20;i++)

{

//转成String格式

Swprintf(DeviceName,L\\Device\\PLX_DRIVER_NAME_UNICODEL-%d,i);

//初始化DeviceName_Unicode

RtlInitUnicodeString(DeviceName_Unicode,DeviceName);

//创建设备

status=IoCreateDevice(

pDriverObject,

sizeof(DEVICE_EXTENSION),

DeviceName_Unicode,

FILE_DEVICE_UNKNOWN,

0,

FALSE,

fdo

);

//为用户应用程序创建Win32关联名

//转成String格式

swprintf(DeviceLinkName,L\\DosDevices\\PLX_DRIVER_NAME_UNICODEL-%d,i);

//初始化DeviceLinkName_Unicode

RtlInitUnicodeString(

DeviceLinkName_Unicode,

DeviceLinkName

);

//建立设备关联符号

status=IoCreateSymbolicLink(

DeviceLinkName_Unicode,

DeviceName_Unicode

);

returnSTATUS_SUCCESS;

}

3.DispatchPnp例程

支持即插即用主要是指实现一个AddDevice例程和一个IRP_MJ_PNP处理程序。这个PnPIRP有8个主要次功能代码,大多数的WDM驱动程序需要支持这些次功能代码。

·IRP_MN_START_DEVICE。

·IRP_MN_QUERY_REMOVE_DEVICE。

·IRP_MN_REMOVE_DEVICE。

·IRP_MN_CANCLE_REMOVE_DEVICE。

·IRP_MN_STOP_DEVICE。

·IRP_MN_QUERY_STOP_DEVICE。

·IRP_MN_CANCLE_STOP_DEVICE。

·IRP_MN_QUERY_CAPABILITIES。

还有一些不太常用的IRP,这里就不再一一介绍,下面是这部分驱动的部分代码。

NTSTATUSDispatch_Pnp(

PDEVICE_OBJECTfdo,

PIRPpIrp

)

{ …

//检查次功能代码

switch(stack->MinorFunction)

{

caseIRP_MN_START_DEVICE: //配置并初始化设备

status=HandleStartDevice(fdo,pIrp);

break;

caseIRP_MN_STOP_DEVICE: //关闭设备

status=HandleStopDevice(fdo,pIrp);

break;

caseIRP_M

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top