在试验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高版本的同行可以试验一下,是否改掉了这个错误。
|