牛卧堂MCU技术交流

标题: 请教各位大侠一个关于读写data flash的棘手的问题。 [打印本页]

作者: shujianxiaoyao    时间: 2013-12-24 10:39
标题: 请教各位大侠一个关于读写data flash的棘手的问题。
我现在用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   .这里,是什么原因呢?请各位大侠指点指点。

作者: shirley    时间: 2013-12-24 15:32
ARM对访问的地址有对齐的要求
例如:如果访问4个字节,buffer地址需要是4对齐的
keil里面使用__align(4)强制buffer 4对齐
作者: a_ziliu    时间: 2013-12-24 21:45
*_myDstPtr = &temp;  
作者: rejoice818    时间: 2013-12-25 14:47
shirley说得对,注意这点
作者: shujianxiaoyao    时间: 2013-12-26 09:59
shirley 发表于 2013-12-24 15:32
ARM对访问的地址有对齐的要求
例如:如果访问4个字节,buffer地址需要是4对齐的
keil里面使用__align(4)强 ...

谢谢指点,确实是结构体字节对齐的问题,不过我加了__align(4)没用呢,我只能把结构体里类型变量都改为int32_t类型了。
作者: shirley    时间: 2014-2-27 16:18
结构体加了__aligh(4)只能保证结构体是4对齐的,不能保证结构体里面每个变量都是4对齐的




欢迎光临 牛卧堂MCU技术交流 (http://nuvoton-mcu.com/) Powered by Discuz! X3.2