我使用的是GD32E230芯片,在进行写flash时一致无法成功写入,先贴代码
uint8_t WriteToFlash(uint16_t SIZE_VAR, uint32_t *Data, uint32_t start_addr, uint32_t end_addr) { fmc_state_enum EarseStatus = FMC_READY; /* 擦除或写入的页数页数 */ uint32_t PageNum = (end_addr - start_addr) / FLASH_PAGE_SIZE; uint32_t EEAddress = start_addr; __disable_irq(); fmc_unlock(); /* 擦除FLASH */ GD_FlashErase(start_addr, PageNum); /* program flash */ while(EEAddress < (start_addr + SIZE_VAR)){ fmc_word_program(EEAddress, *Data); switch(EarseStatus) { case FMC_READY: { EEAddress = EEAddress + 4; Data ++; break; } case FMC_BUSY: { /* 重新写入 */ break; } case FMC_PGERR: case FMC_WPERR: case FMC_TOERR: default: break; } fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR ); } /* lock the main FMC after the program operation */ fmc_lock(); __enable_irq(); return 1; }调用是这样调用的
WriteToFlash(sizeof(UserData),(uint32_t *)&userData,FLASH_CONFIG_START_ADDR,FLASH_CONFIG_END_ADDR);在调试时一运行至fmc_word_program(EEAddress, *Data);就进入了HardFault_Handler();
经过排查,
1,FLASH_CONFIG_START_ADDR的地址和FLASH_CONFIG_END_ADDR都在合法范围内;
2,在进行写flash操作时关闭了中断__disable_irq();
结果依然会进HardFault_Handler();又查到要写入的结构体必须四字节对齐,本来结构体是这样写的:
typedef struct { uint16_t default_flag; uint16_t random_data; }SFlashData; typedef struct { SFlashData flashdata; uint16_t Crc; }UserData;然后改为:
typedef struct { uint16_t default_flag; uint16_t random_data; }SFlashData; typedef struct { SFlashData flashdata; uint16_t Crc; uint16_t reserve; }UserData;以为这样就4字节对齐了,但是问题依然没有解决,后来查到这样只是2字节对齐不是4字节对齐,于是改为:
typedef struct { uint16_t default_flag; uint16_t random_data; }SFlashData; typedef struct { SFlashData flashdata; uint16_t Crc; uint16_t reserve; }__attribute__((aligned(4)))UserData;这样就确保结构体是4字节对齐了,问题也终于解决了!