Davinci 开发中的灵异事件Word文档下载推荐.docx
- 文档编号:6623938
- 上传时间:2023-05-07
- 格式:DOCX
- 页数:12
- 大小:68.27KB
Davinci 开发中的灵异事件Word文档下载推荐.docx
《Davinci 开发中的灵异事件Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Davinci 开发中的灵异事件Word文档下载推荐.docx(12页珍藏版)》请在冰点文库上搜索。
#endif
#ifdefined(BIG_ENDIAN)////Big-Endianmachine
#defineBIG_B2D(B,D)D=*(XDAS_Int32*)(B)
#defineBIG_D2B(D,B)*(XDAS_Int32*)(B)=(XDAS_Int32)(D)
#defineLITTLE_B2D(B,D)D=ENDIAN_REVERSE_DWORD(*(XDAS_Int32*)(B))
#defineLITTLE_D2B(D,B)*(XDAS_Int32*)(B)=ENDIAN_REVERSE_DWORD(D)
#elifdefined(LITTLE_ENDIAN)////Little-Endianmachine
#defineBIG_B2D(B,D)D=ENDIAN_REVERSE_DWORD(*(XDAS_Int32*)(B))
#defineBIG_D2B(D,B)*(XDAS_Int32*)(B)=ENDIAN_REVERSE_DWORD(D)
#defineLITTLE_B2D(B,D)D=*(XDAS_Int32*)(B)
#defineLITTLE_D2B(D,B)*(XDAS_Int32*)(B)=(XDAS_Int32)(D)
//ERROR()
原来这是因为我们在编译时,忘了添加USER_BIG_ENDIAN或USER_LITTLE_ENDIAN等宏。
在CCS的BuildOption选项中,加上即可:
没有运行DSP端程序
错误描述
这个问题发生在GPP和DSP程序联合测试时,当我试图在GPP端调用DSP端算法时,出现如下Trace信息:
ti.sdo.ce.image1.IMGENC1-IMGENC1_process>
Enter(handle=0x3d9c8,inBufs=…)
Exit(handle=0x3d9c8,retVal=0xFFFFFFFD)
错误分析
显然,在Trace信息中没有看到任何和DSP有关的消息,DSP端没有运行。
IMGENC1_process方法直接返回错误:
0xFFFFFFFD(实际上就是-3)。
打开头文件xdm.h,发现有一个含糊的定义:
#defineXDM_EUNSUPPORTED-3/**<
Requestisunsupported.*/
参考一个正确处理过程的Trace信息:
Enter(handle=0x3d9c8,inBufs=……)
CV-VISA_allocMsg>
AllocatingmessageformessageId=0x000600b2
OM-Memory_getBufferPhysicalAddress>
Enter(virtAddr=0x41209000,size=16641)
OM-Memory__getPhysicalAddress>
foundincb(Sc=0x41209000,Ec=……)
returningphysAddr=0x837ac000
return(0x837ac000)
Enter(virtAddr=0x41229000,size=262144)
@13,515,611us:
[+0T:
0x42ac9b60S:
0x42a88eac]CV-VISA_call(visa=0x3d9c8,msg=……
说明,这个错误时在stub中返回的。
修改IIMGENC1
到这一步,不禁想,要是TI提供的imgenc库能打印Trace信息就好了。
幸好CodecEngine里,为我们提供了IMGENC的源代码,因此我需要修改源文件,加入Trace模块,重新编译,替换掉TI原有的库就可以。
IMGENC源文件存放在目录:
($codecengine安装目录)\packages\ti\sdo\ce\image1文件夹中,这里我需要修改imgenc1_stubs.c。
在VisualStudio中打开文件,加入Trace的代码:
GT_Maskti_sdo_ce_image1_IMGENC1_curTrace;
BOOLti_sdo_ce_image1_IMGENC1_curTrace_init=FALSE;
以及初始化函数:
if(!
ti_sdo_ce_image1_IMGENC1_curTrace_init)
{
GT_create(&
ti_sdo_ce_image1_IMGENC1_curTrace,"
ti.sdo.ce.imgenc1.IMGENC1_STUBS"
);
GT_set("
ti.sdo.ce.imgenc1.IMGENC1_STUBS=01234567"
ti_sdo_ce_image1_IMGENC1_curTrace_init=TRUE;
}
接下来就可以在需要加入Trace的地方添加命令了。
GT_Trace使用方法可以参考我的文章:
使用GenericTraceSupport打印调试信息
编译
由于源文件目录下没有makefile、package.bld文件,我们需要手动添加:
makefile文件,主要是载入xdcpaths.mak、xdcrules.mak等文件
PROJECT_ROOTDIR:
=$(CURDIR)/../../../..
include$(PROJECT_ROOTDIR)/xdcpaths.mak
XDC_PATH:
=$(PROJECT_ROOTDIR);
$(XDC_PATH)
include$(PROJECT_ROOTDIR)/buildutils/xdcrules.mak
package.bld文件,主要是指定哪些文件需要被编译:
Pkg.attrs.exportAll=true;
varSRCS=["
imgenc1.c"
"
imgenc1_skel.c"
imgenc1_stubs.c"
];
Pkg.otherFiles=[
"
imgenc1.h"
for(vari=0;
i<
Build.targets.length;
i++){
vartarg=Build.targets[i];
Pkg.addLibrary("
lib/imgenc1"
targ,{
}).addObjects(SRCS);
lib/imgenc1_debug"
profile:
debug"
发现错误
最后,我发现,原来错误来自于:
if((sizeof(VISA_MsgHeader)+sizeof(*inBufs)+sizeof(*outBufs)+
inArgs->
size+outArgs->
size)>
sizeof(_IMGENC1_Msg)){
return(IIMGENC1_EUNSUPPORTED);
原来,我忘记在GPP端为outArgs指定size的值了:
outArgs.size=sizeof(outArgs);
加上后,错误解决。
莫名奇妙死机
问题描述
这下程序应该能完美运行了吧,我兴冲冲地传入测试参数,泡杯茶(第一次运行,不知道需要多久),开始等待……
五分钟过去了……怎么还没有结果?
应该是计算量大的问题,因为我的程序里用了大量的递归,先去打会儿网球吧
不是吧,都过去了两小时,怎么还是停留在这里?
VISA_call(visa=0x3d9c8,msg=0x4115ec80):
……
Comm_put>
Enter(queue=0x6,msg=0x4115ec80)
return(0)
Comm_get>
Enter(queue=0x10005,msg=0x42a88f14,timeout=-1)
Enter(queue=0x0,msg=0x41159c80)
强制退出后,DSP居然死机了……
问题分析
我们知道,DM6446是双核的,GPP和DSP。
一个算法接口,在GPP和DSP端分别对应Stub和Skelton。
GPP端在Stub中通过调用VISA_call方法来执行DSP端的代码。
DSP端完成操作后,在返回。
整个过程,是基于一种“消息”传递机制的。
从上面的Trace信息中可以看出:
代码已经执行到VISA_call,但是,却没有等到DSP端返回结果,因此处于一种“死机”状态。
只是这种状态,也太令人困混了:
由于DSP端没有返回任何信息,因此,我们根本看不到DSP端的Trace信息,无法判断到底是哪里出了问题。
我编写代码有个习惯,现在VC上将代码调试通过,然后移植到DSP上。
既然代码在VC上能调试成功,说明不是程序的问题。
最大的可能是:
内存分配错误导致DSP端代码崩溃!
基于这点,我检查了代码,发现最有可能的问题是:
递归太多。
接下来,我减少了递归的数量,重新编译后,程序通过。
修改栈大小
在C、C++编程中,堆(Heap)和栈(Stack)是分配内存空间,存放数据的两个重要地点。
一般的,使用malloc或new关键字分配的内存空间保存在堆中,而局部变量、或者函数的参数,都是保存在栈中。
因此,当一个程序中递归的数量很多时,栈空间往往不够,最终造成内存溢出。
打开项目中的xs文件,修改getStackSize方法,增大栈空间(我这里将原来的1024增加为4096):
functiongetStackSize(prog)
if(verbose){
print("
gettingstacksizefor"
+this.$name
+"
builtforthetarget"
+prog.build.target.$name
runningonplatform"
+prog.platformName);
}
return(4096);
或者也可以修改server端的cfg文件:
Server.algs=[
{name:
enctriangle"
mod:
ENCTRIANGLE,
groupId:
0,
threadAttrs:
{
stackSize:
4096,
stackMemId:
priority:
Server.MINPRI+1
},
无法分配内存
又出问题了
解决完上述问题,似乎可以松口气,运行程序,编码,一切正常!
怀着期盼的心情,我点击了解码按钮,结果……怎么我的图片少了一大块?
经过检查,确定不是解码的问题,看来编码这块儿还是不能让人放心啊!
继续分析问题
这次比较简单,在编码的关键点加入Trace后,清楚地发现,当系统运行到某个阶段时,
pPersonperson=(pTFlat)malloc(sizeof(Person));
返回NULL指针!
想必是堆空间不够了!
堆不够?
那就弄大点吧!
打开server工程的.cfg文件,睁大眼睛,仔细检查空间分配问题:
varmem_ext=[
comment:
DDRALGHEAP:
off-chipmemoryfordynamicalgmemallocation"
name:
DDRALGHEAP"
base:
0x82E00000,//46MB
len:
0x00a00000,//10MB
space:
code/data"
},
DDR2:
off-chipmemoryforapplicationcodeanddata"
DDR2"
0x83800000,//56MB
0x00600000,//6MB
DSPLINK:
off-chipmemoryreservedforDSPLINKcodeanddata"
DSPLINKMEM"
0x83E00000,//62MB
0x00100000,//1MB
RESET_VECTOR:
off-chipmemoryfortheresetvectortable"
RESET_VECTOR"
0x83F00000,//63MB
0x00000080,
怎么可能,我们明明分配了10MB的空间给DDRALGHEAP。
继续往下看吧:
bios.DDR2.createHeap=true;
bios.DDR2.heapSize=0x20000;
//128K
bios.DDRALGHEAP.createHeap=true;
bios.DDRALGHEAP.heapSize=bios.DDRALGHEAP.len;
试着修改bios.DDR2.heapSize的值,改成0×
40000。
运行程序,错误解决了。
为什么是DDR2
根据上面的内存分配表,DDR2区域应该是存放算法代码、数据的,不应该具备“堆”的功能,为什么这里修改了bios.DDR2.heapSize却可以回避异常呢?
按理来说,应该是DDRALGHEAP才对。
再说,当前程序中将bios.DDR2.heapSize设置成0×
40000可以,如果将来运算量多,区区256K的堆空间,不一定能用。
继续查看代码,发现cfg中设置如下:
bios.setMemCodeSections(prog,bios.DDR2);
bios.setMemDataNoHeapSections(prog,bios.DDR2);
bios.setMemDataHeapSections(prog,bios.DDR2);
修改如下:
bios.setMemDataHeapSections(prog,bios.DDRALGHEAP);
OK了!
无法更新outbuf
这个问题出现在当对第二幅图像编码完成后,从DSP端传出的数值仍然是第一幅图像的编码结果。
分析
DM6446是双核处理器,GPP端和DSP端通过CMEM共享内存来传递数据。
GPP端是相对地址,DSP端是绝对地址。
二者实际上是对应不同的内存块,通过CodecEngineAPI中的Memory_cacheInv、Memory_cacheWb等函数来转换数据(相当于memcpy)。
因此,如果出现上述问题,肯定是由于在skel层没有执行相应的操作。
打开imgenc1_skel.c。
找到以下代码:
if((pStatus->
data.buf!
=NULL)&
&
XDM_ISACCESSMODE_WRITE(pStatus->
data.accessMask)){
Memory_cacheWb(pStatus->
data.buf,pStatus->
data.bufSize);
/*
*Sincewe'
vecacheWbthisbuffer,wearguablyshould
*reflectthiscachestateandcleartheWRITEbitin
*the.accessMaskfield.However,weknowthestub
*doesn'
tpropogatethisfieldtothecallingapp,so
*thisextrabuffermanagementdetailisn'
tnecessary:
*
*XDM_CLEARACCESSMODE_WRITE(pStatus->
data.accessMask);
*/
不难判断,问题出现在XDM_ISACCESSMODE_WRITE(data.accessMask)这里。
解决问题
原来,在DSP端的Skel中,MemoryAPI通过查看data.accessMask来判断该段内存是否被写过,如果写过,才将它转化成GPP端的内存,否则,跳过。
打开Codec实现文件,在更新完outBufs数据后,修改outBufs的accessMask:
/*report_how_weaccessedthe2databuffers*/
XDM_CLEARACCESSMODE_WRITE(inBufs->
descs[0].accessMask);
XDM_SETACCESSMODE_READ(inBufs->
XDM_CLEARACCESSMODE_READ(outBufs->
XDM_SETACCESSMODE_WRITE(outBufs->
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Davinci 开发中的灵异事件 开发 中的 灵异 事件
![提示](https://static.bingdoc.com/images/bang_tan.gif)