在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 5724|回复: 10

[讨论] 请教大侠 Altera的 chaining DMA速率问题

[复制链接]
发表于 2016-8-17 15:26:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
使用的altera PCIE 的官方例程链式chaining DMA  ,底层约束一个链表上的描述符最大为256个,在上位机开发驱动层用的是winDriver,为每个描述符对应的数据分配内存时只能分配一个内存的页,就是4KB,这样的话,每次发起一次链式DMA,能传的数据最大是256*4KB = 1MB,这样的话太小了,如果要传多一点的数据,就要发起很多次DMA。发起DMA这个过程是由上位机做的,需要先准备链表,再写DMA控制寄存器来启动。这样效率真的很低。
不知道是我哪里理解错了,还是由其他的工作方法。还请用过这个例程的大牛指点指点。

上层开发不是我做的,我看了部分winDriver的API,再准备链表这个阶段,用的是WDC_DMASGbufLock这个函数,好像是一个描述符只能锁定一个4KB的页,不知道这是不是可以实现的更大。

如果大牛做过xilinx的链式DMA的应用,请指点一下在描述符和每一个描述符对应的数据亮是什么情况。谢谢嘞
发表于 2016-8-17 19:15:13 | 显示全部楼层
1.为什么只能分4K?我看手册理没有看到有说明啊,我以前是用WD_DMALock这个底层函数。
2.就算只分4K,如果是离散DMA,效率仍然很高。CPU写内存的速度是很恐怖的,慢的是访问PCIE设备。如果将这些描述符往PCIE设备写,就太浪费CPU时间了。你可以开辟多个Buffer,然后分成2组,两组乒乓地操作,一组DMA进行时CPU处理空闲组的列表。这样性能没什么下降。
3.计算机申请内存不要搞得太大
 楼主| 发表于 2016-8-19 17:01:28 | 显示全部楼层
回复 2# cdsmakc

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,不知道我们是不是一样的。
发表于 2016-8-22 13:35:13 | 显示全部楼层
回复 3# nothing92


   2. BUFFER申请一次就可以,不释放,两组链表存在内存中,每次发起DMA只要向PCIE设备写启动寄存器就可以了,所以申请内存不是问题。3. 1M必须在物理地址上连续。软件看到的是虚拟地址。PCIE DMA设备看到的是物理地址。比如说是用malloc申请一块1M内存,很大概率不是物理地址连续的。你想,PCIE DMA就从PC那里的链表获得一个首地址,假设这块空间不连续,那不是会写错?另外,你申请256M,这个太大了,哪怕是服务器插128G内存这个也太大了。我觉得最大就不要超过1M就好了。小几百K就好了。
 楼主| 发表于 2016-8-22 16:26:13 | 显示全部楼层
回复 4# cdsmakc


  那我的实现肯定是有问题了,用windriver没法获取物理地址连续的1MB,最大只能获取物理地址连续的4KB。
发表于 2016-8-22 18:23:15 | 显示全部楼层
回复 5# nothing92


  我刚才看了下windriver的手册,WDC_DMASGbufLock这个函数,貌似是将你申请的buffer挂载为一个DMA buffer,是这样吗?
发表于 2016-8-22 18:50:39 | 显示全部楼层
回复 5# nothing92


   刚才看了下代码,我觉得你应该用WDC_DMACONTIGBUFLOCK这个函数。用它返回给你的内存。
 楼主| 发表于 2016-8-23 14:14:05 | 显示全部楼层
回复 6# cdsmakc


   手册是这样说的,Locks a pre-allocated user-mode memory buffer for DMA and returns the corresponding physicalmappings of the locked DMA page。是你说的意思。
 楼主| 发表于 2016-8-23 14:17:05 | 显示全部楼层
本帖最后由 nothing92 于 2016-8-23 14:26 编辑

回复 7# cdsmakc

回去再试试吧,具体的需要是这样的:
现在需要一次分配256块空间(一个链有256个描述符,一个描述符对应一块),每块大小在4KB到256KB之内,这256块之间的物理地址不必连续,但每一块内部的地址是连续的。这样一次链式DMA可以最多传输64MB。只要能实现30M就很满足了。


-------------
   现在我们已经尝试在底层开发了,等有结果我再来回复。谢谢。
发表于 2016-8-24 08:20:20 | 显示全部楼层
回复 9# nothing92


   我觉得你想的太复杂了,我原来搞的时候,FPGA和WINDRIVER都是我一个人写的,FPGA一共才3500文本行代码,WINDRIVER貌似连1000行都不到。实在不行就用LOW LEVEL API,里面同样可以分配内存。没必要非得自己分配内存。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /3 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-19 11:28 , Processed in 0.034438 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表