WDK分配大的DMA空间_wind_新浪博客

需求:需要分配约1GB的空间,设备通过系统DMA(设备没有DMA控制器,故采用Slave DMA)写入此空间中。运行环境:Win7 x64

方案一: 通过DirectIO方式,使用Scatter/Gatter方式、调用 ​WdfDmaTransactionInitializeUsingRequest进行分配。

问题:分配的多个分页中,有部分指定的地址不再内存范围内,在硬盘上。 偶发部分地址不能写入。  通过屏蔽这样的地址可以解决此问题,但会浪费一些地址段,且大小不可控。​

在32位系统上,分配的是​0-4G范围内的值,但在x64不能应用此设置,会导致混乱。

由于考虑到避免应用程序对驱动的影响,考虑在驱动加载时,分配指定的空间,这样即使应用程序异常关闭,也不影响设备的读写。

测试一: ​在EvtDevicePrepareHardware函数中,使用WdfCommonBufferCreate进行分配。 测试结果:分配不能超出30M,测试2M可以。

​测试二: ​在EvtDevicePrepareHardware函数中,使用WdfDmaEnablerWdmGetDmaAdapter进行分配。 测试结果:分配1M,蓝屏;1GB,提示分配失败。

测试三: ​在EvtDevicePrepareHardware函数中,使用WdfMemoryCreate或ExAllocatePoolWithTag进行分配。 测试结果:​可以分配1GB数据,但部分分页在硬盘上。 另外使用ExAllocatePoolWithTag,在台式机上,分配在硬盘上的概率很小,但在另外一台工控机上,竟然大部分都在硬盘上。

测试四: ​在EvtDevicePrepareHardware函数中,使用MmAllocateContiguousMemory进行分配。 测试结果:​分配约400MB,蓝屏。有朋友测试过30MB可以。

​测试五: ​在EvtDevicePrepareHardware函数中,使用MmAllocatePagesForMdl进行分配,并指定其分配范围。

 

PHYSICAL_ADDRESS LowAddress;

PHYSICAL_ADDRESS HighAddress;       

PHYSICAL_ADDRESS SkipAddress;       

LowAddress.QuadPart = 0;       

HighAddress.QuadPart = 0x00000001ffffffffI64;   //8G以内        SkipAddress.QuadPart = 0;       

pDeviceContext->Mdl = MmAllocatePagesForMdl(LowAddress,            HighAddress,  SkipAddress,  MAXNLEN  );

测试结果:均分配在指定范围内,默认从最大内存值向前依次分配。很方便的满足了DMA传输要求。

另外,如果需要连续的地址段,可以使用MmAllocatePagesForMdlEx​方法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值