打印

犯了一个低级错误,大家看看是否能雾里看花不迷糊

[复制链接]
8299|43
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
古道热肠|  楼主 | 2009-11-14 11:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下代码由于是临时写成,仅作简单测试,基本能用,后用户反应功能异常,仔细一看,发现其中果然有BUG,晕,特发此贴,给大伙提个醒.除虫高手先别公布答案,让新手先找找.

void WriteFileInfoToEEPROM(uint *uiEEPROMAddress)
{
uint uiTemp;

uiTemp = *uiEEPROMAddress;
EEPROMwrite(uiTemp++,(FDB_Current.DIR_FstClusLO)>>8);
EEPROMwrite(uiTemp++,(FDB_Current.DIR_FstClusLO)&0xff);    //
EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)>>24);
EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)>>16);
EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)>>8);
EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)& 0xff);
*uiEEPROMAddress = uiTemp;
}
#if 0
//Old have a Bug in this Function
void ReadFileInfoFromEEPROM(uint *uiEEPROMAddress)
{
uint uiTemp;

uiTemp = *uiEEPROMAddress;
FDB_Current.DIR_FstClusLO = EEPROMread(uiTemp++)<<8;
FDB_Current.DIR_FstClusLO += EEPROMread(uiTemp++);
FDB_Current.DIR_FileSize = EEPROMread(uiTemp++)<<24;
FDB_Current.DIR_FileSize += EEPROMread(uiTemp++)<<16;
FDB_Current.DIR_FileSize += EEPROMread(uiTemp++)<<8;
FDB_Current.DIR_FileSize += EEPROMread(uiTemp++);
*uiEEPROMAddress = uiTemp;
}

相关结构体定义如下:
/* FAT数据区中文件目录信息 */
typedef struct _FAT_DIR_INFO {
UINT8 DIR_Name[11];    /* 00H,文件名,共11字节,不足处填空格 */
UINT8 DIR_Attr;     /* 0BH,文件属性,参考前面的说明 */
UINT8 DIR_NTRes;     /* 0CH */
UINT8 DIR_CrtTimeTenth;   /* 0DH,文件创建的时间,以0.1秒单位计数 */
UINT16 DIR_CrtTime;    /* 0EH,文件创建的时间 */
UINT16 DIR_CrtDate;    /* 10H,文件创建的日期 */
UINT16 DIR_LstAccDate;    /* 12H,最近一次存取操作的日期 */
UINT16 DIR_FstClusHI;    /* 14H */
UINT16 DIR_WrtTime;    /* 16H,文件修改时间,参考前面的宏MAKE_FILE_TIME */
UINT16 DIR_WrtDate;    /* 18H,文件修改日期,参考前面的宏MAKE_FILE_DATA */
UINT16 DIR_FstClusLO;    /* 1AH */
UINT32 DIR_FileSize;    /* 1CH,文件长度 */
} FAT_DIR_INFO;       /* 20H */
typedef FAT_DIR_INFO *P_FAT_DIR_INFO;
FAT_DIR_INFO idata FDB_Current;  /*文件控制块信息*/

同一入口地址值执行一次写,然后读,居然出错了,您能找到问题吗?

相关帖子

沙发
ejack| | 2009-11-14 11:43 | 只看该作者
默认类型?

使用特权

评论回复
板凳
ejack| | 2009-11-14 11:43 | 只看该作者
什么编译器?基于什么平台?

使用特权

评论回复
地板
原野之狼| | 2009-11-14 11:46 | 只看该作者
bug应该是 对于指针的应用。

使用特权

评论回复
5
yewuyi| | 2009-11-14 13:05 | 只看该作者
重大嫌疑犯:
uiTemp = *uiEEPROMAddress;
....
*uiEEPROMAddress = uiTemp;

uint8
uint16
uint32

使用特权

评论回复
6
古道热肠|  楼主 | 2009-11-14 13:09 | 只看该作者
3# ejack

51平台的Keil -C51编译环境.

使用特权

评论回复
7
yewuyi| | 2009-11-14 13:10 | 只看该作者
uiTemp++估计是个帮凶

使用特权

评论回复
8
古道热肠|  楼主 | 2009-11-14 13:12 | 只看该作者
5# yewuyi
这个用法没有错,将无符号指针型变量的实际值赋给一个无符号整型变量,最后将终结地址值通过指针返回到主调函数.

使用特权

评论回复
9
ejack| | 2009-11-14 13:26 | 只看该作者
3# ejack  

51平台的Keil -C51编译环境.
古道热肠 发表于 2009-11-14 13:09


那么,我答对了吗?

使用特权

评论回复
10
急驰的蚂蚁| | 2009-11-14 15:24 | 只看该作者
本帖最后由 急驰的蚂蚁 于 2009-11-14 15:28 编辑

