找回密码
 立即注册

QQ登录

只需一步,快速开始

打印 上一主题 下一主题
开启左侧

[M051] 请教各位大侠一个关于读写data flash的棘手的问题。

[复制链接]
跳转到指定楼层
楼主
shujianxiaoyao 发表于 2013-12-24 10:39:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我现在用KEIL调试M058S的项目遇到一个很奇怪的问题,请各位牛人指导一下。
定义有这样的机构体:
typedef struct {
   uint8_t current;
   int16_t accZero[3];
   int16_t magZero[3];
   uint16_t flashsum;
   uint8_t checksum;     
} global_conf_t;

global_conf_t  global_conf;

data flash读写子函数如下:
//************************************************************************
void eeprom_read_block(void *__dst, uint32_t addr, uint16_t __n)
{
          uint32_t *_myDstPtr;
          uint32_t _mySrcPtr;
          uint16_t  count = __n / 4;
          uint32_t  temp;

          if((__n % 4) != 0) count += 1;
                 
         _myDstPtr        =  (uint32_t *)__dst;
         _mySrcPtr        =  addr + 0x01f000;

         
         SYS_UnlockReg();
     _FMC_ENABLE_ISP();

         while(count--)
     {
//                 *_myDstPtr        =  FMC_Read((uint32_t)_mySrcPtr);        
         temp =  FMC_Read((uint32_t)_mySrcPtr);                  //test
                 *_myDstPtr = temp;                                                         // test
                 _myDstPtr++;
                 _mySrcPtr += 4;
     }
   
           _FMC_DISABLE_ISP();
     SYS_LockReg();
}

//*************************************************************************
void  eeprom_write_block(const void *__src, uint32_t addr, uint16_t __n)
{

         uint32_t        _myDstPtr;
         uint32_t        *_mySrcPtr;
         uint16_t   count = __n / 4;

         if((__n % 4) != 0) count += 1;

     _myDstPtr  =  addr + 0x01f000;
         _mySrcPtr  = (uint32_t *)__src;
                 
         SYS_UnlockReg();
     _FMC_ENABLE_ISP();
         if(addr < 512)
           FMC_Erase(0x01f000);
         else if(addr < 1024)
           FMC_Erase(0x01f000 + 512);
         else if(addr < 1536)
           FMC_Erase(0x01f000 + 1024);
         else if(addr < 2048)
           FMC_Erase(0x01f000 + 1536);
         else if(addr < 2560)
           FMC_Erase(0x01f000 + 2048);
         else if(addr < 3072)
           FMC_Erase(0x01f000 + 2560);

         while(count--)
         {
        FMC_Write((uint32_t)_myDstPtr, *_mySrcPtr++);
            _myDstPtr += 4;

         }
         _FMC_DISABLE_ISP();
     SYS_LockReg();
}

在main函数中只要调用以下其中一个函数,都会有异常出现!
  eeprom_read_block((void *)&global_conf, 0, sizeof(global_conf));
   
   eeprom_write_block((const void*)&global_conf, 0, sizeof(global_conf));

比如调用eeprom_read_block((void *)&global_conf, 0, sizeof(global_conf));
跟踪发现
运行到                 *_myDstPtr = temp;                                                         // test
这里的时候马上会异常跳到这里:startup_M051Series.s中
HardFault_Handler_Ret
     ENDIF

                 B       .
                 ENDP
一直死在这 B   .这里,是什么原因呢?请各位大侠指点指点。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 顶 踩
回复

使用道具 举报

沙发
shirley 发表于 2013-12-24 15:32:33 | 只看该作者
ARM对访问的地址有对齐的要求
例如:如果访问4个字节,buffer地址需要是4对齐的
keil里面使用__align(4)强制buffer 4对齐
回复 支持 反对

使用道具 举报

板凳
a_ziliu 发表于 2013-12-24 21:45:09 | 只看该作者
*_myDstPtr = &temp;  
回复 支持 反对

使用道具 举报

地板
rejoice818 发表于 2013-12-25 14:47:04 | 只看该作者
shirley说得对,注意这点
http://smartmcu.com/
http://smartmcu.taobao.com/
回复 支持 反对

使用道具 举报

5#
 楼主| shujianxiaoyao 发表于 2013-12-26 09:59:30 | 只看该作者
shirley 发表于 2013-12-24 15:32
ARM对访问的地址有对齐的要求
例如:如果访问4个字节,buffer地址需要是4对齐的
keil里面使用__align(4)强 ...

谢谢指点,确实是结构体字节对齐的问题,不过我加了__align(4)没用呢,我只能把结构体里类型变量都改为int32_t类型了。
回复 支持 反对

使用道具 举报

6#
shirley 发表于 2014-2-27 16:18:16 | 只看该作者
结构体加了__aligh(4)只能保证结构体是4对齐的,不能保证结构体里面每个变量都是4对齐的
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU