Windows驱动中的中断

          


 我们都知道,中断对于Windows驱动的重要性。MSFT推荐对于对硬件的操作都采用中断的方式,我们都知道,中断是一种资源,所以需要配置,申请。一般来说,我们都是在ACPI中配置中断资源。而在驱动中,在WDM时代,我们需要调用IoConnectInterrupt函数,此函数定义如下:

              

NTSTATUS
  IoConnectInterrupt(
    OUT PKINTERRUPT  *InterruptObject,
    IN PKSERVICE_ROUTINE  ServiceRoutine,
    IN PVOID  ServiceContext,
    IN PKSPIN_LOCK  SpinLock  OPTIONAL,
    IN ULONG  Vector,
    IN KIRQL  Irql,
    IN KIRQL  SynchronizeIrql,
    IN KINTERRUPT_MODE    InterruptMode,
    IN BOOLEAN  ShareVector,
    IN KAFFINITY  ProcessorEnableMask,
    IN BOOLEAN  FloatingSave
    );

         索性,把MSDN的参数说明也贴出来,因为,我觉得这个函数非常重要。

       

Parameters

InterruptObject
Pointer to the address of driver-supplied storage for a pointer to a set of interrupt objects. This pointer must be passed in subsequent calls to
KeSynchronizeExecution.
ServiceRoutine
Pointer to the entry point for the driver-supplied InterruptService routine.
ServiceContext
Pointer to the driver-determined context that will be supplied to the InterruptService routine when it is called.
The ServiceContext area must be in resident memory: in the device extension of a driver-created device object,
in the controller extension of a driver-created controller object, or in nonpaged pool allocated by the device driver.
See Providing ISR Context Information for details.

SpinLock
Pointer to an initialized spin lock, for which the driver supplies the storage, that will be used to synchronize access to
driver-determined data shared by other driver routines. This parameter is required if the ISR handles more than one vector or
if the driver has more than one ISR. Otherwise, the driver need not allocate storage for an interrupt spin lock and the input pointer is NULL.

Vector
Specifies the interrupt vector passed in the interrupt resource at the u.Interrupt.Vector member of CM_PARTIAL_RESOURCE_DESCRIPTOR.

Irql
Specifies the DIRQL passed in the interrupt resource at the u.Interrupt.Level member of CM_PARTIAL_RESOURCE_DESCRIPTOR.
SynchronizeIrql
Specifies the DIRQL at which the ISR will run. If the ISR handles more than one interrupt vector or the driver has more than one ISR,
this value must be the highest of the Irql values passed at u.Interrupt.Level in each interrupt resource. Otherwise,
the Irql and SynchronizeIrql values are identical.

InterruptMode
Specifies whether the device interrupt is LevelSensitive or Latched.

ShareVector
Specifies whether the interrupt vector is sharable.
ProcessorEnableMask
Specifies a KAFFINITY value representing the set of processors on which device interrupts can occur in this platform.
This value is passed in the interrupt resource at u.Interrupt.Affinity.

FloatingSave
Specifies whether to save the floating-point stack when the driver's device interrupts. For x86-based and IA64-based platforms,
this value must be set to FALSE. For more information about saving floating point and MMX state, see Using Floating Point or MMX in a WDM Driver.

Return Value
IoConnectInterrupt can return one of the following NTSTATUS values:

STATUS_SUCCESS
STATUS_INVALID_PARAMETER
STATUS_INSUFFICIENT_RESOURCES

Comments
New drivers should use the IoConnectInterruptEx routine, which is easier to use. Drivers for devices
that support message-signaled interrupts (MSI) must use IoConnectInterruptEx.

A PnP driver should call IoConnectInterrupt as part of device start-up, before it completes the PnP IRP_MN_START_DEVICE request.

When a driver receives an IRP_MN_START_DEVICE request, the driver receives raw and translated hardware resources in the Parameters.StartDevice.AllocatedResources and Parameters.StartDevice.AllocatedResourcesTranslated members of the IRP's IO_STACK_LOCATION structure, respectively. To connect its interrupt, the driver uses the resources at AllocatedResourcesTranslated.List.PartialResourceList.PartialDescriptors[]. The driver must scan the array of partial descriptors for resources of type CmResourceTypeInterrupt.

If the driver supplies the storage for the SpinLock, it must call KeInitializeSpinLock before passing its interrupt spin lock to IoConnectInterrupt.

On return from a successful call to IoConnectInterrupt, the caller's ISR can be called if interrupts are enabled on the driver's device or
if ShareVector was set to TRUE. Drivers must not enable interrupts until after IoConnectInterrupt returns.

Callers of IoConnectInterrupt must be running at IRQL = PASSIVE_LEVEL.


               我们再来看WDF中的函数,WdfInterrtupCreate:

              

NTSTATUS
  WdfInterruptCreate(
    IN WDFDEVICE  Device,
    IN PWDF_INTERRUPT_CONFIG  Configuration,
    IN OPTIONAL PWDF_OBJECT_ATTRIBUTES  Attributes,
    OUT WDFINTERRUPT*  Interrupt
    );


              我们看到在这个函数,有设备对象,但是在WDM中,IoConnectInterrupt是没有这个参数,所以,我们调用这个函数的时候,是在EvtDeviceAdd函数里,

