驱动程序(5) WDF下DMA传输的驱动程序代码详细说明之device.c

本文深入探讨了在device.c中如何枚举设备,分配和映射PCIe设备的内存资源(BARs),并详细阐述了中断资源的配置,特别是针对MSI中断的问题。代码示例展示了如何使用WDF进行硬件准备和释放,以及自定义中断处理流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一篇文章说明了在device.c文件里,驱动程序怎样枚举设备,然后获得设备资源,并将其显示出来供开发者使用。

device.c

/*++
Module Name: device.c - Device handling events for example driver.
Abstract: This file contains the device entry points and callbacks, sucn as EvtDevicePrepareHardware and EvtDeviceReleaseHardware function.
Environment: Kernel-mode Driver Framework
Time: 20181015
--*/

#include "driver.h"
//#pragma warning(disable:4013)
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, PCIe_EvtDevicePrepareHardware)
#pragma alloc_text(PAGE, PCIe_EvtDeviceReleaseHardware)
#endif

NTSTATUS
PCIe_EvtDevicePrepareHardware(
	IN WDFDEVICE Device,
	IN WDFCMRESLIST ResourceList,
	IN WDFCMRESLIST ResourceListTranslated
)
{
   
   
	ULONG i;
	PDEVICE_CONTEXT pDeviceContext;             //设备上下文结构体的句柄
	PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor; //设备资源描述符
	PINTERRUPT_CONTEXT pInterruptContext;    //中断上下文结构体的句柄
	NTSTATUS status;
	PAGED_CODE();

 	KdPrintEx((DPFLTR_IHVAUDIO_ID, DPFLTR_ERROR_LEVEL, "Function 'PCIe_EvtDevicePrepareHardware' begins\n"));
	pDeviceContext = GetDeviceContext(Device);
	pDeviceContext->MemBaseAddress0 = NULL;
	pDeviceContext->MemBaseAddress1 = NULL;
	pDeviceContext->MemBaseAddress2 = NULL;

	pDeviceContext->Counter_i = 0;

	for (i = 0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++) {
   
   
		
		KdPrintEx((DPFLTR_IHVAUDIO_ID, DPFLTR_ERROR_LEVEL, "i is %0d\n", i));
		//获取到设备资源描述符
		descriptor = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);
		if (!descriptor) {
   
   
			return STATUS_DEVICE_CONFIGURATION_ERROR;
		}
		
		//根据不同类型,将设备资源描述符转化为开发者可用的类型,这里主要用到了memory和interrupt两种资源
		switch (descriptor->Type) 
		{
   
   
		case CmResourceTypeMemory:
			if (i == 0) {
   
   
				//获取到设备存储资源的物理地址
				pDeviceContext->PhysicalAddressRegister0 = descriptor->u.Memory.Start.LowPart;
				//获取到设备存储资源在系统内核模式下的虚拟地址(后续对于寄存器的访问也将用到这个地址)
				pDeviceContext->MemBaseAddress0 = MmMapIoSpace(
					descriptor->u.Memory.Start,
					descriptor->u.Memory.Length,
					MmNonCached);
				if (!pDeviceContext->MemBaseAddress0) {
   
   
					return<
### 回答1: Windows设备驱动程序(WDF)开发是指使用Windows Driver Framework(WDF)来编写和开发驱动程序的过程。WDF是一种微软提供的驱动程序开发框架,旨在简化设备驱动程序的编写过程并提供更高的可靠性和安全性。 首先,要进行WDF开发,我们需要安装Windows Driver Kit(WDK)。WDK是一个开发环境,它提供了用于开发和调试Windows驱动程序的工具和组件。安装好WDK后,我们就可以开始编写WDF驱动程序了。 编写WDF驱动程序的过程主要分为以下几个步骤。 1. 创建驱动程序项目:使用WDK提供的模板、向导或命令行工具来创建一个新的驱动程序项目。这个项目将包含编写驱动程序所需的源代码文件。 2. 定义设备接口:在驱动程序中,我们需要定义设备接口,用于与操作系统和应用程序进行通信。这个接口定义了设备驱动程序的功能和特性。 3. 实现设备驱动程序:在驱动程序中,我们需要实现设备驱动程序的各个功能模块,如设备初始化、资源管理、设备驱动程序的各种操作和处理等。 4. 建立设备和驱动程序之间的通信:在驱动程序中,我们需要使用WDF提供的机制来进行设备和驱动程序之间的通信。这可以是通过使用WDF提供的回调函数、DMA传输、中断处理等。 5. 调试和测试:在开发过程中,我们需要使用WDK提供的调试工具和测试工具来验证驱动程序的正确性和稳定性。这可以帮助我们找到和修复潜在的问题。 总的来说,Windows设备驱动程序(WDF)开发需要使用WDK来创建项目、定义接口、编写和实现驱动程序,并使用WDF提供的机制来进行通信。通过使用WDK提供的调试和测试工具,我们可以确保驱动程序的正确性和可靠性。 ### 回答2: Windows设备驱动程序框架(Windows Driver Framework,简称WDF)是微软为Windows操作系统开发的一种设备驱动程序开发框架。WDF旨在简化设备驱动程序的开发过程,使开发人员能够更快速、高效地开发稳定、可靠的驱动程序WDF提供了两种开发模型:基于内核模式的驱动程序(Kernel-Mode Driver)和用户模式驱动程序(User-Mode Driver)。其中,内核模式驱动程序运行在操作系统内核空间,可以访问系统资源和硬件设备;而用户模式驱动程序运行在用户空间,它通过系统接口与内核空间的驱动程序通信。 WDF开发中的关键概念是设备对象(Device Object),每个设备都由一个设备对象表示。WDF提供了简化的设备对象模型,使开发人员可以更轻松地创建、初始化和管理设备对象。 在WDF开发中,开发人员可以利用WDF框架提供的丰富的API集合来管理设备驱动程序的生命周期、处理设备事件和资源分配等。WDF还提供了一系列的内存管理函数和错误处理机制,帮助开发人员提高驱动程序的稳定性和可靠性。 此外,WDF还支持树形结构设备对象模型,可以方便地处理具有多层次结构的设备。开发人员可以利用WDF框架提供的函数来构建设备层次结构、查询和操作设备。 总之,WDF是一种用于简化Windows设备驱动程序开发的开发框架。通过使用WDF,开发人员可以更快速、高效地开发稳定、可靠的驱动程序,从而提高系统的性能和可维护性。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值