诚心请教一个关于PCI使用DMA的问题

splendidhp 2012-09-25 05:20:15
最近在做一个powerpc+fpga架构的项目,采用PCI总线进行数据传输,在调试驱动的时候遇到了这样的现象,在PCI的probe()之中对PCI的内存空间可以进行ioread,iowrite的操作,数据都正确(这段空间是fifo,读写都不用加偏移),为了提高速率所以添加了DMA,将PCI的内存空间作为源地址,malloc一段空间作为目的地址,计数器设一个定值,设置工作模式后启动DMA,DMA工作完成后读取目的地址的内存查看数据,结果为全0,即并没有将源地址的数据映射过去,在映射过程中读取DMA的状态寄存器可知道DMA确实启动了,工作模式的配置上也做出了多种尝试最后均未能调通。
求有经验的人能给我些指点,还有哪些手段可以用来定位这个问题,跟DMA映射流程相关的寄存器就那么几个,不知道还有什么办法可以来对这个问题进行调试,另外,有没有办法来排除硬件本身的问题?fifo的空间是否支持DMA映射功能?求指教,谢谢
...全文
427 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
guolh 2013-09-10
  • 打赏
  • 举报
回复
我的信箱:guolh@163.com QQ:10789220
guolh 2013-09-09
  • 打赏
  • 举报
回复
楼主好,不知道楼主的问题解决了没有?我使用的环境和楼主的相同,问题也一样,搞了好久,DMA就是不正确,请多多指点,谢谢!
curious_cat 2012-09-29
  • 打赏
  • 举报
回复
malloc 分配的地址为虚拟地址,是不能直接作为DMA的目标地址或源地址的;
虚拟地址需要进行转换为物理地址,才能作为DMA的目标地址;用户使用的内存空间为分页内存,所以转换为物理地址后,其地址范围为一系列不超过4KB(LINUX内存分页为4KB)的内存块,需要把这一系列物理内存的起始地址/长度信息设置到DMA控制器里面。 这种DMA方式叫scatter-gather DMA,由于过程复杂,其驱动程序开发起来也有点复杂.

还有一种方式是在内核中分配物理连续的内存(windows 系列里面叫common buffer), 这种方式不涉及分页内存问题,DMA控制器需要设置的参数就少多了;但是应用程序访问的时候,需要将该内存映射到用户空间,用户的应用程序才能访问。
splendidhp 2012-09-27
  • 打赏
  • 举报
回复
我使用的是linux2.6.35的内核,之前设备用的localbus,DMA功能正常,后来换成了PCI调DMA就出了这个问题
地址转换这里确实有些问题,我用virt_to_bus和bus_to_virt对fpga和kmalloc的地址进行检查
fifo的实地址和虚地址分别使用上面两个接口转换出来的地址对不上
kmalloc出来的可以对应上
我觉得你说的地址转换过程出错很有道理,我再试试看,谢谢
byeyear 2012-09-25
  • 打赏
  • 举报
回复
不知道你用的是什么操作系统
如果操作系统允许的话
专门保留一段内存用于DMA测试
不要用malloc分配的内存
linux可以通过启动参数实现(好像是mem=)
例如你的内存是256M
留出顶端16M给DMA
剩余240M给操作系统
将这16M内存的物理基地址作为DMA起始地址

倾向于怀疑将malloc分配得到的地址转换为物理地址的过程出错

21,599

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