PCI设备内存操作函数总结

本文涉及的产品
简介: <p>1.  <strong>ExAllocatePool</strong>()</p> <p>函数说明:</p> <p align="left"><strong>ExAllocatePool</strong> allocates pool memory of the specified type and returns a pointer to the allocated</p>

1.  ExAllocatePool()

函数说明:

ExAllocatePool allocates pool memory of the specified type and returns a pointer to the allocated

block.

函数定义:

PVOID ExAllocatePool(

                            __in  POOL_TYPE PoolType,

                            __in  SIZE_T NumberOfBytes

);

代码中用来分配设备描述DMA adepter设备的特性(DEVICE_DESCRIPTION),作为参数传递给IoGetDmaAdapter()函数。在调用IoGetDmaAdapter()函数之前就要对PDEVICE_DESCRIPTION结构进行指定各种特性。

         实际中这样使用:

                   PDEVICE_DESCRIPTION DeviceDescription = (PDEVICE_DESCRIPTION) ExAllocatePool

(PagedPool, sizeof(DEVICE_DESCRIPTION));

 

 

2. RtlZeroMemory()

         函数说明:

The RtlZeroMemory routine fills a block of memory with zeros, given a pointer to the block and the length, in bytes, to be filled.

         函数定义:

                  VOID RtlZeroMemory(

                         __in  VOID UNALIGNED *Destination,

                         __in  SIZE_T Length

);

 

 

3. IoGetDmaAdapter()

         函数说明:

The IoGetDmaAdapter routine returns a pointer to the DMA adapter structure for a physical device object.

函数定义:

struct _DMA_ADAPTER* IoGetDmaAdapter(

  __in_opt  PDEVICE_OBJECT PhysicalDeviceObject,

  __in      struct _DEVICE_DESCRIPTION *DeviceDescription,

  __out     PULONG NumberOfMapRegisters

);

实际代码中这样使用:

ULONG  NumberOfMapRegisters=100;

pdx->DmaAdapter=IoGetDmaAdapter(pdx->NextStackDevice,DeviceDescription,&NumberOfMapRegisters);// NextStackDevice在AddDevice函数中已经attach了。

 

 

4. AllocateCommonBuffer()

         函数说明:

The AllocateCommonBuffer routine allocates memory and maps it so that it is simultaneously accessible from both the processor and a device for DMA operations。

函数定义:

PVOID AllocateCommonBuffer(

  __in   PDMA_ADAPTER DmaAdapter,

  __in   ULONG Length,

  __out  PPHYSICAL_ADDRESS LogicalAddress,

  __in   BOOLEAN CacheEnabled

);

注:第一个参数是IoGetDmaAdapter()返回的,第三个参数是自己顶一顶一个物理地址类型,用来接收分配得到的物理地址首址。

返回值:返回值为虚拟地址,供上层使用

 

实际代码中这样使用:

pdx->descAddress=pdx->allocateCommonBuffer(pdx->DmaAdapter,(ULONG)DESC_ADDRESS*PORT_NUM,&pdx->DescLogicalAddress,FALSE);

 

附:使用该函数必不可少的会使用下面的函数

pdx->DmaAdapter=IoGetDmaAdapter(pdx->NextStackDevice,DeviceDescription,&NumberOfMapRegisters);

//创建一个DMA适配器

pdx->allocateCommonBuffer=*pdx->DmaAdapter->DmaOperations->AllocateCommonBuffer; 

//分配连续的物理内存DMA函数

pdx->freeCommonBuffer = *pdx->DmaAdapter->DmaOperations->FreeCommonBuffer;

//释放连续的物理内存DMA函数

pdx->putDmaAdapter=*pdx->DmaAdapter->DmaOperations->PutDmaAdapter;      

//释放DMA Adapter对象

 

 

当通过AllocateCommonBuffer()分配得到地址之后需要把这个地址分成两部分来处理,与硬件打交道的需要用LogicAddress 与 应用程序打交道需用 Virtual Address.

最好将AllocateCommonBuffer()函数取得的这两个地址保存到设备扩展中特定的变量中(根据内存块的用处),便于以后操作。可以这样做:

pdx->RxDescVirBase=(PCHAR)pdx->descAddress;

pdx->RxDescPhyBase=(ULONG)(pdx->DescLogicalAddress.LowPart); //物理地址

 

WRITE_REGISTER_ULONG( (PULONG)&pdx->pHBARegs->RxAddr_des_0,pdx->rx_fc_des

c_buf_phy[0]+16);

WRITE_REGISTER_ULONG( (PULONG)&pdx->pHBARegs->RxAddr_des_addr0_ptr,pdx->r

x_fc_desc_buf_phy[0]+4);

                   注意前面的 +16 和 +4 实际分别代表美一块内存的的偏移位置,由于我们定义了这块内存的结构,并在里面布局,+16 其实代表了struct rx_fc_ctl_tab 结构中的 struct rx_fc_desc_entity entity[RX_FC_DESC_NUM] 域,这里又是一个结构,也就是我们最终会用到的“描述符”。注意:我们这里的操作是将一个地址写到一个寄存器,这个地址必须是物理地址,也就是前面说的LogicAddress。这里pHBARegs是通过pdx->pHBARegs=(PHBA_REGS)pdx->RegsBase;     获得的,也就是在CmResourceTypeMemory传过来时解析,代表硬件提供的DMA寄存器首址。

 

 

 

对于硬件的初始化就是通过WRITE_REGISTER_ULONG()函数来完成,针对设备的起始地址来进行偏移,自己定义结构来匹配各个寄存器的内容,注意这个自己定义的结构一定要严格跟硬件寄存器相同,一bit都不能差。

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
14天前
|
程序员 C语言
C语言库函数 — 内存函数(含模拟实现内存函数)
C语言库函数 — 内存函数(含模拟实现内存函数)
24 0
|
25天前
|
编译器 C语言 C++
【C语言】memset()函数(内存块初始化函数)
【C语言】memset()函数(内存块初始化函数)
26 0
|
25天前
|
编译器 C语言 C++
【C语言】memcpy()函数(内存块拷贝函数)
【C语言】memcpy()函数(内存块拷贝函数)
42 0
|
1月前
|
C语言
模拟实现C语言中经典库函数,字符相关的函数与内存相关的函数
模拟实现C语言中经典库函数,字符相关的函数与内存相关的函数
模拟实现C语言中经典库函数,字符相关的函数与内存相关的函数
|
1月前
|
算法 C语言
C语言中的内存函数你知道多少呢?
C语言中的内存函数你知道多少呢?
|
1月前
|
编译器 C语言
【C语言】动态内存函数介绍
【C语言】动态内存函数介绍
|
1月前
|
C语言
C语言里面的内存函数
C语言里面的内存函数
15 0
|
1月前
|
C语言
c语言内存函数的深度解析
c语言内存函数的深度解析
32 3
|
2天前
|
编译器 C语言
字符串与内存函数
字符串与内存函数
18 0

热门文章

最新文章