变量被编译器优化掉了

STM32上移植ucosII跑任务的时候,发现程序竟然死掉了,没有运行。程序也比较简单,总共有4个任务,外加一个串口中断,由串口中断控制其中一个任务,然后这个任务启动和关闭另外三个任务。

第一个任务,点亮led1。由任务4创建和删除该任务

     第二个任务,点亮led2。由任务4创建和删除该任务

     第三个任务,点亮led3。由任务4创建和删除该任务

     第四个任务,控制前三个任务,根据串口接收的数据分别创建和删除对应的任务。

 

     其中前三个任务的优先级都比第四个的任务优先级都要高。

4个任务的代码如下:

clip_image002

在任务4的程序中,会等待mode_shaolu的值。当串口接收数据的时候,串口中断程序会使该值改变,然后while不成立,往下执行,根据mode_shaolu的值去执行不同的程序,但是发现,串口数据发后,程序根本就没有执行起来。通过硬件仿真,去跟踪看看是什么地方出问题了。

         clip_image004

硬件仿真,发现mode_shaolu确实因为串口收到数据而改变了,但是while循环,一直跳不出来。这可奇怪了,这明明条件都不符合了。

clip_image006

一看汇编,就发现问题了。mode_shaolu赋值给了r0寄存器。然后就一直判断r0寄存器是不是为0。为0的话,就继续比较,而没有重新载入mode_shaolu的值。所以,当然就造成的效果是while循环一直退不出了。

原来这一切就是编译器优化的问题。在初始的时候,给mode_shaolu赋了一个初值0。但是在程序中没有改变这个值,编译器就自己将这个值给优化成0了。所以就造成上面这个效果了。

所以,我们要让编译器不要自己做这个优化。

 

这有两种方法了,一种是对编译器设置,让编译器编译的时候不要优化。

clip_image008

MDK中,选择优化等级为0

 

第二个方法就是将这个变量添加volatile属性。

即声明变量的时候,前面加volatile,告诉编译器这个变量不要进行任何优化。

clip_image010

 

重新测试。

clip_image012

硬件仿真,程序跳出while循环了。查看生成的汇编代码:

clip_image014

发现汇编代码都变了,先将变量的值载入到r0中,然后比较r00。相等的话,在将变量的值载入到r0中,在比较。这样r0的值就一直是变量的值。

 

在嵌入式的编程中,要注意变量优化的问题。如果编译器对代码优化的话,对一些在外部改变程序的变量,要注意声明为volatile,防止编译器对其进行优化,从而使代码没有实现我们想要的功能。   

 

此条目发表在c/c++, 编程语言分类目录,贴了标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。