CODECOMPOSER: 使用定时器进行延时操作时循环无法退出

Part Number: CODECOMPOSER
Other Parts Discussed in Thread: MSP430FR2476

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <msp430fr2476.h>
#define CPU_F ((unsigned long int) 2000000)
#define delay_us(x) __delay_cycles(CPU_F * x / ((unsigned long int)1000000))
#define delay_ms(x) __delay_cycles(CPU_F * x / ((unsigned long int)1000))
#define delay_s(x) __delay_cycles(CPU_F * x / ((unsigned long int)1))
unsigned long int global_sec_count = 0;
//unsigned long int sec_start;
unsigned char timer1_cfg()
{
TA1CTL &= 0xFFCF; // stop
TA1CTL |= 0x0004; // clear
TA1CTL = 0x01C0; // other
TA1CCTL0 = 0x0000;
TA1CCR0 = 0x0200; // 32768 / 8 / 8
TA1EX0 = 0x0007;
TA1CTL |= 0x0010; //up mode
TA1CTL |= 0x0002; // enable interrupt
return 0;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

开发环境:

Code Composer Studio 12.4.0.00007

目标平台MSP430FR2476

能够复现问题的代码如上所示。该代码的期望功能是初始化MSP430FR2476,然后开启定时器,定时器每隔1秒钟将global_sec_count的值增加1。之后使用sec_start记录当前global_sec_count的值(因为定时器刚开启,所以sec_start应该为0),在while循环时每隔1秒检测sec_start和global_sec_count的差值,当二者差值超过3,即经过3秒后,结束循环,执行后续代码。

实际执行情况是:

现象1、如果使用在线调试工具让代码自动执行,会发现程序无法跳出循环。暂停程序运行后会发现sec_start的高16位值被改变,使得sec_start的值从正确的值0变为一个随机的值(如图所示为0xE6730000)。此时即使global_sec_count已经大于4(如图所示为7),会仍然在进行循环。

现象2、如果使用仿真器在循环内单步执行程序,sec_start的值能够保持为0,但是即使global_sec_count已经大于4(如图所示为7),会仍然在进行循环。

现象3、如果将77行代码的unsigned long int sec_start;修改为signed long int sec_start;,即将sec_start定义为有符号的长整型,程序就能正确跳出while循环。

现象4、如果将sec_start定义为全局变量,仍然保持其为unsigned long int格式,程序也能正确跳出while循环。

现象5、如果在循环内部调用一个理论上不影响循环的函数(例如代码中的dummy_func()),程序也能正确跳出while循环。

从代码来看现象1和现象2不应该出现,同时在现象3-现象5的情况下解决BUG的问题也很异常。

  • 已经收到了您的案例,调查需要些时间,感谢您的耐心等待。

  • 您好

    现象1、如果使用在线调试工具让代码自动执行,会发现程序无法跳出循环。暂停程序运行后会发现sec_start的高16位值被改变,使得sec_start的值从正确的值0变为一个随机的值(如图所示为0xE6730000)。此时即使global_sec_count已经大于4(如图所示为7),会仍然在进行循环。

    我假设已启用-O0(寄存器级)优化。您能否尝试完全禁用优化(设置为-Ooff),以便sec_start位于RAM中?然后看看程序是否按预期运行。

  • 上述结果是在已启用-O0(寄存器级)优化时的现象。完全禁用优化(设置为-Ooff)后,sec_start被分配到0x003FF8地址处,程序能够正常跳出循环,按照预期运行。

    但是我实际项目中的代码量比较大,为了能让程序运行在MSP430FR2476上,我编译的时候是开启O2级别优化以减小程序存储器占用的。

    在开启O2级别优化的情况下,在现象1、2的条件下程序无法退出循环,和O0优化级别相同;在现象5的条件下程序可以退出循环,和O0优化级别相同;但是在现象3、4的条件下程序变得无法退出循环。因为开启O2优化后“Variables”窗口已经无法显示sec_start的数值,所以无法确认其内容是否正确。

    有没有办法在不禁用优化的情况下修复这个问题呢?

  • 这个是链接里需要的文件。

    bug_report.zip

  • 您好

    谢谢你的测试用例。我把它编译成汇编代码。我看到了一些似乎不对劲的东西。我会提交一份条目并回复您。

  • 您好

    EXT_EP-12754

    该条目目前描述模糊且不够准确。在错误得到明确描述后,我们会改进此条目。