烧写flash后的dsp程序运行不正常的情况分析.docx
这段时间一直在调试DSP6713的FLASH烧写,现在对FLASH的烧写也算心中了如。那天,非常HAPPY的发现将闪烁LED烧写到FLASH成功了,然后,就以为一切都OK了那天,成功烧写了一个300KB以上的程序,又认为,这次应该OK了那天,写了个TIMER中断程序,烧写到FLASH,却死机了那天,在RAM上运行很流畅的一个算法(算法中调用了CCS的ATAN函数),在烧写到FLASH后算法却死机了那天,我开始思考是什么情况导致RAM中跑得很HAPPY的程序烧写到FLASH就运行得如此的不堪众多的囧相。“且行且珍惜”,珍惜这些次发现BUG的机会,因此,我要总结在RAM中能正常运行,而烧写到FLASH后无法正常运行的一些情况讨论。请检查中断向量表中断向量表包含了所有中断的入口,在烧写FLASH的时候,有两种方式可以保证中断能正常工作。具体可参见TMS320C6713烧写FLASH的通用方法的第5小节。请检查程序中隐蔽的内存错误很多情况下,当出现数组越界时,在RAM中的程序都能正常运行,但在烧写FLASH后运行就会出现死机或程序跑飞的现象。比如定义一个数组,INTX5你使用X510这样的语句在RAM程序中是某些时候能正确运行的,在PC上应该也可以。但将这种程序烧写到FLASH之后运行,DSP果断和你说拜拜因此,请谨慎地检查程序代码中的数组越界和指针操作。在DSP程序中,坚决不使用C库函数中的MALLOC函数。如果需要动态分配内存的操作,可以自己写一个,或使用UCOSII或DSP/BIOS等嵌入式操作系统。请尽量避免使用MATHH中的三角及LOG等函数也不知道是什么原因,也可能是我对ATAN函数的使用方法不正确造成的吧。在我的一个最初的程序中,我是直接这样计算ATANX的,FLOATX,YYATANX//X范围为0,17在RAM中以及在PC中都多次测试过没有任何问题。烧写FLASH之后,也不是死机,但程序运行到ATAN这个函数的时候会卡上很长一段时间,再接着往下运行。难道是MATHH中的ATAN运算效率太低但为什么RAM中就能运行呢这个还不清楚。于是想了个招,在要使用三角函数和LOG等函数的地方都使用查表法替代库函数,在精度要求高而存储空间又有限的场合,可使用查表插值的方式。下面是改进方法计算ATAN,/TABLEOFDETERMINEATANX/CONSTFLOATATAN_TB{//精度0020000,115,229,343,457,571,684,797,909,1020,1131,1241,1350,1457,1564,1670,1774,1878,1980,2081,2180,2278,2375,2470,2564,2657,2747,2837,2925,3011,3096,3180,3262,3342,3422,3499,3575,3650,3723,3795,3866,3935,4003,4070,4135,4199,4261,4323,4383,4442,4500,4557,4612,4667,4720,4773,4824,4874,4924,4972,5019,5066,5112,5156,5200,5243,5285,5327,5367,5407,5446,5485,5522,5559,5595,5631,5666,5700,5734,5767,5799,5831,5863,5893,5924,5953,5983}YATAN_TBUINT16_TX1001建立ATAN的表可以借助MATLAB。在需要插值的场合,比如,上面ATAN_TB的精度为002,而我们希望在少数的一些场合下使ATAN在001的精度,如果以001建表将会使表的数据存储量扩大1倍,这是我们可以在002精度表的基础上再使用插值的方式。比如,要计算ATAN003,我们可以从表中查到ATAN002和ATAN004,如果仅使用线性插值的话,则ATAN003ATAN002ATAN004/2请检查程序的逻辑曾傻傻的写过一个类似下面的程序,UINT8_TDIR//低3位进行了编码,下面的SWITCH进行解码INTDIST_SWITCHINTA,INTB,INTC{INTMAX_DISTINTMIN_DISTINTRESULT0SWITCHDIR{CASE0X00BREAKCASE0X01MAXAMINBBREAKCASE0X02MAXAMINCBREAKCASE0X03MAXBMINABREAKCASE0X04MAXBMINCBREAKCASE0X05MAXCMINABREAKCASE0X06MAXCMINBBREAKCASE0X07BREAKDEFAULTBREAK}RESULTMAX100/MINMAXRETURNRESULT}咋一看,没有语法问题,SWITCH的BREAK语句也加上了。问题出就出在DIR低三位进行了编码,最大编码个数应该是8。而因为实际中只用到6种情况,SWITCH中对其它的两种编码都使用BREAK,问题就出来了,如果我的DIR0X00会怎么样SWITCH语句当然没问题,问题在下一条语句RESULTMAX100/MINMAXDIR0X00没有对MAX和MIN进行任何的赋值,而且其它地方也没有。因此MAX和MIN作为局部变量将会是一个随机的值,这在RAM中是能够运行通过的,但烧写到FLASH之后,这种局部变量的不确定性直接回导致FLASH宕机。因此,对于SWITCH以及IFELSE的逻辑问题,不能只关注它们所在范围,请仔细检查其上下文。请特别关照一下程序中的除法运算XA/B中若B可能为0,这样的程序烧写到FLASH会直接导致DSP死机的。如果可以的话,尽量将除法运算转换为移位运算。比如,要计算YX/002,一个号的转换方式就是YUINT32_TX100/2UINT32_TX1001还可以更好一点,将100也使用移位替代,UINT32_TTMP_XUINT32_TXYTMP_X1这样你就再也看不到除法运算了。/可能原因1程序没有跑起来,程序初始化有问题;2片内程序比仿真运行的快,灯已经闪烁了,但是看不出来,可以用示波器查看。看到好多网友遇到过这样的问题,现在就此问题来收集一下建议和解决方法,有更好的方法,还望大家多多分享。1程序烧到FLASH之后,请用不要断开仿真器,用LOADSYMBOLS将程序加载,然后运行,FLASH在线调试,看看程序跑到什么地方了另外,程序中是否使用DELAY_US函数,此函数是否已经COPY到RAM中执行。STACK的大小开的是否足够看看程序是否进入了什么ILLEGALISR2我也遇到了类似的问题,烧到FLASH里后连着仿真器非常正常,去掉仿真器就有一定的误码率。后来不使用DELAYUS来延时,用定时中断就不会出现这个问题了。DELAYUS在程序里已经SECT“RAMFUNCS“,是不是已经声明为RAM运行还用不用在主程序里做一些处理3请确认是否正确初始化FLASHWAITSTATES,通过以下方法MEMCOPY//CALLFLASHINITIALIZATIONTOSETUPFLASHWAITSTATES//THISFUNCTIONMUSTRESIDEINRAMINITFLASH