该文档以下面路径内的cla_asin工程为例来说明CLA调试与分析的相关注意事项。
C2000Ware_3_02_00_00\device_support\f2837xd\examples\cpu1\cla_asin
1. CLA调试
用户可以按照以下步骤开始在CLA上调试其代码
1) 添加_mdebugstop()
- 在要调试的CLA任务的开始处放置__mdebugstop()。如Cla1Task1
2) 设置构建选项:
- 您可以为* .cla文件设置单独的构建属性。
- 右键单击.cla文件,然后选择Properties-> C / C ++ Build,如下图1所示
图1 设置构建选项
3) 连接到CLA:
- 一旦构建了项目并启动了调试会话,默认情况下,CCS将仅连接到C28内核
- 为了能够调试CLA代码,您将需要连接到CLA内核
- 注意: 使用-g(完整符号调试)构建代码以生成将加载到调试器的符号
- 单击CLA debug session
- 选择Target->Connect to Target或使用Alt-C快捷键
- 一旦连接了CLA内核,就可以通过单击RUN-> Load-> Load Symbols- > cla_asin_cpu01.out来继续加载项目符号,如下图2所示
图2 CLA连接
4) 运行C28x:
在该示例中,我们启用了CLA的task1,并在C28端的软件中触发了它。当我们在C28调试会话上运行代码时,它似乎停滞在Cla1ForceTask1andWait()中,这表明正在等待CLA任务1运行完成。当我们切换到CLA会话时,我们看到__mdebustop()内在函数已停止执行。
5) 调试代码:
- 此时,我们可以单步执行代码。
- 调试CLA有一些限制,下面将讨论
2. 已知的调试问题
- CLA pipeline 不会在单个步骤上被刷新。因此结果需要等到再执行几条指令(一般为3条)之后才可能可见。请参阅CLA用户指南,以获取有关pipeline的更多详细信息。
- 如果您打算在CLA上调试(单步)代码,则必须将MNOP放在MSTOP之前,以确保指令在执行MSTOP之前先通过pipeline 。
- 如果使用debug(-g)进行编译,则编译器将插入这些MNOP。如果不调试CLA代码,则不需要MNOP。
- 不支持Run-to-Line。Step over 和Step into 效果相同
3. Task运行时间分析
CLA不支持时钟功能,因此无法直接获得特定任务的周期计数。用户可以在ePWM上配置时基模块,以跟踪任务的执行时间。
可以将ePWM1(或任何ePWM)的时基设置为以递增计数模式在SYSCLKOUT上运行,如下所示:
void InitEPwm(void) {
// Setup TBCLK
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm1Regs.TBPRD = 0xFFFF; // Set timer period
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm1Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0
EPwm1Regs.TBCTR = 0x0000; // Clear counter
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
}
而后定义两个宏READ_CLOCK和RESTART_CLOCK,前一个宏冻结ePWM计时器并将经过的时间复制到变量中,而后者重新启动ePWM计时器。
#define READ_CLOCK(X) __meallow();\
EPwm1Regs.TBCTL.bit.CTRMODE = TB_FREEZE;\
X = EPwm1Regs.TBCTR;\
__medis();
#define RESTART_CLOCK __meallow();\
EPwm1Regs.TBCTL.bit.CTRMODE = TB_FREEZE;\
EPwm1Regs.TBCTR = 0;\
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;\
__medis();
定义一个变量,例如ulCycleCount来保存周期数
#pragma DATA_SECTION(ulCycleCount,"Cla1ToCpuMsgRAM");
unsigned long ulCycleCount;
将RESTART_CLOCK放在任务的开始处以重新启动ePWM计时器,并将READ_CLOCK放在任务的末尾以读取计时器的值。经过的时间将为您提供周期计数以及两个宏的最小开销
__interrupt void Cla1Task1 ( void ) {
//Local Variables
float a;
__mdebugstop();
RESTART_CLOCK;
a = 10;
...
...
...
READ_CLOCK(ulCycleCount);
}
测试结果如下图3所示:
图3 测试结果
最后附上工程文件: