13872|35

59

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

IAR4.42AForSTM32的危险Bug! [复制链接]

在试验SDIO 代码的时候发现了一个明显的运算错误:
  
 
测试环境:

   2G SD 卡, STM32
   IAR Assembler for ARM  4.42A (4.42.1.501)
   编译优化:none
   代码:

   SDIO 的 SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo) 函数;

    ... ... ...

    /* Byte 9 */
    tmp = (u8)((CSD_Tab[2] & 0x00FF0000) >> 16);
    cardinfo->SD_csd.MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5;
    cardinfo->SD_csd.MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2;
    cardinfo->SD_csd.DeviceSizeMul = (tmp & 0x03) << 1;         // 执行后 cardinfo->SD_csd.DeviceSizeMul=0x06
    /* Byte 10 */
    tmp = (u8)((CSD_Tab[2] & 0x0000FF00) >> 8);                 // 执行后 tmp=0xFF
    cardinfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7;        // 执行后 cardinfo->SD_csd.DeviceSizeMul=0x6F
                                                                // 正确的代码应改为  0x07 
    ... ... ...

    跟踪了一下汇编发现,关键的语句是
    ORRS  R3,R3,R2,LSR #7           // 其中 R3=0x06 对应于 cardinfo->SD_csd.DeviceSizeMul
                                    //      R2=0x002DB7FF   对应于 tmp

    错误在于没有对 R2 做取低8位处理,导致 R2 右移将高位数据移到了低8位。

简化程序做了一下试验,下面的三种语句都是一个结果 BB=0x68,显然是不对的。 
   编译优化:none

u8  AA,BB=0;
u32 CC;
    CC = 0x12345678;
    AA = CC >> 8;
    BB |= (AA & 0x80) >> 7;   // BB=0x68

    AA = (u8)CC >> 8;
    BB |= (AA & 0x80) >> 7;   // BB=0x68

    AA = (u8)(CC >> 8);
    BB |= (AA & 0x80) >> 7;   // BB=0x68


显然很危险,问题是如何有效的避免这种Bug 呢?

有IAR高版本的同行可以试验一下,是否改掉了这个错误。

此帖出自stm32/stm8论坛

最新回复

                                 正要对STM的SDIO开工 路过看看林锐的书一直束之高阁还有更多的书被束之高阁被自己的书吓晕了~~~   详情 回复 发表于 2009-2-12 10:55
点赞 关注
 

回复
举报

65

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

不可能吧!

ORRS  R3,R3,R2,LSR #7 前面应该还有条UXTB指令
EWARM5.20上没有问题!
此帖出自stm32/stm8论坛
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

我试过结果是正确的呢。

                                  
此帖出自stm32/stm8论坛
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

4
 

测试的屏幕拷贝

u8  AA,BB;
u32 CC;
    CC = 0x12345678;

    BB =0; 
    AA = CC >> 8;
    BB |= (AA & 0x80) >> 7;
                         // AA=0x56 BB=0x68  错
    BB =0; 
    AA = (u8)(CC >> 8);
    BB |= (AA & 0x80) >> 7;
                        // AA=0x56 BB=0x68  错
此帖出自stm32/stm8论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

5
 

BB |= ((AA & 0x80) >> 7);

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

6
 

LZ用的软件仿真还是硬件仿真器?

                                 我再试仍对。
此帖出自stm32/stm8论坛
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

7
 

看这个AA BB变量

                                 就知道肯定是lz愚蠢的错误
此帖出自stm32/stm8论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

8
 

回答 mcuisp, 软件和硬件单步的结果都是错的

回答 mcuisp, 软件和硬件单步的结果都是错的。
正确的结果 BB的值应该为0x00.

mcuisp 你试验的环境和我一样吗? 包括版本和优化级别
另外, 编译CPU 是 ST STM32F10xxE

楼上老狼提出的使用下面的语句
BB |= ((AA & 0x80) >> 7);
其结果 BB=0x68 仍然是错的
此帖出自stm32/stm8论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

9
 

