您的位置:首页 > 其它

STVD 调试STM8S所遇到的问题

2011-11-02 17:40 253 查看
环境为主控芯片: STM8SF103F3,编译器 COSMIC8,IDE环境为STVD。

大概代码如下:

u8 ret;
ret=rf_get_addr_len();
ret=rf_get_trint_level();
ret=rf_get_drssi_level();
ret=rf_get_dest_provider();
ret=rf_get_addr_len();
使用STLINK进行调试时发现,ret的值根本就不是正确的,我跟踪到具体的函数里面去,检测值是正确的,但为什么赋值给ret后,这个值就不对了呢?

后来google搜后发现一个贴上有说明,内容如下:

一段很简单的代码,跑在ST-DISCOVERY的板子上(实际芯片是STM8S105C6),环境是STVD + COSMIC 4.3.4

float f1 = 3.90, f2 = 2.78, f3 = 0.0;

unsigned int i1 = 3, i2 = 12, i3 = 0;

initMCU(115200);

f3 = f1 * f2;

i3 = i1 * i2;

这样用ST-LINK/SWIM调试下来,结果完全不对:



(原文件名:test1.JPG)
引用图片

貌似i3和f3的值仍然是之前的内存保存的值,感觉像完全没有做乘法一样。

而加上volatile后,

volatile float f1 = 3.90, f2 = 2.78, f3 = 0.0;

volatile unsigned int i1 = 3, i2 = 12, i3 = 0;

initMCU(115200);

f3 = f1 * f2;

i3 = i1 * i2;

再运行,结果就都对了:



(原文件名:test2.JPG)
引用图片

难道COSMIC/STM8S一定要在局部变量上加上volatile?

看了一下编译器设置,好像DEBUG模式下没有任何的优化啊。

有没有TX有ST-DISCOVERY的一起试一下?

本贴被 curahee 编辑过,最后修改时间:2010-04-21,12:01:27.

2010-04-21,12:00:13

资料


邮件


回复


引用回复 ↑↑ ↓↓

















编辑


删除






【1楼】 lianglong

积分:289

派别:

等级:------

来自:
奇怪! 找机会试试

2010-04-21,12:48:08

资料


邮件


回复


引用回复 ↑↑ ↓↓

















编辑


删除






【2楼】 dr2001

积分:1433

派别:

等级:------

来自:
建议检查一下汇编代码。

即便是Debug模式,局部变量,在某些地方,也可能有寄存器优化。此时,数据是在寄存器内,不一定会,或者立即,写回内存。而加了volatile,数据一定会被及时更新到内存。

调试器一般不会管理Reg和自动变量的对应关系,而是直接从内存提取数据信息。这种情况下,就会出问题。

2010-04-21,12:54:37

资料


邮件


回复


引用回复 ↑↑ ↓↓

















编辑


删除






【3楼】 curahee

积分:25

派别:

等级:------

来自:
会不会编译器认为这段代码毫无意义(乘法结果后面都没用到)给咔嚓了?

2010-04-21,13:06:34

资料


邮件


回复


引用回复 ↑↑ ↓↓

















编辑


删除






【4楼】 McuPlayer

积分:471

派别:

等级:------

来自:深圳
优化导致

如果你的某些运算后面没用用到,编译器会帮你把它干掉

如果某个局部表达式后面多次用到,编译器会只在第一次运算,后面的直接使用先前的计算结果

volatile声明此变量是易失的,可以理解为“直接硬件相关”的,所以编译器优化的时候会保持这个变量参与的运算
__________________________

俺的BLOG:http://www.mcuplayer.com

2010-04-21,13:09:14

资料


邮件


回复


引用回复 ↑↑ ↓↓

















编辑


删除






【5楼】 bynce 罗曼



积分:1399

派别:

等级:------

来自:
volatile float f1 = 3.90, f2 = 2.78, f3 = 0.0;

volatile unsigned int i1 = 3, i2 = 12, i3 = 0;

initMCU(115200);

f3 = f1 * f2;

i3 = i1 * i2;

你这个是局部变量?把你完整程序帖出来

2010-04-21,13:20:18

资料


邮件


回复


引用回复 ↑↑ ↓↓

















编辑


删除






【6楼】 curahee

积分:25

派别:

等级:------

来自:
继续,全部代码是这样的,稍作修改:

void main(void)

{

float f1 = 3.90, f2 = 2.78, f3 = 0.0;

unsigned int i1 = 3, i2 = 12, i3 = 0;

initMCU(115200);

f3 = 0.0;

i3 = 0;

f3 = f1 * f2;

i3 = i1 * i2;

while(1)

{

if( i3 > (u16)f3 )

{

LED_ON;

}

else

{

LED_OFF;

}

}

}

如果不加volatile,执行完的结果:



(原文件名:test3.JPG)
引用图片

f3 == f2, i3 == i2 ?? 怎么会连i2和f2的值也会变?

本贴被 curahee 编辑过,最后修改时间:2010-04-21,15:09:53.

2010-04-21,15:07:58

资料


邮件


回复


引用回复 ↑↑ ↓↓

















编辑


删除






【7楼】 curahee

积分:25

派别:

等级:------

来自:
引用图片【6楼】curahee

-----------------------------------------------------------------------



(原文件名:test3.JPG)
引用图片

明白了一点,编译器其实没有错,而且很强大,i3和i2分配在同一个地址,还有f3和f2也分配在同一个地址上。

一分钱是掰成两半花的。

总结,COSMIC很节约,会节省每个字节的FLASH/RAM:

1. 没有用的变量和代码会被和谐掉(见1楼的代码)

2. 可以用一个地址分配的变量一定不会用两个地址空间来分配(见6楼的代码和结果)。

3. 加了volatile会绕过这些优化。

挺好!

原文:http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3988838&bbs_page_no=1&search_mode=3&search_text=curahee&bbs_id=9999
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: