OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5718|回复: 7

关于MDK代码优化的问题

[复制链接]

20

主题

100

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
297
金钱
297
注册时间
2012-12-22
在线时间
24 小时
发表于 2016-2-26 16:33:05 | 显示全部楼层 |阅读模式
最近没事干,自己编了个小RTOS,用于M0 M3 M4 M7系列,基本已经成功了,但是发现了一个有关编译器的问题:当MDK开启代码优化:O2 或 O3 时,系统就瘫痪了。
我是用一个时钟程序来测试自己编的这个RTOS的,就是一个钟,显示时间的。使用IAR for ARM 来编译 一切正常,开到最高级别的代码优化,程序依然正常工作,连续测试一个礼拜,一切正常。
但是改用MDK后,问题来了,在O0或O1级别下,一切正常,但是一开到O2,数码管就黑了,整个程序死掉了。
一直苦恼到底是怎么回事,后来发现这个问题:
//宏定义进入临界区:关中断
#define        OS_CRITICAL_ENTER()                do                                                                                \
                                                        {                                                                                \
                                                                OS_INTERRUPT_SHUT();                                        \
                                                                if(OSCriNestNum < 255)        OSCriNestNum++;        \
                                                        }while(0)

//宏定义退出临界区:开中断
#define        OS_CRITICAL_EXIT()                do                                                                                \
                                                        {                                                                                \
                                                                if(OSCriNestNum > 0)        OSCriNestNum--;                        \
                                                                if(OSCriNestNum == 0)        OS_INTERRUPT_OPEN();        \
                                                        }while(0)

同样一段 OS_CRITICAL_EXIT(); 在O0 O1 和 O2 O3两种级别下,编译出来的结果完全不同。。。
O2 O3 级别下 if(OSCriNestNum == 0)        OS_INTERRUPT_OPEN();   完全被编译器去掉了,也就导致 出临界区 没有开中断,上下文就没有办法切换了,所以程序死掉是一定的。
不知道MDK这个代码优化是什么原则,尽然这么歪曲代码的原意。。。难道他认为 先判断了if(OSCriNestNum > 0) 就没必要在判断 if(OSCriNestNum == 0)吗。。。
而且OSCriNestNum 这个全局变量我已经volatile修饰过来,至今我还没有找到可行的办法来不让编译器去优化这第二个if。。。 只能用O1 O0
把这个问题拿出来在论坛里面,大家讨论一下,呵呵!

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

239

帖子

0

精华

高级会员

Rank: 4

积分
545
金钱
545
注册时间
2015-6-5
在线时间
110 小时
发表于 2016-2-26 16:42:39 | 显示全部楼层
用else代替那條判斷試試?
回复 支持 反对

使用道具 举报

20

主题

100

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
297
金钱
297
注册时间
2012-12-22
在线时间
24 小时
 楼主| 发表于 2016-2-26 16:52:44 | 显示全部楼层
Rocks 发表于 2016-2-26 16:42
用else代替那條判斷試試?

那不行啊 意思不对
回复 支持 反对

使用道具 举报

2

主题

239

帖子

0

精华

高级会员

Rank: 4

积分
545
金钱
545
注册时间
2015-6-5
在线时间
110 小时
发表于 2016-2-26 17:26:12 | 显示全部楼层
本帖最后由 Rocks 于 2016-2-26 17:29 编辑

if(OSCriNestNum) --OSCriNestNum;

if(OSCriNestNum == 0) ....

這樣勒
回复 支持 反对

使用道具 举报

20

主题

100

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
297
金钱
297
注册时间
2012-12-22
在线时间
24 小时
 楼主| 发表于 2016-2-26 17:37:55 | 显示全部楼层
Rocks 发表于 2016-2-26 17:26
if(OSCriNestNum) --OSCriNestNum;

if(OSCriNestNum == 0) ....

if(OSCriNestNum)  OSCriNestNum = OSCriNestNum - 1;
都不行
回复 支持 反对

使用道具 举报

2

主题

239

帖子

0

精华

高级会员

Rank: 4

积分
545
金钱
545
注册时间
2015-6-5
在线时间
110 小时
发表于 2016-2-26 17:40:33 | 显示全部楼层
if(OSCriNestNum == 1)
{
OS_INTERRUPT_OPEN();
}else
{
OSCriNestNum--;
}
回复 支持 反对

使用道具 举报

20

主题

100

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
297
金钱
297
注册时间
2012-12-22
在线时间
24 小时
 楼主| 发表于 2016-2-28 12:45:54 | 显示全部楼层
想尽了各种办法也搞不定。。。MDK 和 IAR相比还是逊色了不少,下面是MDK 和 IAR 对  OS_CRITICAL_EXIT();的反汇编结果 都是开最高等级的代码优化,结果却。。。
MDK:
0x000006A4       LDRB     r0,[r1,#0x00]
0x000006A6       CMP      r0,#0x00
0x000006A8       BEQ      0x000006AE
0x000006AA       SUBS     r0,r0,#1
0x000006AC       STRB     r0,[r1,#0x00]

IAR:
0x0800073C     LDRB         R0, [R4]
0x0800073E     CMP          R0, #0
0x08000740     BEQ.N       0x080074C
0x08000742     SUBS         R0, R0, #1
0x08000744     STRB         R0, [R4]
0x08000746     UXTB         R0, R0
0x08000748     CMP          R0, #0
0x0800074A     BNE.N       0x0800074E
0x0800074C     CPSIE        I
可以看到MDK最高优化直接把  if(OSCriNestNum == 0)        OS_INTERRUPT_OPEN(); 这个判断给干掉了。。。
没办法这就是差距,如果要用MDK还必须用汇编去写这段代码。。。真是服气了
或者还是老老实实的不要用代码优化。。。
回复 支持 反对

使用道具 举报

36

主题

256

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2016-4-20
在线时间
169 小时
发表于 2016-10-12 10:22:33 | 显示全部楼层
这个帖子很晚才看到,楼主如果有时间的话用vu 命名 OSCriNestNum变量看看还会不会被优化掉。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-24 02:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表