Questions:擦除页大小不同的内部 FLASH 有何注意事项?
Answer:
AT32F4 全系列内部 FLASH 大小为 256K 及以上的闪存扇区大小是 2K,内部 FLASH 大小小于 256K 的闪存扇区大小是 1K,在擦除时有所区别:
1. 擦除闪存扇区步骤:解锁闪存->擦除闪存扇区->锁定闪存
2. 擦除闪存扇区起始地址(Page_Address)及页内的任何地址都可以将该页擦除
3. 擦除位于 512K 之内的闪存扇区,是操作寄存器 FLASH->CTRL/FLASH->ADDR;擦除位于 512K 及以外的闪存扇区,是操作寄存器 FLASH->CTRL2/FLASH->ADDR2
4. 将闪存扇区大小是 1K 的擦除代码移植到闪存扇区大小是 2K 时,若连续擦除多个闪存扇区,需要将起始地址递增长度改为 2K(0x800)。如果起始地址递增长度还是 1K(0x400),那么一个 2K 的闪存扇区将会被擦除两次。例如,在 IAP 升级 APP 时,一般操作是擦除 1 页,写 1 页。如果页大小 2K 还是按页大小 1K 的擦除代码操作,比如擦除起始地址是 0x08001000 的闪存扇区,第一次会将该页擦除,写入 1K 数据后,第二次擦除长度只增加 1K,写入的起始地址是 0x08001400,那么还是会将该页擦除,将上一次写入的 1K 数据擦除
5. 将闪存扇区大小是 2K 的擦除代码移植到闪存扇区大小是 1K 时,若连续擦除多个闪存扇区,需要将起始地址递增长度改为 1K(0x400)。如果起始地址递增长度还是 2K(0x800),那么每隔一页将会有一页被漏擦除。例如,在 IAP 升级 APP 时,一般操作是擦除 1 页,写 1 页。如果闪存扇区大小 1K 还是按闪存扇区大小 2K 的擦除代码操作,比如擦除起始地址是 0x08001000 的页,将该页 1K 空间擦除,但写入 2K 数据,那么起始地址是 0x08001400 的页在没有被擦除就写入数据,会导致写入的数据错误
由于上述原因,在使用 AT32F413/AT32F415 系列 FLASH 小于 256K 的型号时,需要特别注意 BSP 程序基于该系列最大资源设计(FLASH 大小 256K),直接编译下载可能会造成下载失败或不全片擦除无法二次下载等问题。
此时处理方法如下:
1. 参考 BSP document 路径下《AT32F4xx 固件库 BSP&Pack 应用指南》在 Options 下 Device 修改对应AT32 芯片型号及 FLASH 算法文件
2. 在 Options 下 C/C++预处理 Preprocessor Symbols 的 Define 修改对应芯片型号
3. 如果使用的是 FLASH 读写例程,还需要注意在 flash.c/flash.h 文件中修改对应 SECTOR_SIZE 大小擦除页大小不同的内部 FLASH 注意事项
#define SECTOR_SIZE 2048
擦除程序示例:
flash_unlock();
flash_sector_erase(sector_address);
flash_lock();
其中 flash_sector_erase();函数中针对位于 512K 以内的闪存扇区擦除代码如下:
#define FLASH_BANK1_START_ADDR ((uint32_t)0x08000000) /*!< flash start address of bank1 */
#define FLASH_BANK1_END_ADDR ((uint32_t)0x0807FFFF) /*!< flash end address of bank1 */
if((sector_address >= FLASH_BANK1_START_ADDR) && (sector_address <=
FLASH_BANK1_END_ADDR))
{
/* wait for last operation to be completed */
status = flash_bank1_operation_wait_for(ERASE_TIMEOUT);
if(status == FLASH_OPERATE_DONE)
{
/* if the previous operation is completed, continue to erase the sector */
FLASH->ctrl_bit.secers = TRUE;
FLASH->addr = sector_address;
FLASH->ctrl_bit.erstr = TRUE;
/* wait for operation to be completed */
status = flash_bank1_operation_wait_for(ERASE_TIMEOUT);
/* disable the secers bit */
FLASH->ctrl_bit.secers = FALSE;
}
}
针对位于 512K 及以外的闪存扇区擦除代码如下:
#define FLASH_BANK2_START_ADDR ((uint32_t)0x08080000) /*!< flash start address of bank2 */
#define FLASH_BANK2_END_ADDR ((uint32_t)0x080FFFFF) /*!< flash end address of bank2 */
if((sector_address >= FLASH_BANK2_START_ADDR) && (sector_address <=
FLASH_BANK2_END_ADDR))
{
/* wait for last operation to be completed */
status = flash_bank2_operation_wait_for(ERASE_TIMEOUT);
if(status == FLASH_OPERATE_DONE)
{
/* if the previous operation is completed, continue to erase the sector */
FLASH->ctrl2_bit.secers = TRUE;
FLASH->addr2 = sector_address;
FLASH->ctrl2_bit.erstr = TRUE;
/* wait for operation to be completed */
status = flash_bank2_operation_wait_for(ERASE_TIMEOUT);
/* disable the secers bit */
FLASH->ctrl2_bit.secers = FALSE;
}
}
类型:MCU 应用
适用型号:AT32 全系列
主功能:FLASH
次功能:无