uiTemp = *uiEEPROMAddress;
*uiEEPROMAddress = uiTemp;

uiTemp在函数里面申请的 属于局部变量 在栈上申请的
退出函数的时候被释放
所以uiEEPROMAddress最后指向一个不确定的地址

是不是这样?

使用特权

评论回复
11
古道热肠|  楼主 | 2009-11-14 15:35 | 只看该作者
10# 急驰的蚂蚁
uiEEPROMAddress是传址方式的入口参数,传入的是一个主调函数给出的真实常量或变量的地址,用*uiEEPROMAddress就是将子程序的某个结果通过指针返回给主调函数.因而与函数内部申请的临时变量uiTemp使用无关.

使用特权

评论回复
12
古道热肠|  楼主 | 2009-11-14 15:36 | 只看该作者
9# ejack
确定吗?

使用特权

评论回复
13
急驰的蚂蚁| | 2009-11-14 15:53 | 只看该作者
本帖最后由 急驰的蚂蚁 于 2009-11-14 15:58 编辑


你的uiEEPROMAddress指向的值都改变了
write和read的参数变量虽然是同一个,但是值不一样了

使用特权

评论回复
14
急驰的蚂蚁| | 2009-11-14 16:02 | 只看该作者
#11 古道热肠

假如最后是这样的话
uiEEPROMAddress = &uiTemp;
就会发生我#10 楼说的情况吧

使用特权

评论回复
15
yewuyi| | 2009-11-14 16:15 | 只看该作者
5# yewuyi  
这个用法没有错,将无符号指针型变量的实际值赋给一个无符号整型变量,最后将终结地址值通过指针返回到主调函数.
古道热肠 发表于 2009-11-14 13:12


老大,你定义的函数是void好不好?!你返回什么啊你?!如果在函数里面开辟的局部变量地址被覆盖了,返回的值能对吗?!

使用特权

评论回复
16
急驰的蚂蚁| | 2009-11-14 16:25 | 只看该作者
#15
他的这个用法没错
uiEEPROMAddress在主函数应该初始化了,指向一个确定的地址了
只是把uiEEPROMAddress指向的变量的值改变了而已
而指针没有变

使用特权

评论回复
17
古道热肠|  楼主 | 2009-11-14 17:14 | 只看该作者

你的uiEEPROMAddress指向的值都改变了
write和read的参数变量虽然是同一个,但是值不一样了
急驰的蚂蚁 发表于 2009-11-14 15:53

哈哈,没找准虫穴的方向

相关主调部分如下:

uint uiEEPROMAddress;   //EEPROM地址记数器
uchar ucCount;     //播报的语音文件总数
......
while(ucRepeatCount--)
{
  ucAddressCount = 4;
  uiEEPROMAddress = 0x100;  //EEPROM地址记数器
  ucCount = 0;     //播报的语音文件总数

......
      #if Module_Current_PlayFileFormat_CFG == c_PlayFileFormat_WAV
       strcpy(ucFileNameBuf,"点.WAV");
      #else
       strcpy(ucFileNameBuf,"点.mp3");
      #endif        
      ucStatus = FindFileInSubDir(c_FindMode_FileName,1,ucFileNameBuf);
      if(ucStatus == ERR_SUCCESS)
      {
//        PlayMusicMain();
       WriteFileInfoToEEPROM(&uiEEPROMAddress);
       ucCount++;
      }
      else
      {      
       #if(c_DBU_Info)
        printf("err Value is %d\n",(uint)ucStatus);
       #else
        ComShowString("Find File Fail!\n");
       #endif
      }

......

#if 1  
  uiEEPROMAddress = 0x100;
  while(ucCount--)
  {
   ReadFileInfoFromEEPROM(&uiEEPROMAddress);
   PlayMusicMain();
  }
#endif

初始化肯定会做的.写和读分开来的,EEPROM就是个临时中转站而已.

使用特权

评论回复
18
xwj| | 2009-11-14 20:45 | 只看该作者
很明显的BUG,而且这样写估计效率很低。

提示:
溢出

使用特权

评论回复
19
因特网用户| | 2009-11-14 21:45 | 只看该作者
肠子的代码风格不错

使用特权

评论回复
20
古道热肠|  楼主 | 2009-11-15 10:39 | 只看该作者
呵呵,大家按18楼老X的提示去找,很快能找到.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:以VS1003B和山景SOC芯片为背景,倾心研制数字化语音录放产品. 排忧邮箱:xg_2004_sy@126.com 得意之作是做了个AVR高压编程器,用起来爽歪歪, 串口MP3录放音模块,全面进入数字录放音时代

284

主题

6411

帖子

16

粉丝