您尚未登录。

楼主 #1 2020-04-24 12:41:37

ntmusic
会员
注册时间: 2020-02-24
已发帖子: 43
积分: 33

关于F1C100s的DMA使用

这段时间断断续续在搞F1C100s的ADC音频采集,使用FIFO中断的方法采集数据没问题(这里有一个小坑,FIFO中断中读数据时,我用结构体地址指向的方式将Rx寄存器的值读出,发现不管读几次都只能读出FIFO最后一个值,按理说每读一次Rx应该就从FIFO中取下一个数据才对。后来实在没法子,用了Read32()函数,就可以了。。。。),但使用DMA传输就不行了,DMA缓冲区的数据一大部分压根不变化。啃了好几遍手册,各个Channel都试了,仍不行。一开始以为又进了读FIFO之类的坑,但最后排查来排查去,问题应该是Cache的问题。
    我是在RTT BSP中开发,在board.c对MMU的初始化函数中可以看到,32M的DDR是全部Cacheble的,RTT内存管理当然也是Cacheble,目标缓存是rt_malloc出来的,在DMA结束后,CPU操作这些缓存数据时使用的还是Cache中的数据,导致一致性问题。尝试了一下,在rt_hw_mmu_init中直接将mmu_enable_dcache()屏蔽掉后,编译运行一切正常。。
    当然关掉dcache是不实际的,但我不知道什么指令能使Cache和内存同步,mmu.c中的mmu_clean_invalidated_dcache()函数和mmu_clean_dcache()函数等好像也不起作用,于是换一种方式,在mmu_init函数的mem_desc表中,添加一部分DDR地址为“RW_NCNB”,把DMA传输的目标地址指向这个区域,就没问题了。

离线

楼主 #4 2020-04-24 16:18:35

ntmusic
会员
注册时间: 2020-02-24
已发帖子: 43
积分: 33

Re: 关于F1C100s的DMA使用

armstrong 说:

对cache的使用知识,是裸机开发ARM9必备啊。你可以从我的rtx+emwin包里,找到mmu_c.c和mmu_a.s,我把所有mmu操作的api都放在里边了。你这个情况,只要调用我的MMU_InvalidateDCacheArray函数,使dma访问过的ram对应的cache无效就行了。注意,“无效”和“清理”是两个截然不同的概念。

谢谢指点,对arm9刚接触很多都还不熟悉,尤其是底层方面,还得向各位大牛学习!

离线

楼主 #8 2020-04-24 22:37:48

ntmusic
会员
注册时间: 2020-02-24
已发帖子: 43
积分: 33

Re: 关于F1C100s的DMA使用

armstrong 说:

cpu把数据写到内存,然后交给外设或dma,要用clean;
cpu读取由外设或dma放在ram的数据之前,要invalid;
dcacheinvalid和dcacheclean指令,要么是针对mva的,要么是针对cache-line的,要么就整个dcache
所以MMU_InvalidateDCacheArray函数封装了mva的遍历。
对ram变量也有cache-line对齐的要求,即变量或数组的大小和地址必须32字节对齐,否则会破坏变量。

感谢您的热心指导,受益匪浅!实测使用mmu_invalidate_dcache是正确的,之前测试不起作用是粗心了没有设置对DMA的目的地址,犯了低级错误

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn