使用TI DaVinci OMAP3530/DM3730, etc. 做ARM與DSP的異質多核心程式開發時,由於雙核心架構下,DSP是由ARM在控制,與過去單純DSP的做法不同,因此DSP的debug是一件複雜的事情。
依照我的了解,可以使用的方法有兩種:
其一為使用 Codec Engine的 CE_DEBUG功能,第二是使用Codec Engine的TraceUtil方法
依照我的了解,可以使用的方法有兩種:
其一為使用 Codec Engine的 CE_DEBUG功能,第二是使用Codec Engine的TraceUtil方法
在TI的建議裡面 CE_DEBUG 是拿來檢視 函式功能的,看是不是有進到哪個function
(類似於OpenCV中的 CV_FUNCNAME 功能) ,而TraceUtil適合於runtime 找performance上的問題。
首先注意cfg不要有這條 xdc.useModule("ti.sdo.ce.osal.Global").embedBuildInfo = false; 這會會關掉 CE_DEBUG
(如果有要改成true, default我記得是true,所以不一定有)
TraceUtil 要開啟必須注意 remote.cfg中的 TraceUtil.attrs = TraceUtil.FULL_TRACING; 要開啟
(就是不要註解掉,不要寫成下面三種狀況
//TraceUtil.attrs = TraceUtil.NO_TRACING;
//TraceUtil.attrs = TraceUtil.SOCRATES_TRACING;
//TraceUtil.attrs = TraceUtil.DEFAULT_TRACING; )
當程式要執行時,在 執行命令前加上 CE_DEBUG=1 (可為1 or 2 or 3)
例如有一個執行檔: edge_detection
則在command line下,執行 CE_DEBUG=1 edge_detection 即可,當然後面要加參數也是可以,照舊。
當CE_DEBUG=3時,會有最完整的資訊。
CE_DEBUG可參考 : http://processors.wiki.ti.com/index.php/CE_DEBUG
TraceUtil 可參考: http://processors.wiki.ti.com/index.php/TraceUtil (注意Codec engine 3.x後又不支援了,但可以不要理這件事,因為TI後續改架構,DVSDK 到 4.x:,後面捨棄這種做法,往OpenMP靠攏,工具都會換掉,例如關鍵的DSPLink就換成SysLink,所以不用期待在既有板子上,要能用別的方法debug)
最後必須注意: dsplinkk.ko 編譯的時候,trace要打開(我記得預設是打開的..)參考:http://processors.wiki.ti.com/index.php/Enabling_trace_in_DSPLink 以及http://processors.wiki.ti.com/index.php/Building_DSPLink
(類似於OpenCV中的 CV_FUNCNAME 功能) ,而TraceUtil適合於runtime 找performance上的問題。
首先注意cfg不要有這條 xdc.useModule("ti.sdo.ce.osal.Global").embedBuildInfo = false; 這會會關掉 CE_DEBUG
(如果有要改成true, default我記得是true,所以不一定有)
TraceUtil 要開啟必須注意 remote.cfg中的 TraceUtil.attrs = TraceUtil.FULL_TRACING; 要開啟
(就是不要註解掉,不要寫成下面三種狀況
//TraceUtil.attrs = TraceUtil.NO_TRACING;
//TraceUtil.attrs = TraceUtil.SOCRATES_TRACING;
//TraceUtil.attrs = TraceUtil.DEFAULT_TRACING; )
當程式要執行時,在 執行命令前加上 CE_DEBUG=1 (可為1 or 2 or 3)
例如有一個執行檔: edge_detection
則在command line下,執行 CE_DEBUG=1 edge_detection 即可,當然後面要加參數也是可以,照舊。
當CE_DEBUG=3時,會有最完整的資訊。
CE_DEBUG可參考 : http://processors.wiki.ti.com/index.php/CE_DEBUG
TraceUtil 可參考: http://processors.wiki.ti.com/index.php/TraceUtil (注意Codec engine 3.x後又不支援了,但可以不要理這件事,因為TI後續改架構,DVSDK 到 4.x:,後面捨棄這種做法,往OpenMP靠攏,工具都會換掉,例如關鍵的DSPLink就換成SysLink,所以不用期待在既有板子上,要能用別的方法debug)
最後必須注意: dsplinkk.ko 編譯的時候,trace要打開(我記得預設是打開的..)參考:http://processors.wiki.ti.com/index.php/Enabling_trace_in_DSPLink 以及http://processors.wiki.ti.com/index.php/Building_DSPLink
具體程式使用方法,底下轉貼自: http://www.cnblogs.com/elect-fans/archive/2011/12/06/2408730.html
在代码中使用Generic Trace Support:
首先,我们要定义一个GT_Mask对象,GT_Mask是用来描述GT模块的对象,它的定义如下:
typedef struct {
String modName;
UInt8 *flags;
} GT_Mask;
我们在程序中可以这样定义:
GT_Mask curMask = {0,0};
然后,调用初始化函数:
GT_create(&curMask, "snowwaft");
GT_set("snowwaft=01234567");
上面的代码,我们给curMask设定了名字:snowwaft,将它的级别设为0-7(有关级别,后面会描述)。
当完成以上工作后,我们就可以使用GT模块来输出信息了:
GT_0trace(curMask, GT_2CLASS, "main>; Welcome to DSP server's main().\n");
屏幕会输出如下结果:
[DSP] @0×000001a2:[T:0x00000000] snowwaft - main> Welcome to DSP server’s main().
关于GT_*trace宏,以上我们使用GT_0trace宏来输出信息,同样的,我们还可以使用以下宏:
GT_0trace( mask, classId, format )
GT_1trace( mask, classId, format, arg1 )
GT_2trace( mask, classId, format, arg1, arg2 )
GT_3trace( mask, classId, format, arg1, arg2, arg3 )
GT_4trace( mask, classId, format, arg1, arg2, arg3, arg4 )
GT_5trace( mask, classId, format, arg1, arg2, arg3, arg4, arg5 )
GT_6trace( mask, classId, format, arg1, arg2, arg3, arg4, arg5, arg6 )
这些宏分别定义了输出1个、2个、……、6个参数的使用方式,例如,我们需要输出两个参数:
GT_2trace(curMask, GT_2CLASS, "App->; Decode frame %d (0x%x)\n",p1,p2);
关于GT_*CLASS宏,在GT_*trace宏里,第二个参数为classId,这个参数是什么用的呢?某些时候,我们在打印Trace信息的时候,有可能希望只打印某些级别的信息,而不打印其他级别的信息,因此,我们指定classID。
在GT Module里一共定义了7种级别:
#define GT_1CLASS ((UInt8)0x02)
#define GT_2CLASS ((UInt8)0x04)
#define GT_3CLASS ((UInt8)0x08)
#define GT_4CLASS ((UInt8)0x10)
#define GT_5CLASS ((UInt8)0x20)
#define GT_6CLASS ((UInt8)0x40)
#define GT_7CLASS ((UInt8)0x80)
这7种级别分别表示:
GT_1CLASS : 纯粹的Debug信息
GT_2CLASS : 由开发人员指定,告诉使用人员这这条信息可能有用
GT_3CLASS : 进入某个模块
GT_4CLASS : 由开发人员指定,告诉使用人员这是比较重要的信息
GT_5CLASS : 标记
GT_6CLASS : 警告
GT_7CLASS : 错误
不难理解,为什么我们要在调用GT_set时制定:snowwaft=01234567,这表示,对于snowwaft这个GT_Mask,我们关心的信息包括以上所有部分,而0,则表示进入、退出某个函数的报告。
【小节】使用GT_Mask,可以在DSP端和ARM端间打印信息,这在一定程度上方便了我们调试信息。
在代码中使用Generic Trace Support:
首先,我们要定义一个GT_Mask对象,GT_Mask是用来描述GT模块的对象,它的定义如下:
typedef struct {
String modName;
UInt8 *flags;
} GT_Mask;
我们在程序中可以这样定义:
GT_Mask curMask = {0,0};
然后,调用初始化函数:
GT_create(&curMask, "snowwaft");
GT_set("snowwaft=01234567");
上面的代码,我们给curMask设定了名字:snowwaft,将它的级别设为0-7(有关级别,后面会描述)。
当完成以上工作后,我们就可以使用GT模块来输出信息了:
GT_0trace(curMask, GT_2CLASS, "main>; Welcome to DSP server's main().\n");
屏幕会输出如下结果:
[DSP] @0×000001a2:[T:0x00000000] snowwaft - main> Welcome to DSP server’s main().
关于GT_*trace宏,以上我们使用GT_0trace宏来输出信息,同样的,我们还可以使用以下宏:
GT_0trace( mask, classId, format )
GT_1trace( mask, classId, format, arg1 )
GT_2trace( mask, classId, format, arg1, arg2 )
GT_3trace( mask, classId, format, arg1, arg2, arg3 )
GT_4trace( mask, classId, format, arg1, arg2, arg3, arg4 )
GT_5trace( mask, classId, format, arg1, arg2, arg3, arg4, arg5 )
GT_6trace( mask, classId, format, arg1, arg2, arg3, arg4, arg5, arg6 )
这些宏分别定义了输出1个、2个、……、6个参数的使用方式,例如,我们需要输出两个参数:
GT_2trace(curMask, GT_2CLASS, "App->; Decode frame %d (0x%x)\n",p1,p2);
关于GT_*CLASS宏,在GT_*trace宏里,第二个参数为classId,这个参数是什么用的呢?某些时候,我们在打印Trace信息的时候,有可能希望只打印某些级别的信息,而不打印其他级别的信息,因此,我们指定classID。
在GT Module里一共定义了7种级别:
#define GT_1CLASS ((UInt8)0x02)
#define GT_2CLASS ((UInt8)0x04)
#define GT_3CLASS ((UInt8)0x08)
#define GT_4CLASS ((UInt8)0x10)
#define GT_5CLASS ((UInt8)0x20)
#define GT_6CLASS ((UInt8)0x40)
#define GT_7CLASS ((UInt8)0x80)
这7种级别分别表示:
GT_1CLASS : 纯粹的Debug信息
GT_2CLASS : 由开发人员指定,告诉使用人员这这条信息可能有用
GT_3CLASS : 进入某个模块
GT_4CLASS : 由开发人员指定,告诉使用人员这是比较重要的信息
GT_5CLASS : 标记
GT_6CLASS : 警告
GT_7CLASS : 错误
不难理解,为什么我们要在调用GT_set时制定:snowwaft=01234567,这表示,对于snowwaft这个GT_Mask,我们关心的信息包括以上所有部分,而0,则表示进入、退出某个函数的报告。
【小节】使用GT_Mask,可以在DSP端和ARM端间打印信息,这在一定程度上方便了我们调试信息。