您好,我们使用DM6437做处理器,TVP5146作为视频采集VPFE,软件采用10位AD输入YUV422视频(UYVY),8层PCB版图。
使用winXP环境,CCS3.3,DVSDK_1_11开发包。在example里的preview基础上做修改。做视频图像增强,软件已基本完工,但软件中只要加入了DMA数据搬运过程就会导致死机。
所谓是死机即不再能采集到摄像头输入的新视频数据,而是在原来buffer中的图片数据反复循环,数据不再被刷新,而程序还能正常跳转。如果不使用DMA则一切正常。所以怀疑是VPFE采集图像的DMA与我们自写程序中的DMA产生了冲突。我们使用的DMA函数为例程自带DMA函数,DATA_COPY。
DMA版本是EDMA3_LLD_01_10
求问这个问题如何解决?
John zeng:
使用DMA时应该锁定DMA,使用完再释放就不会冲突了
Cash King:
回复 John zeng:
初学者不太了解,该如何实现DMA锁定呢?比如在开发包框架上应该调用哪些函数。现在DMA只用到了DATA_COPY函数,并在库函数内部DMA搬运结束之后添加了中断标志函数,还没有用到其他DMA相关函数,也不知道VPFE进行时DMA内部是如何实现的。求指教!
Shane Huang1:
回复 Cash King:
先用memcpy代替DMA试试会不会导致死机。
TI的PSP里面提供了信号量,在使用DMA前先锁住DMA
Cash King:
回复 Shane Huang1:
用memcpy是不会出现死机状态的,视频输入输出处理完全正常,就是速度很慢;是用DMA的时候,正常运行了一小会,VPFE就没有数据进来了,buffer区域只有原来存储的数据,没有更新。
除了VPFE和VPBE外,现程序里只启动了一个DMA用于搬运数据。所以不知道先锁住哪一个DMA,怎么锁(锁住了VPFE的DMA不是没有数据进来了么)?VPFE内部的DMA又该如何修改?
信号量的控制是指用edma3osSemTake、edma3osSemGive这些函数做处理吗?那该怎么使用呢?能不能说的详细点,没太明白,谢谢~
Shane Huang1:
回复 Cash King:
您的意思是5146那边也没有数据过来了?如果只是DMA死了,VPFE应该是还能收到5146过来的数据的。
VPFE内部的DMA是不需要我们去操作的。建议您先把后面图像处理的代码去掉,先调试DMA,看看能不能搬到指定的地方,按照DMA例程写应该不会有问题的。
Cash King:
回复 Shane Huang1:
当时试过,就是不使用DMA就完全没有问题,速度慢了而言;使用DMA,不做图像处理,使用for循环令输入移位后等于输出(10位转8位),也会死掉,不过时间会长一点比如20分钟以后,5146那边就不再有数据传过来了;如果做图像处理,那么死得更快,超不过5秒钟。但是在卡死之前,DMA搬运没有问题,即查看CCS的memory地址,能把数据搬到指定位置的。
Shane Huang1:
回复 Cash King:
还是先单独调DMA吧。检查下代码有没有分配的内存没有释放。
Cash King:
回复 Shane Huang1:
刚刚又单独调DMA,还是同样的问题。即DMA读完再写,令输入等于输出,显示视频,程序运行,DMA能正常搬运数据到内存和DDR,显示屏显示正常视频。
然后不管它,运行了大约二十分钟,就出现了视频卡死,在缓存的几帧图像中转换的问题;程序不死机,还能设断点,单步执行等等;只是VPFE已经没有新的视频数据输入到DDR中了,所以我们感觉是VPFE死掉了,但不知道怎么设置。
但正如前述,使用memcpy代替DMA则一个小时以来VPFE都没有死掉,现在还能显示视频(不使用DMA方法)
Cash King:
回复 Shane Huang1:
另外在每次DMA使用DATA_COPY之前,我们使用BCACHE_wbInv(写之前)或BCACHE_inv(读之前),不知道算不算所说的对DMA内存的释放?
至于其他不存在内存泄露的问题吧,数组这些大多是局部变量,跳出函数即释放,而全局变量和视频帧存要直到关机才能从DDR视频缓存真正释放吧,程序运行中是反复使用的。
所以代码应该没有分配的内存没有释放的情况吧。
Shane Huang1:
回复 Cash King:
判断VPFE是否死掉,可以看有没有VD中断。理论上DMA 是不会导致VPFE死掉的。