WDF驱动开发-DMA(一)

在 Windows 7 及更早版本上,Kernel-Mode Driver Framework (KMDF) 仅支持 (DMA) 设备的总线-主直接内存访问。 此类设备包含其自己的 DMA 控制器。

在片上系统 (SoC) 上运行Windows 8及更高版本的平台上,该框架还支持系统模式 DMA,其中多个设备共享单个多通道 DMA 控制器。

框架的 DMA 支持包括:

  • 一组框架 DMA 对象和方法,驱动程序使用这些对象和方法将 I/O 请求转换为 DMA 操作;
  • 一组驱动程序提供的事件回调函数,这些函数在发生不同事件时配置设备的 DMA 行为;

框架支持单数据包和 scatter/gather DMA 传输。 它还支持使用通用缓冲区。

在运行 Windows 8 及更高版本的基于 SoC 的平台上,框架支持单数据包系统模式 DMA 传输。

为了在基于框架的驱动程序中处理总线主机和系统模式 DMA 操作,框架提供了三个对象:

  • DMA 启用程序对象框架的 DMA 启用程序对象使驱动程序能够对特定设备使用框架的 DMA 支持。 驱动程序必须为支持 DMA 操作的每个设备创建 DMA 启用程序对象;
  • DMA 任务对象(事务对象)框架的 DMA 任务对象表示单个 DMA I/O 操作。 如果设备使用 DMA 执行请求的操作,基于框架的驱动程序通常会为其接收的每个 I/O 请求创建 DMA 事务对象;
  • 公共缓冲区对象框架的公共缓冲区对象表示计算机内存的一个区域,该区域映射供驱动程序和设备同时访问。 某些驱动程序在为 DMA 设备设置 I/O 操作时 使用通用缓冲区 ;

下面是一些术语的解释: 

DMA 任务(事务):DMA 任务是一个完整的 I/O 操作,例如来自应用程序的单个读取或写入请求;

DMA 传输:DMA 传输是单个硬件操作,用于将数据从计算机内存传输到设备或从设备传输到计算机内存;

单个 DMA 任务始终包含至少一个 DMA 传输,但一个任务可以包含多个传输。

当基于框架的驱动程序收到 I/O 请求时,驱动程序通常会创建一个 DMA 任务对象来表示请求。 当框架开始为任务提供服务时,它会确定设备是否可以在单个传输中处理整个任务。 如果任务太大,框架会将任务分解为多个传输。

在适用于总线主控 DMA 设备的 KMDF 驱动程序中处理 I/O 请求

处理总线主 DMA 设备的 KMDF 驱动程序中的 I/O 请求需要多个驱动程序的事件回调函数中的代码,如下图所示:

如上所示,与 DMA 相关的处理分四个阶段进行:

  1. 驱动程序的 EvtDriverDeviceAdd 或 EvtDevicePrepareHardware 回调函数必须为设备 启用 DMA 事务 ,以便驱动程序可以使用框架的 DMA 功能。 如果设备和驱动程序需要访问共享内存缓冲区,则相同的回调函数还必须 创建一个公共 缓冲区;
  2. 当驱动程序收到需要设备执行 DMA 操作的 I/O 请求时,驱动程序 的请求处理程序 之一必须 创建并初始化新的 DMA 事务。 请注意,如果驱动程序 重用 DMA 事务对象,驱动程序的 EvtDriverDeviceAdd 回调函数可以创建事务对象。然后,请求处理程序必须 启动 DMA 事务 ,以便框架可以根据需要开始将事务分解为较小的 DMA 传输,并调用驱动程序的 EvtProgramDma 回调函数;
  3. 驱动程序的 EvtProgramDma 回调函数针对单个 DMA 传输对 DMA 硬件进行编程 ,并启用设备中断;
  4. 设备中断时,框架会调用驱动程序的 EvtInterruptIsr 回调函数,这将保存易失设备信息并计划驱动程序的 EvtInterruptDpc 回调函数的执行。驱动程序的 EvtInterruptDpc 回调函数在硬件 完成处理后完成每个 DMA 传输 。 DMA 事务的最终传输完成后, EvtInterruptDpc 回调函数 完成 DMA 事务;

驱动程序可能会 重复使用其 DMA 事务对象 ,以确保它们在内存资源不足时可以运行。

驱动程序可以提供一组回调函数,用于处理 特定于 DMA 的电源管理操作。

某些驱动程序使用设备和驱动程序都可以访问的通用缓冲区 。

启用 DMA 事务

如果基于框架的驱动程序处理 DMA 设备的 I/O 操作,则驱动程序必须为每个 DMA 设备启用框架的 DMA 功能。 若要启用这些功能,驱动程序的 EvtDriverDeviceAdd 或 EvtDevicePrepareHardware 回调函数必须:

