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

所有支持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不必进行处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值