调试经验--davinci特性

时间:2021-03-02 08:46:02


调试经验--davinci特性


    每一个硬件平台,都有别的平台所没有的特性。
   这里,我把我调试dm6446过程中遇到的平台特性相关问题总结了一下:

   1,硬件resize的使用;2,davinci的地址分析;3,共享内存CMEM的使用。


一,6446的resize调试:

   6446的dvsdk中有两个例程,一个是视频环路loop,一个是编解码encodedecode,而我需要一个结合了dsp调用的视频环路程序,所以,将两个例程进行了整合。

   整合之后,DSP端算法程序运行不起来。

   首先简化,将dsp算法简化为空,可以执行。然后逐步添加功能模块,经过多次测试后发现,竟然是硬件resize的问题!

   跟踪查看应用程序,发现ARM端的smooth与resize,其实与DSP端的硬件resize用的是同一个硬件。

   在arm端已经使用了硬件resize,然后在dsp端又使用了硬件resize,两边的配置不一致,根本问题可能是两个核(arm与dsp)同时访问了同一个硬件

(硬件resize),从而导致异常了。

   在dsp端改用for循环实现resize,程序就可以正常运行了。

   反过来,去掉arm端的resize配置,而dsp启用硬件resize,程序也能运行,但是发现图像抖动加大,效果不好,未采用。

   最终方案:改为在arm端resize,dsp端直接使用缩放后的图像。这样,既保证了只有一个核访问硬件resize,同时又兼顾了运行效率。

   由于smooth并没有改变图像的大小,尝试使用memcpy代替resize。
   在ARM端操作时:注意物理地址与虚拟地址的区别。
   resize的buf地址参数,使用物理地址;
   memcpy的buf地址参数,使用虚拟地址。
   替换之后也能正常运行。但是考虑到smooth对图像有处理平滑的效果,最终没有替换。

   目前arm端使用了3次resize,1,capture,2,video中reduce,3,display 。
   需要避免配置的冲突:在capture,display,video中都要先配置后执行。

   尝试规范化resize的配置函数Rszcopy_config_reduce():
   统一到一个函数后,运行发现图像颜色异常(都使用缩小的过滤参数)。
   结论:不同比例的resize,使用的过滤参数也不同,不能简单统一到一个函数中。

   6446对标清图像进行硬件resize的执行,每次耗时约6-7ms,运行时resize的调用线程阻塞,此时resize是由硬件执行的,而ARM转移给其他线程。对比使用for循环实现的软件resize,可以观察到ARM占用率明显下降。
 

二,davinci的地址分析:
 arm端的应用程序,使用虚拟地址;
 dsp端算法,使用物理地址。
 arm给dsp传递参数时,若是指针,必须使用物理地址。
  使用codec engine进行缓冲传递时,dsplink会有一个地址的转换,编程时不用考虑差异。
 在arm端应用程序中,若直接使用物理地址,赋值给指针,会导致系统异常。
 

三,共享内存CMEM的使用

   对于共享内存CMEM的使用,需要非常的注意。首先,其总大小是有限的,一般分配为8M。对于视频处理的算法,总是需要传递整帧的图像进行处理,如果还要有多缓冲以进行并行的处理,很可能共享内存就不够用了。其次,共享内存使用容易出错,必须有相应的保护。我们的经验是:
(1) 尽早的提取图像中的有用信息,以在后续的传递过程中减小内存的使用;
(2) 较多的使用控制标志,以达到一块内存区域实现多种使用功能的效果。
(3) 需要严格的将输入变量与输出变量分离,在ARM端将意义相同的变量值统一。
(4) 需要特别注意的是,必须将公共变量进行保护,在某一个时刻只允许ARM或DSP中的一个来进行访问。

共享内存分配函数示例:
buf = (char *)Memory_contigAlloc(bufSize, 128);
取物理地址示例:
physaddr = Memory_getBufferPhysicalAddress((char *)buf,4,NULL);

关联头文件:
#include "/root/dvsdk_3_10_00_19/codec_engine_2_25_05_16/packages/ti/sdo/ce/osal/Memory.h"

需要开辟连续内存,获取物理地址,都与cmem相关,需要工具链的支持。 不能使用arm-gcc单独编译,需要使用dvsdk中的xdc。