你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
leekuip 提问时间:2021-11-17 13:42 / 未解决
我用的芯片是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;
}


收藏 评论4 发布时间:2021-11-17 13:42

举报

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


我先擦除BANK2的12~16区,然后写入数据0x12345678在这些区。接着我又擦除了第13区重新写入数据为0xaa5588ff,


结果一切正常。 你确认下地址给对没有,是否配置为双BANK区了。这里有参考例程 STM32Cube_FW_F7_V1.16.1\Projects\STM32F769I-Discovery\Examples\FLASH\FLASH_EraseProgram可以参考下。
xmshao 回答时间:2021-11-18 13:56:38

我今天上午测试过了F769的开发板,是可以基于扇区擦或写的。

image.png

image.png

你注意开启了双BANK,然后地址给对。被写的地方擦除过了。

ju+(春) 回答时间:2021-11-19 09:57:08

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启动

以下是我遇到过的问题,我做过STM32L496VGT6和STM32F439ZGT6的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) &amp; (FLASH_OPTCR_BFB2)) /* BANK1 active for boot */
{
   AdvOBInit.BootConfig = OB_DUAL_BOOT_DISABLE;
   AdvOBInit.OptionType = OPTIONBYTE_BOOTCONFIG;//用于触发选项字节   读的时候不需要 仅仅在修改的时候需要
   result =  HAL_FLASHEx_AdvOBProgram(&amp;AdvOBInit);
   DUALBANK_PRINTF("((AdvOBInit.BootConfig) &amp; (FLASH_OPTCR_BFB2)) == 1 \r\n");
}
else
{
   AdvOBInit.BootConfig = OB_DUAL_BOOT_ENABLE;

    AdvOBInit.OptionType = OPTIONBYTE_BOOTCONFIG;//用于触发选项字节   读的时候不需要 仅仅在修改的时候需要
    result =  HAL_FLASHEx_AdvOBProgram(&amp;AdvOBInit);

    DUALBANK_PRINTF("((AdvOBInit.BootConfig) &amp; (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; }

leekuip 回答时间:2021-11-22 13:54:43

xmshao 发表于 2021-11-18 13:51
你首先要通过选项配置为双bank模式,然后就可以操作了。我今天找了F769的开发板进行测试,没有问题。</p>
<p>

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

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版