请注意:局部变量被分配到寄存器,不能在Watch窗口查看中间

Watch窗口始终是显示变量对应的内存中数据的变化,如果在变量参与运算时是在寄存器中进行,则Watch窗口不能反映实际变量数值的变化。

请使用全局变量定义AA和BB,然后再操作结束后再观察Watch窗口。
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

10
 

针对版主的建议的试验结果,仍然不对

我设计了一个全局变量 DD,执行完后仍然不对,代码如下:

static  u8 DD;

int main(void) {

u8  AA,BB;
u32 CC;
    CC = 0x12345678;

    BB =0; 
    AA = CC >> 8;
    BB |= (AA & 0x80) >> 7;
    DD = BB;
                         // AA=0x56 BB=0x68 DD=0x68  错
其实,如果看看汇编的情况,可以估计是编译器的问题
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

11
 

请问,在单步操作过程中,是否看到watch窗口的内容有变化?

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

12
 

DD 变为红色的 0x68

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

90

帖子

0

TA的资源

一粒金砂(初级)

13
 

请打开寄存器窗口,看看各个寄存器的变化

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(中级)

14
 

不好用?

做以下实验
  将CPU 改为STM32F10x ,然后用软仿真,试一下,我的那个语句应该是正确的,如果是这样,说明你可能没有打补丁,去ST下一个吧,或者去万历的网站,因为4.42版本出来的早!(那个升级包有时候不太好用,建议直接下一个5.2的版本,重新装)

 如果还是有问题,建议将软件改为
   u8  AA=0;
   u8  BB=0;
   u8  dd=0;
   u32 CC;
   
    BB=0;
    CC = 0x12345678;
    AA = CC >> 8;
    //BB |= (AA & 0x80) >> 7;      
    dd = (AA & 0x80);   // BB=0x68
    dd=dd>>7;
    BB = BB|dd;   // BB=0x68
    一步步跟踪!
此帖出自stm32/stm8论坛
 
 
 

回复

53

帖子

0

TA的资源

一粒金砂(初级)

15
 

Re

应该和C的整型位操作扩展有关系。没认真学习C标准,不知道标准对这个是怎么规定的。

但是拿8Bit进行计算的时候,有可能编译器会默认扩展到32位去算,位操作,要么强制类型转换,要么就需要去自己与上个东西缩小到合适的范围。

MISRA建议貌似是强制与范围。
此帖出自stm32/stm8论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

16
 

我没有打任何补丁.4.42版,优化None

                                 呵呵,我也想看IAR出错呢。
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

17
 

此问题的阶段小结


1. 下载的V5.3 (32K限制版)同样程序试验,结果OK。 正如2楼所说V5.3编译器在该指令之前加了一个UXTB指令
  UXTB
  ORRS  R3,R3,R2,LSR #7 
2. 同样一段程序在不同版本的编译器下的执行结果不一样,显然是编译器的Bug导致。而不是我们程序的表达问题。
3. 楼上老狼提出的针对4.42A的编译器的补丁,我没有找到。只是看到一些MCU器件扩充的补丁,相信这些补丁不会影响编译Bug。如果有同行发现4.42A的编译器的补丁下载,请通报一下。
4. 楼上的 mcuisp 始终没有验证这个问题,建议你看看汇编代码,是否含有UXTB指令。或者贴上你的调试画面。

Thanks

此帖出自stm32/stm8论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

18
 

同样的程序拷到万利的例子里,出现了楼主所说的Bug

呵呵。
我先前的试验里,AA/BB/CC都被分配到了SRAM里。
而万利的例子AA/BB/CC分别是R4,R5,R6

应该算是IAR的Bug了。
支持楼主!!!
此帖出自stm32/stm8论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

19
 

IAR4.42是有这个问题

我曾经找IAR的工程师确认过了,估计是前期版本的bug,在IAR5.2就好了。

所以说,请大家用最新的编译器咯。
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

20
 

实验了一下,真有这个问题

太可怕了,不知道还有多少编译器隐含的问题。
为避免这类问题不知道在编程上需要注意些什么?
此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表