调用 WdfDeviceSetAlignmentRequirement 以指定设备的缓冲区对齐要求。

调用 WdfDmaEnablerCreate 以指定 DMA 操作的类型 (单个数据包或散点/收集) 以及设备支持的最大传输大小。 从 KMDF 版本 1.11 开始,该框架支持在操作系统的 Windows 8 或更高版本上运行的基于芯片 (SoC) 的系统上的系统模式 DMA。

调用 WdfDmaEnablerSetMaximumScatterGatherElements 以指定设备可在scatter/gather列表中支持的最大元素数,如果设备支持scatter/gather操作。

以下代码示例演示了如何启用框架的 DMA 功能:

WDF_DMA_ENABLER_CONFIG   dmaConfig;WdfDeviceSetAlignmentRequirement( DevExt->Device, PCI9656_DTE_ALIGNMENT_16 );
WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig,WdfDmaProfileScatterGather64Duplex,DevExt->MaximumTransferLength );
status = WdfDmaEnablerCreate( DevExt->Device,&dmaConfig, WDF_NO_OBJECT_ATTRIBUTES,&DevExt->DmaEnabler );

如果驱动程序需要通用缓冲区,驱动程序的 EvtDriverDeviceAdd 回调函数通常会设置它们。 

驱动程序调用 WdfDmaEnablerCreate 后,它可以调用 WdfDmaEnablerWdmGetDmaAdapter 以获取指向框架为设备的输入和输出方向创建的 WDM DMA_ADAPTER 结构的指针。 但是,大多数基于框架的驱动程序不需要访问这些结构。

创建并初始化 DMA 事务

在驱动程序可以将 I/O 请求发送到 DMA 设备之前,驱动程序必须:

  • 调用 WdfDmaTransactionCreate 为请求创建 DMA 事务对象;
  • 调用 WdfDmaTransactionInitializeUsingRequest、 WdfDmaTransactionInitialize 或 WdfDmaTransactionInitializeUsingOffset 来初始化事务对象;

通常,驱动程序会创建 DMA 事务 ,因为 请求处理程序 已收到 框架请求对象 ,并且必须将请求传递给硬件。 在这种情况下,驱动程序应调用 WdfDmaTransactionInitializeUsingRequest,后者接受请求对象句柄作为输入,并从请求对象中提取请求的地址参数。

如果驱动程序必须创建 不 基于驱动程序收到的框架请求对象的 DMA 事务,则驱动程序可以调用 WdfDmaTransactionInitialize 或 WdfDmaTransactionInitializeUsingOffset。 这两种方法都接受驱动程序提供的地址参数。

所有三种初始化方法都需要 EvtProgramDma 事件回调函数的地址作为输入参数。 此回调函数对设备进行程序,并且每次 DMA 传输 可用时,框架都会调用回调函数。

当驱动程序调用 WdfDmaEnablerCreate 来创建 DMA 启用程序对象时,驱动程序将提供包含设备最大传输长度的 WDF_DMA_ENABLER_CONFIG 结构。 框架使用此值作为所有 DMA 传输的默认最大长度。

对于某些类型的 DMA 事务,可能需要指定与设备的默认最大长度不同的最大传输长度。 可以使用 WdfDmaTransactionSetMaximumLength 设置单个事务的最大传输长度。 框架仅在处理指定的事务时使用指定的最大传输长度。

请注意,最大传输长度受操作系统提供给 DMA 启用程序对象的 映射寄存器 数的限制。 若要确定可用的最大传输长度,驱动程序可以调用 WdfDmaEnablerGetFragmentLength。 如果 WdfDmaEnablerGetFragmentLength 返回的值小于驱动程序提供给 WdfDmaEnablerCreate 的最大传输长度,则框架使用较小的值。

在驱动程序创建并初始化 DMA 事务后,驱动程序必须 启动该事务。

启动 DMA 事务

在驱动程序 创建并初始化 DMA 事务后,驱动程序可以调用 WdfDmaTransactionExecute 方法来启动该事务。 此方法为与事务关联的第一个 DMA 传输 生成散点/收集列表。 接下来, 方法调用驱动程序为事务注册的 EvtProgramDma 回调函数。 回调函数 对 DMA 硬件进行程序 以启动传输。

在驱动程序调用 WdfDmaTransactionExecute 之前,驱动程序必须存储 DMA 事务句柄,以便在驱动程序完成与事务关联的每个 DMA 传输时可以检索该句柄。 存储事务句柄的一个好位置是在框架对象的上下文内存中,通常是设备的框架设备对象。 

以下代码演示如何初始化并执行 DMA 事务:

VOID PLxEvtIoRead(IN WDFQUEUE         Queue,IN WDFREQUEST       Request,IN size_t           Length)
{NTSTATUS            status = STATUS_UNSUCCESSFUL;PDEVICE_EXTENSION   devExt;// Get the DevExt from the queue handledevExt = PLxGetDeviceContext(WdfIoQueueGetDevice(Queue));do {// Validate the Length parameter.if (Length > PCI9656_SRAM_SIZE)  {status = STATUS_INVALID_BUFFER_SIZE;break;}// Initialize the DmaTransaction.status = WdfDmaTransactionInitializeUsingRequest(devExt->ReadDmaTransaction,Request, PLxEvtProgramReadDma, WdfDmaDirectionReadFromDevice );if(!NT_SUCCESS(status)) {. . . //Error-handling code omittedbreak; }// Execute this DmaTransaction.status = WdfDmaTransactionExecute( devExt->ReadDmaTransaction, WDF_NO_CONTEXT);if(!NT_SUCCESS(status)) {. . . //Error-handling code omittedbreak; }// Indicate that the DMA transaction started successfully.// The DPC routine will complete the request when the DMA// transaction is complete.status = STATUS_SUCCESS;} while (0);// If there are errors, clean up and complete the request.if (!NT_SUCCESS(status )) {WdfDmaTransactionRelease(devExt->ReadDmaTransaction); WdfRequestComplete(Request, status);}return;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/32071.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频讲解|基于模型预测算法的含储能微网双层能量管理模型【mpc】

1 主要内容 该讲解视频对应的免费程序链接为【防骗贴】基于模型预测算法的含储能微网双层能量管理模型,主要做的是一个微网双层优化调度模型,微网聚合单元包括风电、光伏、储能以及超级电容器,在微网的运行成本层面考虑了电池的退化成本&…

快捷方式(lnk)--加载HTA-CS上线

免责声明:本文仅做技术交流与学习... 目录 CS: HTA文档 文件托管 借助mshta.exe突破 本地生成lnk快捷方式: 非系统图标路径不同问题: 关于lnk的上线问题: CS: HTA文档 配置监听器 有效载荷---->HTA文档--->选择监听器--->选择powershell模式----> 默认生成一…

政务大厅引导系统:AR、VR技术革新引领政务服务体验升级

一、传统政务大厅面临的普遍痛点 随着城市的发展和政务服务需求的增长,传统的政务大厅面临着诸多挑战和痛点: 信息不对称:政务大厅内各部门信息分散,群众难以快速获取全面准确的服务信息,导致办事效率低下。 办事流…

计算机视觉 | 基于图像处理和边缘检测算法的黄豆计数实验

目录 一、实验原理二、实验步骤1. 图像读取与预处理2. 边缘检测3. 轮廓检测4. 标记轮廓序号 三、实验结果 Hi,大家好,我是半亩花海。 本实验旨在利用 Python 和 OpenCV 库,通过图像处理和边缘检测算法实现黄豆图像的自动识别和计数&#xff0…

JetBrains GoLand 2024 mac/win版:高效开发,Go无止境

JetBrains GoLand 2024是一款专为Go语言开发者设计的集成开发环境(IDE),为开发者带来了更加高效、智能和便捷的编程体验。 GoLand 2024 mac/win版获取 在代码编辑方面,GoLand 2024提供了全行代码补全功能,通过利用先进的深度学习模型&#x…

力扣85.最大矩形

力扣85.最大矩形 遍历所有行作为底边 做求矩形面积&#xff08;84. class Solution {public:int maximalRectangle(vector<vector<char>>& matrix) {if (matrix.empty()) return 0;int n matrix.size(),m matrix[0].size();int res0;vector<int> li…

适耳贴合的气传导耳机,带来智能生活体验,塞那Z50耳夹耳机上手

现在大家几乎每天都会用到各种AI产品&#xff0c;蓝牙耳机也是我们必不可少的装备&#xff0c;最近我发现一款很好用的分体式气传导蓝牙耳机&#xff0c;它还带有一个具备AI功能的APP端&#xff0c;大大方便了我们日常的使用。这款sanag塞那Z50耳夹耳机我用过一段时间以后&…

开发指南033-数据库兼容

元芳&#xff0c;你怎么看&#xff1f; 单一数据库自身就有一些不同处理之处&#xff0c;如果一个平台要兼容所有数据库&#xff0c;就是难上加难&#xff0c;像isnull函数各数据库就不同。 对于这类问题&#xff0c;平台采用统一自定义函数解决&#xff0c;例如上面的round函…

模式分解的概念(下)-无损连接分解的与保持函数依赖分解的定义和判断、损失分解

一、无损连接分解 1、定义 2、检验一个分解是否是无损连接分解的算法 输入与输出 输入&#xff1a; 关系模式R&#xff08;U&#xff0c;F&#xff09;&#xff0c;F是最小函数依赖集 R上的一个分解 输出&#xff1a; 判断分解是否为无损连接分解 &#xff08;1&#x…

JAVA同城服务场馆门店预约系统支持H5小程序APP源码

&#x1f4f1;一键预约&#xff0c;畅享无忧体验&#x1f3e2; &#x1f680;一、开启预约新纪元 在繁忙的都市生活中&#xff0c;我们常常因为时间紧张而错过心仪的门店或场馆服务。然而&#xff0c;有了“门店场馆预约小程序”&#xff0c;这些问题都将迎刃而解。这款小程序…

群辉NAS中文件下载的三种方案

目录 一、迅雷套件 1、添加套件来源 2、安装套件 3、手机安装迅雷 二、qBittorrent套件 1、添加套件来源 2、改手工安装 3、更新后的问题 4、最后放弃DSM6 (1)上传文件手工安装 (2)添加套件来源 5、解决登陆报错 6、添加tracker 7、修改下载默认位置 8、手机…

c++之说_15|成员函数的const尾缀修饰 ( const const)

我记得我刚接触c的时候 遇到成员函数 右边尾部 写了个const 我当时就很蒙 不过慢慢的也从大佬口中获得一二经验了 class kj{public:void get(){printf("无修饰\n");}void get()const{printf("const 修饰\n");}}; 大概就是这个样子 当时我抓耳挠腮的看…

【yolov8语义分割】跑通:下载yolov8+预测图片+预测视频

1、下载yolov8到autodl上 git clone https://github.com/ultralytics/ultralytics 下载到Yolov8文件夹下面 另外&#xff1a;现在yolov8支持像包一样导入&#xff0c;pip install就可以 2、yolov8 语义分割文档 看官方文档&#xff1a;主页 -Ultralytics YOLO 文档 还能切…

图扑助力铝型材挤压:数字孪生引领智慧管理

通过图扑数字孪生技术&#xff0c;为铝型材挤压车间提供实时监控和优化管理方案。高精度三维建模和数据可视化提升了生产效率和管理透明度&#xff0c;推动智能制造和资源优化配置。

leetcode 二分查找·系统掌握 寻找旋转排序数组中的最小值II

题目&#xff1a; 题解&#xff1a; 本题比普通的寻找旋转排序数组中的最小值多了一个数组中的元素可以重复这一点。 这会时原来的思路出现一个漏洞&#xff08;大家感兴趣可以看看我做普通版寻找旋转排序数组最小值的思路&#xff09;&#xff0c;就是旋转后的数组中的第二个…

cas客户端流程详解(源码解析)--单点登录

博主之前一直使用了cas客户端进行用户的单点登录操作&#xff0c;决定进行源码分析来看cas的整个流程&#xff0c;以便以后出现了问题还不知道是什么原因导致的 cas主要的形式就是通过过滤器的形式来实现的&#xff0c;来&#xff0c;贴上示例配置&#xff1a; 1 <list…

Spring-bean

Spring 网站&#xff1a;spring.io 两个方面&#xff1a; 简化开发&#xff1a; IoCAOP 框架整合&#xff1a; MyBatis SpringFrameWork系统架构&#xff08;上层依赖下层&#xff09; 解决问题&#xff08;代码耦合度高——模块与模块之间的依赖程度&#xff09; 目标&am…

Pikachu靶场--越权漏洞

参考借鉴 pikachu之越权漏洞_pikachu越权漏洞-CSDN博客 水平越权 需要输入username和password进行登录 查看提示&#xff0c;获取username和password 输入其中一组账号信息进行登录 可以查看到个人信息 在URL中更改username的值-->回车 成功越权&#xff0c;登录到其他账号…

【文献及模型、制图分享】1985-2015年美国坦帕湾流域土地开发利用强度时空变化分析

公众号新功能 目前公众号新增以下等功能 1、处理GIS出图、Python制图、区位图、土地利用现状图、土地利用动态度和重心迁移图等等 2、核密度分析、网络od分析、地形分析、空间分析等等 3、地理加权回归、地理探测器、生态环境质量指数、地理加权回归模型影响因素分析、计算…

[极客大挑战 2020]Roamphp2-Myblog

又来喽 经过一番测试&#xff0c;发现文件包含&#xff0c;使用伪协议读取文件 例&#xff1a;php://filter/readconvert.base64-encode/resourcelogin //这里我只写php部分 //login.php <?php require_once("secret.php"); mt_srand($secret_seed); $_SESSION…