久芯网

STM32F765使用Dual bank模式,bank2无法擦除

avatar leekuip 提问时间: 2023-08-17 15:45:45 / 未解决
我用的芯片是STM32F765VGT6,内部flash大小是1M,配置为了dual bank模式,现在参照STM32F767ZI-Nucleo的flash擦写例程,对bank1可以正常擦写,bank2只能在整片擦除后才能写,无法对单个扇区进行擦除。找不到问题在哪里,求助一下大家。

相关代码如下:

HAL_FLASH_Unlock();

HAL_FLASH_OB_Unlock();
FlashErasePage(ADDR_APP_DATA_PAGE1);
FlashWriteByte(ADDR_USER_DATA_INIT_FLAG1,pData,USER_DATA_NUM);
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();


uint32_t STMFLASH_GetFlashSector(u32 addr)
{
  if(addr<ADDR_FLASH_SECTOR_1)return FLASH_SECTOR_0;
  else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_SECTOR_1;
  else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_SECTOR_2;
  else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_SECTOR_3;
  else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_SECTOR_4;
  else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_SECTOR_5;
  else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_SECTOR_6;
  else if(addr<ADDR_FLASH_SECTOR_12)return FLASH_SECTOR_7;
  else if(addr<ADDR_FLASH_SECTOR_13)return FLASH_SECTOR_12;
  else if(addr<ADDR_FLASH_SECTOR_14)return FLASH_SECTOR_13;
  else if(addr<ADDR_FLASH_SECTOR_15)return FLASH_SECTOR_14;
  else if(addr<ADDR_FLASH_SECTOR_16)return FLASH_SECTOR_15;
  else if(addr<ADDR_FLASH_SECTOR_17)return FLASH_SECTOR_16;
  else if(addr<ADDR_FLASH_SECTOR_18)return FLASH_SECTOR_17;
  else if(addr<ADDR_FLASH_SECTOR_19)return FLASH_SECTOR_18;
  return FLASH_SECTOR_19;
}
HAL_StatusTypeDef FlashErasePage(u32 addr)
{
  u32 SectorError=0;
  FLASH_EraseInitTypeDef FlashEraseInit;
  HAL_StatusTypeDef FlashStatus;

  FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;       //擦除类型,扇区擦除
  FlashEraseInit.Sector=STMFLASH_GetFlashSector(addr);   //要擦除的扇区
  FlashEraseInit.NbSectors=1;                             //一次只擦除一个扇区
  FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;      //电压范围,VCC=2.7~3.6V之间!!
  FlashStatus = HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError);
  if(FlashStatus != HAL_OK)
  {
    return FlashStatus;
  }
  SCB_CleanInvalidateDCache();                            //清除无效的D-Cache

  return FlashStatus;
}



如需获得 STM32F765 等器件的更多信息,请点击链接或 点击此处 联系在线客服!

4个回答
  • avatar xmshao
    回答时间: 2023-08-17 16:05:53

    你首先要通过选项配置为双bank模式,然后就可以操作了。我今天找了F769的开发板进行测试,没有问题。 我先擦除BANK2的12~16区,然后写入数据0x12345678在这些区。接着我又擦除了第13区重新写入数据为0xaa5588ff, 结果一切正常。 你确认下地址给对没有,是否配置为双BANK区了。这里有参考例程 STM32Cube_FW_F7_V1.16.1\Projects\STM32F769I-Discovery\Examples\FLASH\FLASH_EraseProgram可以参考下。

  • avatar xmshao
    回答时间: 2023-08-17 16:25:06

    我今天上午测试过了F769的开发板,是可以基于扇区擦或写的。 你注意开启了双BANK,然后地址给对。被写的地方擦除过了。

  • avatar ju+(春)
    回答时间: 2023-08-17 16:42:29

    1/先确认你的Flash到底是1M的还是2M的,根据芯片型号判断不准,需要先根据寄存器,读取到Flash的大小,如果是1M的,需要先1M的Flash切换为2个5K的双bank的Flash,然后再去手册找到2个bank时候,每个扇区的大小,然后在往Bank2区域擦鞋数据,最后写完成后设置为DualBank模式,从Bank2启动 2/如果你的芯片型号是1M的,实际寄存器读出来是2M的,此时不需要切分Flash,那你需要根据2M的Flash方式查找第2个Bank的起始地址,然后再去擦写数据做测试,最后再切换为Dualbank模式,从bank2启动 以下是我遇到过的问题,我做过STM32L496VGT6STM32F439ZGT6的DualBank切换,其中STM32L496VGT6是1M的,每个扇区都是均匀的大小,不牵扯到需要把1M切换为2个5K的DualBank Flash,所以都是直接往第2个区域擦写数据,然后开启DualBank让他从Bank2启动 的。但是当我用STM32F439ZGT6是1M的Flash,我却怎么也无法实现Dual Bank功能,发现此时1M的Flash在单bank模式下和Dual Bank模式下Flash分区时完全不一样的,我需要上电第1不先把Flash强制设置为Dual Bank的Flash(注意此处是对Flash切换为Dual Bank方式,并不是激活Dual Bank启动功能),所有操作都实现以后,但却仍然无法实现功能,类似于楼主所说的往Flash写数据,写成功了,但实际查看地址却没有数据,于是各种检查各种尝试都不行,我快要放弃的时候,突然发现我在上电的时候读寄存器读到的Flash大小是2M的,和芯片型号对不上,于是乎我再按照2M的Flash方式查看之前1M时候写的数据与2M时候的扇区号对上了,我才知道,原来我写的扇区号是2M的,后续我都按照2M的Flash大写去操作Dual Bank功能,上电检查一下当前是运行在Bank2还是Bank1,并要检查是否激活了Dual Bank功能,(如果是1M的,应该还要开启Duak Bank Flash功能),以下是Bsp_FlashDualBank_Check是上电Duak bank状态检查,擦写完Flash后最后在通过FLASH_If_BankSwitch函数,交换启动Bank区域 void Bsp_FlashDualBank_Check(void) { FLASH_AdvOBProgramInitTypeDef AdvOBInit; LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);// __HAL_RCC_SYSCFG_CLK_ENABLE(); / Test from which bank the program runs / / SYSCFG_MEMRMP bit8 (FB_MODE) 0-bank1 /1-bank2 Start / if(LL_SYSCFG_GetFlashBankMode()==LL_SYSCFG_BANKMODE_BANK1) //0-bank1映射在0x800000 1-bank2映射在0x800000 { DualBank.CurrentBank = DUAL_BANK1; DUALBANK_PRINTF("MEMRMP(FB_MODE bit8=0) Running from Bank1 "); } else { DualBank.CurrentBank = DUAL_BANK2; DUALBANK_PRINTF("MEMRMP(FB_MODE bit8=1) Running from Bank2 "); } / Get the Dual boot configuration status / //AdvOBInit.OptionType = OPTIONBYTE_BOOTCONFIG;//用于触发选项字节 读的时候不需要 仅仅在修改的时候需要 HAL_FLASHEx_AdvOBGetConfig(&AdvOBInit); / Enable/Disable dual boot feature / if (((AdvOBInit.BootConfig) & (FLASH_OPTCR_BFB2)) == FLASH_OPTCR_BFB2) { DualBank.Active = DUALBANK_ACTIVE; DUALBANK_PRINTF("System ROM bank active \r\n"); } else { DualBank.Active = DUALBANK_INACTIVE; DUALBANK_PRINTF("System ROM bank deactivated\r\n"); } } /** @brief Modify the BFB2 status of user flash area. @param none @retval HAL_StatusTypeDef HAL_OK if change is applied. */ HAL_StatusTypeDef FLASH_If_BankSwitch(void) { FLASH_AdvOBProgramInitTypeDef AdvOBInit; HAL_StatusTypeDef result; LL_SYSCFG_SetFlashBankMode(LL_SYSCFG_BANKMODE_BANK2); HAL_FLASH_Unlock();//HAL_FLASH_Lock(); // / Clear OPTVERR bit set on virgin samples / // __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); / Allow Access to option bytes sector / HAL_FLASH_OB_Unlock(); / Get the current configuration / HAL_FLASHEx_AdvOBGetConfig(&AdvOBInit); if((DualBank.CurrentBank == DUAL_BANK2)||((DualBank.CurrentBank == DUAL_BANK1)&&(DualBank.Active != DUALBANK_ACTIVE))) { DUALBANK_PRINTF("CurrentBank "); if ((AdvOBInit.BootConfig) & (FLASH_OPTCR_BFB2)) /* BANK1 active for boot */ { AdvOBInit.BootConfig = OB_DUAL_BOOT_DISABLE; AdvOBInit.OptionType = OPTIONBYTE_BOOTCONFIG;//用于触发选项字节 读的时候不需要 仅仅在修改的时候需要 result = HAL_FLASHEx_AdvOBProgram(&AdvOBInit); DUALBANK_PRINTF("((AdvOBInit.BootConfig) & (FLASH_OPTCR_BFB2)) == 1 \r\n"); } else { AdvOBInit.BootConfig = OB_DUAL_BOOT_ENABLE; AdvOBInit.OptionType = OPTIONBYTE_BOOTCONFIG;//用于触发选项字节 读的时候不需要 仅仅在修改的时候需要 result = HAL_FLASHEx_AdvOBProgram(&AdvOBInit); DUALBANK_PRINTF("((AdvOBInit.BootConfig) & (FLASH_OPTCR_BFB2)) == 0 \r\n"); } if (result == HAL_OK) { HAL_FLASH_OB_Launch(); } } /* Prevent Access to option bytes sector */ HAL_FLASH_OB_Lock(); / Disable the Flash option control register access (recommended to protect the option Bytes against possible unwanted operations) / HAL_FLASH_Lock(); DUALBANK_PRINTF("....SwappingBank OK............\r\n............\r\n"); / Initiates a system reset request to reset the MCU / HAL_NVIC_SystemReset(); return result; }

  • avatar leekuip
    回答时间: 2023-08-17 17:11:03
    xmshao 发表于 2021-11-18 13:51
    你首先要通过选项配置为双bank模式,然后就可以操作了。我今天找了F769的开发板进行测试,没有问题。

    谢谢,已经解决了,后来查的发现是单片机型号焊接的不对,焊接的是2M flash的。好一番折腾,,,,

会员中心 微信客服
客服
回到顶部