DSP无法在线仿真无法进入main()函数
1.问题描述
接手前人的DSP代码,硬件平台是DSP C6701,软件IDE是CCS 12.3.0。仿真器版本是XDS 560V2。
在进行在线仿真时,经常出现“伪在线”的情况。简单来说,正常的在线过程:在CCS软件中点击debug按钮,程序加载进硬件后,会进入暂停状态,此时点击继续运行按钮,程序开始运行,接收遥控指令等功能正常。而“伪在线”地情况,点击debug按钮,程序加载进硬件进入暂停状态,此时点击继续运行按钮,程序看似正常运行,但不对遥控进行响应,此时暂停程序,会显示停留在中断函数的某一句语句上,重复地进行“暂停-启动”操作,程序每次都停止在相同的语句。
在第一版代码中,也就是前人的代码,该问题偶尔出现,出现该问题后需要反复重启产品、仿真器、CCS软件等,运气好的话几次就能在线成功。
在对第一版代码进行修改后,本文使用第二版代码进行在线,开始每次都出现该问题,始终无法在线成功。
程序的大概结构如下:
class ReceiveSend
{
private:
//一些私有函数和私有变量
public:
fun_process();
fun_isr_process();
}
ReceiveSend * ptr_tmp;
int main()
{
//中断定时器设置
_fun_timer00_set();
//中断设置
_fun_isr_init();
//DSP EMIF口初始话
_fun_emif_init();
//new对象
ptr_tmp = new ReceiveSend;
while(1)
{
//需要在main()中的对时间要求不高的功能
//包含接收遥控指令,发送遥测数据
ptr_tmp -> fun_processs();
}
return 0;
}
interrupt void c_int14()
{
//在中断中运行的,对事件要求比较高的功能
ptr_tmp -> fun_isr_process();
}
2.问题定位
代码中的fun_processs()
函数实现了接收主机的遥控指令,向主机发送遥测数据的功能,因此在debug的过程中,将主机能否接收到遥测数据作为程序是否正常运行的判别标准。如果主机可以接收到遥测数据,则认为程序正常运行。
(1)最开始怀疑是第二版代码添加的功能太多了,造成了无法在线运行的问题,因此将许多无效的变量和函数删除,将Memory的分配占比调整地比第一版的分配占比还低,但是很可惜,“伪在线”的问题还是没有解决。
(2)接下来将中断函数c_int14
中fun_isr_process()
函数中的内容全部注释,也就是保留中断函数,但是中断函数中不执行任何功能。这回程序fun_process()
中的遥控遥测收发是正常的,主机端接收到了遥测。
于是怀疑是fun_isr_process()
中的功能太多了,在中断事件内无法运行完。程序此时是具备遥控遥测收发功能的,fun_isr_process()
函数中没有任何功能,本文使用#if 0的办法,去增加fun_isr_process()
中的功能模块。如果增加到,比如说C模块时,遥控遥测收发不正常了,那么问题可能出现在C模块的代码中。
试验的结果比较奇怪:
第一次试验,逐步地增加模块数量,直到剩余1个功能模块没有启用,程序正常运行,将最后1个模块也启用,程序不能正常运行;
第二次试验,产品断电重启,将代码恢复到可以正常启用的情况,也就是不启用最后1个模块的状态,程序不能正常运行;
第三次试验,产品断电重启,重复第一次试验的步骤,逐步增加模块数量直至最后1个功能模块,程序正常运行。
第四次试验,产品断点重启,重复第一次试验的步骤,逐步增加功能模块,直到启用最后1个功能模块,此时程序不能正常运行,此时不断电,将代码中的最后1个模块禁用, 程序还是不能正常运行。
总结来说,代码完全相同的情况下,程序能否正常运行是个玄学问题。
(3)
重复(2)中的第四次试验,到达“最后1个模块禁用+程序不能正常运行”的状态,在fun_process()
函数中打上断点,断点位于一个必定会执行的函数后,结果程序没有停止在断点的位置。
本文怀疑fun_process()
函数根本就没有运行,没有运行自然就没有遥控遥测收发功能了。
3.问题解决
以“DSP程序不进入main()函数”进行搜索,搜索到了一个可能的原因:
求助:DSP28034程序跑不到main是什么原因 (amobbs.com 阿莫电子技术论坛)
本文的第二版代码确实是向class中添加了很多变量和函数。
于是调整了一下main()函数中的代码的顺序,将new ReceiveSend
的操作放到程序的最开始,也就是中断函数设置之前,问题解决,可以正常地在线调试了…
int main()
{
//放置在最开始
ptr_tmp = new ReceiveSend;
//中断定时器设置
_fun_timer00_set();
//中断设置
_fun_isr_init();
//DSP EMIF口初始话
_fun_emif_init();
//new对象
//ptr_tmp = new ReceiveSend;
本文猜测是中断设置完成后,中断函数就开始运行了,中断函数中的fun_isr_process()
函数用到了class ReceiveSend
中的变量和函数,而这个时候还还在new
的过程中,还没有初始化完成,就产生冲突,造成程序无法正确运行了。当然这些都是猜测,不管怎么说,虽然不了解原理,但是问题得到了解决,没有耽误开发。
4.遗留问题
遗留的问题在于,为什么“伪在线”的问题只出现在线仿真阶段,如果将程序的.bin文件烧写进Flash,由FPGA加载程序,就不出现该问题。也许在线加载和从Flash启动程序存在区别?