ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:68.27KB ,
资源ID:10625639      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10625639.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Davinci 开发中的灵异事件.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Davinci 开发中的灵异事件.docx

1、Davinci 开发中的灵异事件Davinci 开发中的“灵异事件”在进行Codec Engine 服务器端的开发时,有时会出现一些莫名其妙的现象,在模拟器上明明跑得好好地一段程序,移植到开发板上愣是出现一堆错误。这些错误,和GPP端不同:它们没有错误信息、不会自动退出、甚至连Trace信息也不打印。我把这些都称为“灵异事件”。当然,这些事件的产生还是归咎于代码本身的缺陷或不周全。以下问题是我在开发Davinci应用程序中遇见的,摘录下来,供大家参考。链接时提示符号未定义这个问题发生在Sever端集成时,无论Lib、还是Codec在各自的机器上都编译通过了,唯独集成在一起时,确出现了以下集成错

2、误信息:undefined first referenced symbol in file- -_LITTLE_B2D /prj/common/lib/libaes.a_LITTLE_D2B /prj/common/lib/libaes.a打开libaes项目,发现LITTLE_B2D、LITTLE_D2B定义在头文件中:#undef BIG_ENDIAN#undef LITTLE_ENDIAN#if defined(USER_BIG_ENDIAN) #define BIG_ENDIAN#elif defined(USER_LITTLE_ENDIAN) #define LITTLE_ENDIA

3、N#else #if 0 #define BIG_ENDIAN / Big-Endian machine with pointer casting #elif defined(_MSC_VER) #define LITTLE_ENDIAN / Little-Endian machine with pointer casting #else / #error #endif#endif#if defined(BIG_ENDIAN) / Big-Endian machine #define BIG_B2D(B, D) D = *(XDAS_Int32 *)(B) #define BIG_D2B(D,

4、 B) *(XDAS_Int32 *)(B) = (XDAS_Int32)(D) #define LITTLE_B2D(B, D) D = ENDIAN_REVERSE_DWORD(*(XDAS_Int32 *)(B) #define LITTLE_D2B(D, B) *(XDAS_Int32 *)(B) = ENDIAN_REVERSE_DWORD(D)#elif defined(LITTLE_ENDIAN) / Little-Endian machine #define BIG_B2D(B, D) D = ENDIAN_REVERSE_DWORD(*(XDAS_Int32 *)(B) #d

5、efine BIG_D2B(D, B) *(XDAS_Int32 *)(B) = ENDIAN_REVERSE_DWORD(D) #define LITTLE_B2D(B, D) D = *(XDAS_Int32 *)(B) #define LITTLE_D2B(D, B) *(XDAS_Int32 *)(B) = (XDAS_Int32)(D)#else /ERROR()#endif原来这是因为我们在编译时,忘了添加USER_BIG_ENDIAN或USER_LITTLE_ENDIAN等宏。在CCS的Build Option选项中,加上即可:没有运行DSP端程序错误描述这个问题发生在GPP和D

6、SP程序联合测试时,当我试图在GPP端调用DSP端算法时,出现如下Trace信息:ti.sdo.ce.image1.IMGENC1 - IMGENC1_process Enter (handle=0x3d9c8, inBufs=)ti.sdo.ce.image1.IMGENC1 - IMGENC1_process Exit (handle=0x3d9c8, retVal=0xFFFFFFFD)错误分析显然,在Trace信息中没有看到任何和DSP有关的消息,DSP端没有运行。IMGENC1_process方法直接返回错误:0xFFFFFFFD(实际上就是-3)。 打开头文件xdm.h,发现有一个

7、含糊的定义:#define XDM_EUNSUPPORTED -3 /* Enter (handle=0x3d9c8, inBufs=)CV - VISA_allocMsg Allocating message for messageId=0x000600b2OM - Memory_getBufferPhysicalAddress Enter(virtAddr=0x41209000, size=16641)OM - Memory_getPhysicalAddress Enter(virtAddr=0x41209000, size=16641)OM - Memory_getPhysicalAdd

8、ress found in cb(Sc=0x41209000, Ec=)OM - Memory_getPhysicalAddress returning physAddr=0x837ac000OM - Memory_getBufferPhysicalAddress return (0x837ac000)OM - Memory_getBufferPhysicalAddress Enter(virtAddr=0x41229000, size=262144)13,515,611us: +0 T:0x42ac9b60 S:0x42a88eac CV - VISA_call(visa=0x3d9c8,

9、msg=说明,这个错误时在stub中返回的。修改IIMGENC1到这一步,不禁想,要是TI提供的imgenc库能打印Trace信息就好了。幸好Codec Engine里,为我们提供了IMGENC的源代码,因此我需要修改源文件,加入Trace模块,重新编译,替换掉TI原有的库就可以。 IMGENC源文件存放在目录:($codecengine安装目录)packagestisdoceimage1文件夹中,这里我需要修改imgenc1_stubs.c。在Visual Studio中打开文件,加入Trace的代码:GT_Mask ti_sdo_ce_image1_IMGENC1_curTrace;BOO

10、L ti_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

11、_Trace使用方法可以参考我的文章:使用Generic Trace Support打印调试信息编译由于源文件目录下没有makefile、package.bld文件,我们需要手动添加:makefile文件,主要是载入xdcpaths.mak、xdcrules.mak等文件PROJECT_ROOTDIR := $(CURDIR)/./././.include $(PROJECT_ROOTDIR)/xdcpaths.makXDC_PATH := $(PROJECT_ROOTDIR);$(XDC_PATH)include $(PROJECT_ROOTDIR)/buildutils/xdcrules.

12、makpackage.bld文件,主要是指定哪些文件需要被编译:Pkg.attrs.exportAll = true;var SRCS = imgenc1.c, imgenc1_skel.c, imgenc1_stubs.c;Pkg.otherFiles = imgenc1.h;for (var i = 0; i size + outArgs-size) sizeof(_IMGENC1_Msg) return (IIMGENC1_EUNSUPPORTED);原来,我忘记在GPP端为outArgs指定size的值了:outArgs.size = sizeof(outArgs);加上后,错误解决。

13、莫名奇妙死机问题描述这下程序应该能完美运行了吧,我兴冲冲地传入测试参数,泡杯茶(第一次运行,不知道需要多久),开始等待五分钟过去了怎么还没有结果?应该是计算量大的问题,因为我的程序里用了大量的递归,先去打会儿网球吧不是吧,都过去了两小时,怎么还是停留在这里?VISA_call(visa=0x3d9c8, msg=0x4115ec80): Comm_put Enter(queue=0x6, msg=0x4115ec80)Comm_put return (0)Comm_get Enter(queue=0x10005, msg=0x42a88f14, timeout=-1)Comm_get retu

14、rn (0)Comm_put 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端

15、的Trace信息,无法判断到底是哪里出了问题。我编写代码有个习惯,现在VC上将代码调试通过,然后移植到DSP上。既然代码在VC上能调试成功,说明不是程序的问题。最大的可能是:内存分配错误导致DSP端代码崩溃!基于这点,我检查了代码,发现最有可能的问题是:递归太多。接下来,我减少了递归的数量,重新编译后,程序通过。修改栈大小在C、C+编程中,堆(Heap)和栈(Stack)是分配内存空间,存放数据的两个重要地点。一般的,使用malloc或new关键字分配的内存空间保存在堆中,而局部变量、或者函数的参数,都是保存在栈中。因此,当一个程序中递归的数量很多时,栈空间往往不够,最终造成内存溢出。打开项目

16、中的xs文件,修改getStackSize方法,增大栈空间(我这里将原来的1024增加为4096):function getStackSize(prog) if (verbose) print(getting stack size for + this.$name + built for the target + prog.build.target.$name + , running on platform + prog.platformName); return (4096);或者也可以修改server端的cfg文件:Server.algs = name: enctriangle, mod:

17、 ENCTRIANGLE, groupId: 0, threadAttrs: stackSize: 4096, stackMemId: 0, priority: Server.MINPRI + 1 ,;无法分配内存又出问题了解决完上述问题,似乎可以松口气,运行程序,编码,一切正常!怀着期盼的心情,我点击了解码按钮,结果怎么我的图片少了一大块?经过检查,确定不是解码的问题,看来编码这块儿还是不能让人放心啊!继续分析问题这次比较简单,在编码的关键点加入Trace后,清楚地发现,当系统运行到某个阶段时,pPerson person=(pTFlat)malloc(sizeof(Person);返回NU

18、LL指针!想必是堆空间不够了!堆不够?那就弄大点吧!打开server工程的.cfg文件,睁大眼睛,仔细检查空间分配问题:var mem_ext = comment: DDRALGHEAP: off-chip memory for dynamic algmem allocation, name: DDRALGHEAP, base: 0x82E00000, / 46MB len: 0x00a00000, / 10MB space: code/data, comment: DDR2: off-chip memory for application code and data, name: DDR2,

19、 base: 0x83800000, / 56MB len: 0x00600000, / 6MB space: code/data, comment: DSPLINK: off-chip memory reserved for DSPLINK code and data, name: DSPLINKMEM, base: 0x83E00000, / 62MB len: 0x00100000, / 1MB space: code/data, comment: RESET_VECTOR: off-chip memory for the reset vector table, name: RESET_

20、VECTOR, base: 0x83F00000, / 63MB len: 0x00000080, space: code/data,;怎么可能,我们明明分配了10MB的空间给DDRALGHEAP。继续往下看吧:bios.DDR2.createHeap = true;bios.DDR2.heapSize = 0x20000; / 128Kbios.DDRALGHEAP.createHeap = true;bios.DDRALGHEAP.heapSize = bios.DDRALGHEAP.len;试着修改bios.DDR2.heapSize的值,改成040000。运行程序,错误解决了。为什么是

21、DDR2根据上面的内存分配表,DDR2区域应该是存放算法代码、数据的,不应该具备“堆”的功能,为什么这里修改了bios.DDR2.heapSize却可以回避异常呢?按理来说,应该是DDRALGHEAP才对。再说,当前程序中将bios.DDR2.heapSize设置成040000可以,如果将来运算量多,区区256K的堆空间,不一定能用。继续查看代码,发现cfg中设置如下:bios.setMemCodeSections(prog, bios.DDR2);bios.setMemDataNoHeapSections(prog, bios.DDR2);bios.setMemDataHeapSection

22、s(prog, bios.DDR2);修改如下:bios.setMemCodeSections(prog, bios.DDR2);bios.setMemDataNoHeapSections(prog, bios.DDR2);bios.setMemDataHeapSections(prog, bios.DDRALGHEAP);OK了!无法更新outbuf问题描述这个问题出现在当对第二幅图像编码完成后,从DSP端传出的数值仍然是第一幅图像的编码结果。分析DM6446是双核处理器,GPP端和DSP端通过CMEM共享内存来传递数据。GPP端是相对地址,DSP端是绝对地址。二者实际上是对应不同的内存块,

23、通过Codec Engine API中的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); /* * Since weve cacheWb this buffer,

24、we arguably should * reflect this cache state and clear the WRITE bit in * the .accessMask field. However, we know the stub * doesnt propogate this field to the calling app, so * this extra buffer management detail isnt necessary: * * XDM_CLEARACCESSMODE_WRITE(pStatus-data.accessMask); */不难判断,问题出现在X

25、DM_ISACCESSMODE_WRITE(data.accessMask)这里。解决问题原来,在DSP端的Skel中,Memory API通过查看data.accessMask来判断该段内存是否被写过,如果写过,才将它转化成GPP端的内存,否则,跳过。打开Codec实现文件,在更新完outBufs数据后,修改outBufs的accessMask:/* report _how_ we accessed the 2 data buffers */XDM_CLEARACCESSMODE_WRITE(inBufs-descs0.accessMask);XDM_SETACCESSMODE_READ(inBufs-descs0.accessMask);XDM_CLEARACCESSMODE_READ(outBufs-descs0.accessMask);XDM_SETACCESSMODE_WRITE(outBufs-descs0.accessMask);

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1