一般是在创建设备对象以后。而IoConnectInterrupt函数,一般是在处理IRP_MN_START_DEVICE的函数里,其实也就是得到资源的函数里。上面MSDN的解释了这些。

            我们再来看下WDF_INTERRUPT_CONFIG这个结构体:

           

typedef struct _WDF_INTERRUPT_CONFIG {
  ULONG  Size;
  WDFSPINLOCK  SpinLock;
  WDF_TRI_STATE  ShareVector;
  BOOLEAN  FloatingSave;
  BOOLEAN  AutomaticSerialization;
  PFN_WDF_INTERRUPT_ISR  EvtInterruptIsr;
  PFN_WDF_INTERRUPT_DPC  EvtInterruptDpc;
  PFN_WDF_INTERRUPT_ENABLE  EvtInterruptEnable;
  PFN_WDF_INTERRUPT_DISABLE  EvtInterruptDisable;
} WDF_INTERRUPT_CONFIG, *PWDF_INTERRUPT_CONFIG;


      这里也把MSDN中的解释贴出来,这些参数,我们看到,我们可以控制硬件设备中断产生前的动作,因为我们可以设备EvtInterrtupEnable函数,一般来说,EvtDeviceD0Entry后,会调用这个使能函数。

    

Members

Size
The size, in bytes, of this structure.
 
SpinLock
The handle to a framework spin-lock object, obtained by a previous call to WdfSpinLockCreate, or NULL.
If this parameter is NULL, the framework uses an internal spin-lock object. The framework acquires the
spin lock before it calls the driver's EvtInterruptSynchronize event callback function and when the driver calls WdfInterruptAcquireLock.

ShareVector
A WDF_TRI_STATE-typed value. If this value is WdfTrue, the interrupt vector can be shared.
If the value is WdfFalse, the interrupt vector cannot be shared. If the value is WdfDefault,
the PnP manager uses the bus driver's value.

FloatingSave
A Boolean value that, if TRUE, indicates that the system will save the processor's floating point and MMX state when the device interrupts.
If FALSE, the system does not save the floating point and MMX state. A driver should set this value to TRUE only if
its EvtInterruptIsr callback function must use floating point or MMX registers.
For more information about saving floating point and MMX state, see Using Floating Point or MMX in a WDM Driver.

AutomaticSerialization
A Boolean value that, if TRUE, indicates that the framework will synchronize execution of the interrupt object's
EvtInterruptDpc callback function with callback functions from other objects that are underneath the interrupt's parent device object.
For more information, see the following Comments section.

EvtInterruptIsr
A pointer to the driver's EvtInterruptIsr callback function. This pointer cannot be NULL.

EvtInterruptDpc
A pointer to the driver's EvtInterruptDpc callback function, or NULL.

EvtInterruptEnable
A pointer to the driver's EvtInterruptEnable callback function, or NULL.

EvtInterruptDisable
A pointer to the driver's EvtInterruptDisable callback function, or NULL.

Headers
Declared in Wdfinterrupt.h. Include Wdf.h.

Comments
The WDF_INTERRUPT_CONFIG structure is available in version 1.0 and later versions of KMDF.

The WDF_INTERRUPT_CONFIG structure is used as input to WdfInterruptCreate.

To initialize a WDF_INTERRUPT_CONFIG structure, your driver should first call WDF_INTERRUPT_CONFIG_INIT
and then fill in structure members that WDF_INTERRUPT_CONFIG_INIT does not initialize.

Setting AutomaticSerialization to TRUE has no effect if the parent device object's synchronization scope is set to
WdfSynchronizationScopeNone.

Setting AutomaticSerialization to TRUE causes WdfInterruptCreate to fail if the parent device object's execution level is set to
WdfExecutionLevelPassive.

For more information about AutomaticSerialization and synchronizing driver callback functions, see Synchronization Techniques for
Framework-Based Drivers.

For more information about handling interrupts in framework-based drivers, see Handling Hardware Interrupts.

 

 

 

再来看下WDF_OBJECT_ATTRIBUTES:

    

typedef struct _WDF_OBJECT_ATTRIBUTES {
  ULONG  Size;
  PFN_WDF_OBJECT_CONTEXT_CLEANUP  EvtCleanupCallback;
  PFN_WDF_OBJECT_CONTEXT_DESTROY  EvtDestroyCallback;
  WDF_EXECUTION_LEVEL  ExecutionLevel;
  WDF_SYNCHRONIZATION_SCOPE  SynchronizationScope;
  WDFOBJECT  ParentObject;
  size_t  ContextSizeOverride;
  PCWDF_OBJECT_CONTEXT_TYPE_INFO  ContextTypeInfo;
} WDF_OBJECT_ATTRIBUTES, *PWDF_OBJECT_ATTRIBUTES;

 

          我们重点看一下,WDF_EXECUTION_LEVEL,这里我们可以设备PASSIVER或者Displatch.

         下面来贴一个MSDN例子:

          NTSTATUS  status;
         WDF_INTERRUPT_CONFIG  interruptConfig;
          WDF_OBJECT_ATTRIBUTES  interruptAttributes;

          WDF_INTERRUPT_CONFIG_INIT(
                          &interruptConfig,
                          MyEvtInterruptIsr,
                          MyEvtInterruptDpc
                          );
         WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
                                        &interruptAttributes,
                                        INTERRUPT_DATA
                                        );
          status = WdfInterruptCreate(
                            device,
                            &interruptConfig,
                            &interruptAttributes,
                            &devExt->WdfInterrupt
                            );

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值