请教大侠 Altera的 chaining DMA速率问题
不知道是我哪里理解错了,还是由其他的工作方法。还请用过这个例程的大牛指点指点。
上层开发不是我做的,我看了部分winDriver的API,再准备链表这个阶段,用的是WDC_DMASGbufLock这个函数,好像是一个描述符只能锁定一个4KB的页,不知道这是不是可以实现的更大。
如果大牛做过xilinx的链式DMA的应用,请指点一下在描述符和每一个描述符对应的数据亮是什么情况。谢谢嘞
1.为什么只能分4K?我看手册理没有看到有说明啊,我以前是用WD_DMALock这个底层函数。
2.就算只分4K,如果是离散DMA,效率仍然很高。CPU写内存的速度是很恐怖的,慢的是访问PCIE设备。如果将这些描述符往PCIE设备写,就太浪费CPU时间了。你可以开辟多个Buffer,然后分成2组,两组乒乓地操作,一组DMA进行时CPU处理空闲组的列表。这样性能没什么下降。
3.计算机申请内存不要搞得太大
1、WDC_DMASGbufLock这个函数锁定的最大的连续物理空间貌似是一个页表(
内存的page),就是4KB.,也不知到是不是用的方式不对。
2 、你说的对,可以在pc端这里做乒乓。这个描述符表是pcie设备通过存储器读
从pc读来的,不是pc主动写的。每次pc先要准备描述符,期间就用到了
WDC_DMASGbufLock这个函数进行内存锁定,准备完描述符,然后写PCIe设备的DMA
控制寄存器启动DMA,然后就是开始说的,PCIE设备自己读描述符进行DMA操作。
3,我分配了256MB,不知道会太大,电脑2G内存。这256MB是常驻内存吗?
我看了你在另一个帖子的回复:“我怎么记得我做WINDRIVER最大划过1M的空间?划的时候必须设置为物理地址也连续。虚拟地址连续物理地址未必连续。如果物理地址不连续,DMA就错了”
请问这个1M是连续的1M吗?还是所有的离散片段加起来1M?
我现在实现的就是每个连续的片段是4K,一共256个片段,加起来1MB,不知道我们是不是一样的。
2. BUFFER申请一次就可以,不释放,两组链表存在内存中,每次发起DMA只要向PCIE设备写启动寄存器就可以了,所以申请内存不是问题。3. 1M必须在物理地址上连续。软件看到的是虚拟地址。PCIE DMA设备看到的是物理地址。比如说是用malloc申请一块1M内存,很大概率不是物理地址连续的。你想,PCIE DMA就从PC那里的链表获得一个首地址,假设这块空间不连续,那不是会写错?另外,你申请256M,这个太大了,哪怕是服务器插128G内存这个也太大了。我觉得最大就不要超过1M就好了。小几百K就好了。
那我的实现肯定是有问题了,用windriver没法获取物理地址连续的1MB,最大只能获取物理地址连续的4KB。
我刚才看了下windriver的手册,WDC_DMASGbufLock这个函数,貌似是将你申请的buffer挂载为一个DMA buffer,是这样吗?
刚才看了下代码,我觉得你应该用WDC_DMACONTIGBUFLOCK这个函数。用它返回给你的内存。
手册是这样说的,Locks a pre-allocated user-mode memory buffer for DMA and returns the corresponding physicalmappings of the locked DMA page。是你说的意思。
回去再试试吧,具体的需要是这样的:
现在需要一次分配256块空间(一个链有256个描述符,一个描述符对应一块),每块大小在4KB到256KB之内,这256块之间的物理地址不必连续,但每一块内部的地址是连续的。这样一次链式DMA可以最多传输64MB。只要能实现30M就很满足了。
-------------
现在我们已经尝试在底层开发了,等有结果我再来回复。谢谢。
我觉得你想的太复杂了,我原来搞的时候,FPGA和WINDRIVER都是我一个人写的,FPGA一共才3500文本行代码,WINDRIVER貌似连1000行都不到。实在不行就用LOW LEVEL API,里面同样可以分配内存。没必要非得自己分配内存。
