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

这段时间一直在调试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后运行就会出现死机或程序跑飞的现象。

比如定义一个数组,

int x[5];

你使用x[5]=10这样的语句在RAM程序中是某些时候能正确运行的,在PC上应该也可以。但将这种程序烧写到Flash之后运行,DSP果断和你说拜拜!

因此,请谨慎地检查程序代码中的数组越界和指针操作。在DSP程序中,坚决不使用C库函数中的malloc函数。如果需要动态分配内存的操作,可以自己写一个,或使用uCOS II或DSP/BIOS等嵌入式操作系统。

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

也不知道是什么原因,也可能是我对atan函数的使用方法不正确造成的吧。在我的一个最初的程序中,我是直接这样计算atan(x)的,

float x,y;
...
y = atan(x); // x范围为[0, 1.7]

在RAM中以及在PC中都多次测试过没有任何问题。

烧写Flash之后,也不是死机,但程序运行到atan这个函数的时候会卡上很长一段时间,再接着往下运行。

难道是math.h中的atan运算效率太低?但为什么RAM中就能运行呢?这个还不清楚。

于是想了个招,在要使用三角函数和log等函数的地方都使用查表法替代库函数,在精度要求高而存储空间又有限的场合,可使用查表+插值的方式。

下面是改进方法计算atan,

/* table of determine ATAN(x) */
const float atan_tb[] = {  // 精度(0.020)
0.00, 1.15, 2.29, 3.43, 4.57, 5.71 , 6.84, 7.97, 9.09, 10.20,
11.31, 12.41, 13.50, 14.57, 15.64, 16.70 , 17.74, 18.78, 19.80, 20.81,
21.80, 22.78, 23.75, 24.70, 25.64, 26.57 , 27.47, 28.37, 29.25, 30.11,
30.96, 31.80, 32.62, 33.42, 34.22, 34.99 , 35.75, 36.50, 37.23, 37.95,
38.66, 39.35, 40.03, 40.70, 41.35, 41.99 , 42.61, 43.23, 43.83, 44.42,
45.00, 45.57, 46.12, 46.67, 47.20, 47.73 , 48.24, 48.74, 49.24, 49.72,
50.19, 50.66, 51.12, 51.56, 52.00, 52.43 , 52.85, 53.27, 53.67, 54.07,
54.46, 54.85, 55.22, 55.59, 55.95, 56.31 , 56.66, 57.00, 57.34, 57.67,
57.99, 58.31, 58.63, 58.93, 59.24, 59.53 , 59.83 
};

y = atan_tb[((uint16_t)(x*100)) >> 1];

建立atan的表可以借助Matlab。在需要插值的场合,比如,上面atan_tb的精度为0.02,而我们希望在少数的一些场合下使atan在0.01的精度,如果以0.01建表将会使表的数据存储量扩大1倍,这是我们可以在0.02精度表的基础上再使用插值的方式。

比如,要计算atan(0.03),我们可以从表中查到atan(0.02)和atan(0.04),如果仅使用线性插值的话,则

atan(0.03) = (atan(0.02) + atan(0.04)) / 2

请检查程序的逻辑

曾傻傻的写过一个类似下面的程序,

uint8_t dir;  // 低3位进行了编码,下面的switch进行解码

int dist_switch(int a, int b, int c)
{
    int max_dist;
    int min_dist;
    int result = 0;

    switch (dir) {
    case 0x00: break;
    case 0x01: max=a;min=b;break;
    case 0x02: max=a;min=c;break;
    case 0x03: max=b;min=a;break;
    case 0x04: max=b;min=c;break;
    case 0x05: max=c;min=a;break;
    case 0x06: max=c;min=b;break;
    case 0x07: break;
    default: break;
    }

    result = max * 100 / (min + max);

    return result;
}

咋一看,没有语法问题,switch的break语句也加上了。

问题出就出在:dir低三位进行了编码,最大编码个数应该是8。而因为实际中只用到6种情况,switch中对其它的两种编码都使用break,问题就出来了,如果我的dir=0x00会怎么样?switch语句当然没问题,问题在下一条语句:

result = max * 100 / (min + max);

dir=0x00没有对max和min进行任何的赋值,而且其它地方也没有。因此max和min作为局部变量将会是一个随机的值,这在RAM中是能够运行通过的,但烧写到Flash之后,这种局部变量的不确定性直接回导致Flash宕机。

因此,对于switch以及if...else...的逻辑问题,不能只关注它们所在范围,请仔细检查其上下文。

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

x=a/b中若b可能为0,这样的程序烧写到Flash会直接导致DSP死机的。如果可以的话,尽量将除法运算转换为移位运算。

比如,要计算y=x/0.02,一个号的转换方式就是:

y=(uint32_t)(x*100)/2=((uint32_t)(x*100) >> 1);

还可以更好一点,将*100也使用移位替代,

uint32_t tmp_x = (uint32_t)x;
y = ((tmp_x<<6) + (tmp_x<<5) + (tmp_x<<2)) >> 1;

这样你就再也看不到除法运算了。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: DSP28335是一款数字信号处理器,它有一个内置的闪存(flash)可以用来存储程序代码。如果您想将程序烧写DSP28335的闪存中,可以按照以下步骤进行操作: 1. 准备好烧写工具:您需要一个能够烧写DSP28335闪存的编程器,比如JTAG编程器或者USB编程器。 2. 连接编程器:将编程器连接到DSP28335的JTAG或者USB接口上。 3. 打开烧写软件:启动编程器提供的烧写软件。 4. 设置烧写参数:在烧写软件中设置好DSP28335的型号和闪存大小等参数,以及要烧写的程序文件路径。 5. 烧写程序:按下烧写软件中的烧写按钮,开始烧写程序到DSP28335的闪存中。等待烧写完成。 6. 验证程序:烧写完成后,可以通过读取DSP28335的闪存内容来验证程序是否成功烧写到了闪存中。 请注意,烧写程序到DSP28335的闪存中需要特殊的硬件和软件支持,如果您不了解这方面的知识,建议请专业人士协助操作。 ### 回答2: DSP28335是一种数字信号处理器,可以通过编程控制来实现特定的功能。要将程序烧写FLASH中,我们需要遵循以下步骤: 1. 准备好烧录工具和软件。通常,我们会使用JTAG或USB烧录器来进行烧录。同时,我们还需要选择一款好用的编程软件,比如Code Composer Studio。 2. 确定需要烧写的程序文件。将我们想要烧写的程序文件转化为.hex或.bin格式。 3. 将DSP28335开发板与计算机连接。通过USB或串口连接。 4. 将编程工具与DSP28335开发板进行连接。确保连接的正确性。 5. 打开编程软件,在其中选择需要烧录的程序文件。 6. 配置烧录参数。例如,选择烧录方式,地址,以及擦除范围等等。 7. 进行烧录操作。在烧录前,我们需要确保没有程序正在运行。同时,我们也需要做好备份,避免烧录失败后数据丢失。 烧写完毕后,我们需要进行验证。可以再次运行程序来确认其是否正常工作。同时,我们也可以通过读取FLASH中的数据来验证烧录结果。总的来说,DSP28335烧写程序到FLASH并不难,但是我们需要认真细心地完成每一个步骤,以避免出现错误。 ### 回答3: DSP28335是德州仪器(Texas Instruments)公司推出的一款高性能数字信号处理器(DSP)。在开发DSP28335的过程中,需要烧写程序到Flash中。 首先,在使用DSP28335进行烧写之前,需要安装好烧录器和编程软件。常用的编程软件可以是CodeComposer Studio、IAR、KEIL等。接着,连接DSP28335和电脑,并将烧录器和DSP28335连接。 然后,在编程软件中选择烧写程序的文件,将其编译生成需要烧写的HEX文件。接下来,在编程软件中设置好需要烧写Flash地址和烧录选项。Flash地址包括Flash起始地址、Flash结束地址、Flash地址呈递增顺序、Flash地址写入字位等。 在设置好Flash地址和烧录选项之后,需要将DSP28335处于烧写模式。具体来说,需要在DSP28335上拉低SCI模拟输出端口(SCI_TXD)引脚并保持低电平,然后将DSP28335复位。此时,编程软件会检测到DSP28335处于烧写模式,可以进行烧写操作。 最后,在编程软件中点击“Start Programming”按钮,启动烧写操作。编程软件会将HEX文件中的程序数据逐一写入Flash中,直到写入完成。完成后,将DSP28335退出烧写模式并重启,即可运行烧写的程序。 总的来说,DSP28335烧写程序到Flash的过程主要包括:准备工作、编写程序并生成HEX文件、设置烧写选项和Flash地址、将DSP28335处于烧写模式、烧写程序到Flash中、退出烧写模式并重启。注意在整个烧写过程中,需要保持DSP28335和编程软件的连接稳定,以确保烧写成功。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值