windriver下的WDC_DMAContigBufLock函数和WDC_DMASGBufLock函数的区别

来源:互联网 发布:如何编写软件测试报告 编辑:程序博客网 时间:2024/06/04 18:31

对于DMA内存的分配主要有俩种,但是不管如何目的是找到。(对于什么是dma就没必要解释了)

      一般来说我们在底层分配分配一块大的内存的(所谓底层是指物理地址,而不是通过操作系统的页式管理的虚拟地址),由于Dma的底层传输的实现是基于系统总线的物理地址。所以我们需要再传输之前发送物理地址,而且dma的传输过程是没有cpu的参与,基于dma控制器(当然,这里其实是不绝对的(也就是说dma控制器的配置不绝对),好多fpga自己写的dma控制器)dma的底层物理地址应该是连续的,最起码是dma块内是连续的,通过快速的自增实现快速的索引传输。

问题也就来了,物理底层的连续似乎是没那么容易保证的,保证个4k一般来说是非常容易的,因为这就是物理的页框,但是太大的往往不能确定的分配到,所以解决这类问题的方法一般是俩种,一种是对于大的文件传输,我既然无法分配到大的连续内存,那么我们干脆小内存多次调用传输,显然这种效率比较低,另一种解决方案是我们分配多个这种小的物理内存块,然后通过一个二层协议(我喜欢这么称呼)也就是在传输的数据中我们再增加一个格式(方便我们再获取了一个块的基础上再获取另一个块的地址)而这种传输的方式
其实就是链式dma传输。对于 Altera公司的fpga提供的demo一般就是链式dma传输,设置了各种字段属性后,和多个描述符(本质是多个块地址和大小)就可以快速的进行dma传输。而这种使用了多个块的方法在windriver里面叫分散聚合dma传输。这里要辨析的就是windriver下的俩个分配物理内存的函数,当然我们的数据操作一定是基于应用层的,所以这俩个函数的本质就是,提供应用层的地址,实现底层和物理地址的绑定,同时返回物理地址,此后我们就可以操作应用层的地址,实现底层特定地址的数据操作。

  WDC_D MAContigBufLock()


Purpose

• Allocates a contiguous DMA buffer, locks it in physical memory, and returns mappings of the allocated buffer to physical address space and to user-mode and kernel virtual address spaces.

Prototype
DWORD DLLCALLCONV WDC_DMAContigBufLock(    WDC_DEVICE_HANDLE hDev,    PVOID *ppBuf,    DWORD dwOptions,    DWORD dwDMABufSize,    WD_DMA **ppDma);
Parameters
NameTypeInput/OutputhDevWDC_DEVICE_HANDLEInputppBufPVOID*OutputdwOptionsDWORDInputdwDMABufSizeDWORDInputppDmaWD_DMA**Output

 WDC_DMASGBufLock()

Purpose

• Locks a pre-allocated user-mode memory buffer for DMA and returns the corresponding physical mappings of the locked DMA pages. On Windows 7/Vista/Server 2008/Server 2003/XP/2000 the function also returns a kernel-mode mapping of the buffer.

Prototype
DWORD DLLCALLCONV WDC_DMASGBufLock(    WDC_DEVICE_HANDLE hDev,    PVOID pBuf,    DWORD dwOptions,    DWORD dwDMABufSize,    WD_DMA **ppDma);
Parameters
NameTypeInput/OutputhDevWDC_DEVICE_HANDLEInputpBufPVOIDInputdwOptionsDWORDInputdwDMABufSizeDWORDInputppDmaWD_DMA**Output

这俩个函数一个是连续的底层物理内存的分配,一个是离散聚合的方式分配,虽然底层是离散的,但是该函数的应用层映射的地址是连续的
方便操作。

其实也没什么难度,一个传一级指针,一个传二级指针,传一个一级指针有什么用,没什么乱用,仅仅是把地址告诉了底层。
底层无法改变指向,只能是绑定该地址映射,所以我们需要再应用层分配连续的空间,然后将首地址下传。
而传二级指针的好处是改变指向,所以传二级指针的时候,意味着你的指向修改,也就是改函数不仅仅是分配了底层的物理空间,连应用层的
连续空间也分配好了。