您的位置:首页 > 其它

chapter 6.7: KMDF设备对象的创建和初始化

2013-03-05 22:27 417 查看
所有支持PnP的KMDF驱动不许有EvtDriverDeviceAdd回调函数。用于创建和初始化device对象和相关资源。

系统在发现驱动控制的一个设备时会调用它的EvtDriverDeviceAdd。

EvtDriverDeviceAdd创建了一个WDFDEVICE对象,用来表示设备和通过大量初始化任务让framework提供信息来创建它自己的内部结构。

EvtDriverDeviceAdd过程:

1.把消息填充到一个device initialization structure

2.创建device对象的context area

3.创建设备对象

4.启动tasks,例如创建I/O queue和device interface

bus driver启动的过程:参见chapter 6.3的Bus drivers

KMDF的device initialization structure

device object没有configuration structure,而是通过WDFDEVICE_INIT结构。

framework调用EvtDriverDeviceAdd,同时传一个指向WDFDEVICE_INT的指针,然后调用WdfDeviceInitXxx方法填充该结构。最后在创建WDFDEVICE对象时使用这些信息。

WdfDeviceInitXxx:

1.设置device characteristics

2.设置I/O类型

3.创建context area或给I/O请求设置其他的参数

4.注册PnP和power mgr回调函数

5.注册event回调函数(file create,close,cleanup)

对不同的对象还有其他不同的初始化任务。

KMDF FDO的初始化

WdfDeviceInitSetPowerPolicyEventCallbacks来注册关于idle in low-power state和wake signal的回调函数。

EvtDeviceFilterRemoveResourceRequirements和EvtDeviceFilterAddResourceRequirements callbacks增加移除来自于bus driver的resource requirements list资源。

用WdfFdoInitSetEventCallbacks来注册他们

EvtDeviceRemoveAddedResources?

其他WdfFdoInitXxx方法获得device属性、返回指向设备栈中的WDM PDO指针、提供注册表访问、及其他FDO任务

KMDF Filter DO的初始化

WdfFdoInitSetFilter来表示设备是一个filter,来使framework改变其对I/O request默认配置(不处理的请求自动传给下一个驱动)

可以像FDO一样调用WdfDeviceInitXxx方法

设备对象的context area

见第五章,nonpaged pool,driver-defined layout。。。

Osrusbfx2.h例子:

typedef struct _DEVICE_CONTEXT {
WDFUSBDEVICE                    UsbDevice;
WDFUSBINTERFACE                 UsbInterface;
WDFUSBPIPE                      BulkReadPipe;
WDFUSBPIPE                      BulkWritePipe;
WDFUSBPIPE                      InterruptPipe;
UCHAR                           CurrentSwitchState;
WDFQUEUE                        InterrputMsgQueue;
} DEVICE_CONTEXT, *PDEVICE_CONTEXT;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext)

如图,

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME宏定义了type

所以当EvtDriverDeviceAdd回调被调用时,GetDeviceContext访问方法可以用DEVICE_CONTEXT来读写context area

要把设备对象关联到named context area上,driver必须在EvtDriverDeviceAdd中调用WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE来通过这些信息初始化attributes structure。

KMDF设备对象的创建

在driver调用WdfDeviceInitXxx来填充WDFDEVICE_INT结构后,它在attributes structure中设置参数。

参数包括context area的大小和类型,通常包含cleanup callback和同步范围。

driver把attributes structure和WDFDEVICE_INT传给WdfDeviceCreate来创建WDFDEVICE对象,增加到PnP设备栈中,返回handle

EvtDriverDeviceAdd的更多任务

1.若设备持有power policy时,需要设置deivce idle policy,wake配置

2.注册I/O回调,为设备对象创建I/O queue

3.按需要调用WdfDeviceCreateDeviceInterface创建device interface

4.若硬件支持中断,创建一个中断对象

5.创建WMI对象

在之后的启动设备过程中,在合适的时间初始化queue,连接interrupt对象。

KMDF的

EvtDriverDeviceAdd回调函数例子

Osrusbfx2的例子

NTSTATUS OsrFxEvtDeviceAdd(
IN WDFDRIVER        Driver,
IN PWDFDEVICE_INIT  DeviceInit
)
{
WDF_PNPPOWER_EVENT_CALLBACKS        pnpPowerCallbacks;

WDF_OBJECT_ATTRIBUTES               attributes;
NTSTATUS                            status;
WDFDEVICE                           device;
WDF_DEVICE_PNP_CAPABILITIES         pnpCaps;
UNREFERENCED_PARAMETER(Driver);
PAGED_CODE();
// Initialize the pnpPowerCallbacks structure.
. . .// Code omitted.
//[1] Register Plug and Play and power callbacks
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
//[2] Indicate what type of I/O this driver performs.
WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
//[3] Intialize the object attributes structure
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
//[4] Call the framework to create the device object.
status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
if (!NT_SUCCESS(status)) {
return status;
}
// Set device PnP capabilities and configure and create I/O queues.
. . .// Code omitted.
//[5] Register a device interface.
status = WdfDeviceCreateDeviceInterface(device,
&GUID_DEVINTERFACE_OSRUSBFX2,
NULL);// Reference String
if (!NT_SUCCESS(status)) {
return status;
}
return status;
}

EvtDriverDeviceAdd函数处理

1.注册PnP和Power回调
WdfDeviceInitSetPnpPowerEventCallbacks在WDFDEVICE_INIT structure中记录PnP和电源信息
2.设置I/O类型
WdfDeviceIoBuffered,即为默认
3.初始化对象的attributes structure
驱动用context area的类型初始化attributes structure,从而驱动能为设备监理context area
4.创建device对象
WdfDeviceCreate,参数为WDFDEVICE_INIT和object attributes structures
5.创建device interface
WdfDeviceCreateInterface,参数是device对象的指针,GUID指针(在Public.h中得以),可选引用string的指针
驱动通过“引用string”在相同的interface类中区分设备,就是说他们都有不同的GUID。这个例子传了NULL
framework会自动启用和禁用device interface,所以在大多数情况下,driver不必进行处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: