烧写Flash后的DSP程序运行不正常的情况分析

AI summary
在调试DSP6713的Flash烧写过程中,发现程序在RAM中正常运行但在Flash中死机的原因包括中断向量表和cmd链接文件的配置、数组越界、使用math.h中的函数、程序逻辑错误、除法运算的处理,以及强制类型转换的问题。建议仔细检查这些方面以避免程序在Flash中运行不正常。
Tags
Dsp Programming
Flash Memory
Debugging Techniques
Last edited by
Last edited time
Sep 23, 2024 02:29 PM
这段时间一直在调试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小节。

请检查cmd链接文件

也不知道什么原因,我曾经在DSP的内部RAM中使用#pragma分配一个3x1024x8字节的区域,在烧写到Flash后运行会死机,
对应的cmd文件为,
把#pragma去掉后就好了,

请检查程序中隐蔽的内存错误

很多情况下,当出现数组越界时,在RAM中的程序都能正常运行,但在烧写Flash后运行就会出现死机或程序跑飞的现象。
比如定义一个数组,
你使用x[5]=10这样的语句在RAM程序中是某些时候能正确运行的,在PC上应该也可以。但将这种程序烧写到Flash之后运行,DSP果断和你说拜拜!
因此,请谨慎地检查程序代码中的数组越界和指针操作。在DSP程序中,坚决不使用C库函数中的malloc函数。如果需要动态分配内存的操作,可以自己写一个,或使用uCOS II或DSP/BIOS等嵌入式操作系统。

请尽量避免使用math.h中的三角及log等函数

也不知道是什么原因,也可能是我对atan函数的使用方法不正确造成的吧。在我的一个最初的程序中,我是直接这样计算atan(x)的,
在RAM中以及在PC中都多次测试过没有任何问题。
烧写Flash之后,也不是死机,但程序运行到atan这个函数的时候会卡上很长一段时间,再接着往下运行。
难道是math.h中的atan运算效率太低?但为什么RAM中就能运行呢?这个还不清楚。
于是想了个招,在要使用三角函数和log等函数的地方都使用查表法替代库函数,在精度要求高而存储空间又有限的场合,可使用查表+插值的方式。
下面是改进方法计算atan,
建立atan的表可以借助Matlab。在需要插值的场合,比如,上面atan_tb的精度为0.02,而我们希望在少数的一些场合下使atan在0.01的精度,如果以0.01建表将会使表的数据存储量扩大1倍,这是我们可以在0.02精度表的基础上再使用插值的方式。
比如,要计算atan(0.03),我们可以从表中查到atan(0.02)和atan(0.04),如果仅使用线性插值的话,则

请检查程序的逻辑

曾傻傻的写过一个类似下面的程序,
咋一看,没有语法问题,switch的break语句也加上了。
问题出就出在:dir低三位进行了编码,最大编码个数应该是8。而因为实际中只用到6种情况,switch中对其它的两种编码都使用break,问题就出来了,如果我的dir=0x00会怎么样?switch语句当然没问题,问题在下一条语句:
dir=0x00没有对max和min进行任何的赋值,而且其它地方也没有。因此max和min作为局部变量将会是一个随机的值,这在RAM中是能够运行通过的,但烧写到Flash之后,这种局部变量的不确定性直接回导致Flash宕机。
因此,对于switch以及if…else…的逻辑问题,不能只关注它们所在范围,请仔细检查其上下文。

请特别关照一下程序中的除法运算

x=a/b中若b可能为0,这样的程序烧写到Flash会直接导致DSP死机的。如果可以的话,尽量将除法运算转换为移位运算。
比如,要计算y=x/0.02,一个号的转换方式就是:
还可以更好一点,将*100也使用移位替代,
这样你就再也看不到除法运算了。

隐藏强制类型转换可能导致的错误

有这么一段代码,
上面的代码直接在DSP内存运行是正常的,但烧写到Flash装载后运行也会在该位置死机,改成如下就好了,
Loading...