本帖最后由 BinWin 于 2020-8-6 23:32 编辑
STM32G4提供了双BankFlash,支持同时在两个不同的Bank上加载应用程序,用户只需设置一个寄存器就可以实现瞬间切换这两个Bank间的地址,从而实现在线固件升级。安全存储区域可配置大小,用于存放密钥等敏感信息;当退出时可配置为锁定,应用程序无法再读取或调试,适合用于存储关键数据。而且保护固件安全实时升级;编程后调试访问禁用功能可以降低威胁隐患。接下来就来试试这个Flash的在线切换功能。
首先要设计出两个不同的用户程序,在例程基础上修改为这样的:Bank1 中的程序间隔50ms串口发送字符串,LED闪烁。Bank2中的程序间隔1s串口发送字符串,LED闪烁,频率明显不同来区别当前运行的程序。
这里也要借助ST的编程工具STM32CubeProgrammer来烧录bank2区域的用户程序,利用MDK条件编译生成Bin文件供烧录,可以选择这样的配置方式,不讲究路径
编译后就会在工程默认的FLASH_DualBoot.axf同目录下生成bin文件。打开STM32CubeProgrammer,选择好烧录文件,点击编程即可
这部分程序选择地址为0x8040000,接下来继续用MDK烧录0x8000000起始的程序文件。
完成以上步骤,即可看到结果,打开串口助手查看字符串信息,同时观察板卡上的LED灯闪烁的频率,是和串口助手的接受频率一致的。
可以看到时间戳显示间隔1秒钟,说明程序运行正常,此时按下蓝色的按键,会看到如下
此时的频率就快了很多,程序中写的是50毫秒,主循环中的代码部分如下,通过按键触发禁止或使能Bank2启动程序。
while (1)
{
/* Wait for User push-button is released */
if (BSP_PB_GetState(BUTTON_USER) == SET)
{
while (BSP_PB_GetState(BUTTON_USER) == SET);
/* Allow Access to Flash control registers and user Flash */
HAL_FLASH_Unlock();
/* 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 Dual boot configuration status */
HAL_FLASHEx_OBGetConfig(&OBInit);
/* Enable/Disable dual boot feature */
OBInit.OptionType = OPTIONBYTE_USER;
OBInit.USERType = OB_USER_BFB2;
if (((OBInit.USERConfig) & (OB_BFB2_ENABLE)) == OB_BFB2_ENABLE)
{
OBInit.USERConfig = OB_BFB2_DISABLE;
}
else
{
OBInit.USERConfig = OB_BFB2_ENABLE;
}
if(HAL_FLASHEx_OBProgram (&OBInit) != HAL_OK)
{
/*
Error occurred while setting option bytes configuration.
User can add here some code to deal with this error.
To know the code error, user can call function 'HAL_FLASH_GetError()'
*/
/* Infinite loop */
while (1)
{
/* Make LED2 blink (100ms on, 2s off) to indicate error */
BSP_LED_On(LED2);
HAL_Delay(100);
BSP_LED_Off(LED2);
HAL_Delay(2000);
}
}
/* Start the Option Bytes programming process */
if (HAL_FLASH_OB_Launch() != HAL_OK)
{
/*
Error occurred while reloading option bytes configuration.
User can add here some code to deal with this error.
To know the code error, user can call function 'HAL_FLASH_GetError()'
*/
/* Infinite loop */
while (1)
{
/* Make LED2 blink (100ms on, 2s off) to indicate error */
BSP_LED_On(LED2);
HAL_Delay(100);
BSP_LED_Off(LED2);
HAL_Delay(2000);
}
}
/* 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();
}
else
{
#ifdef FLASH_BANK1
/* Toggle LED1 */
BSP_LED_Toggle(LED2);
HAL_UART_Transmit(&hlpuart1,(uint8_t*)"this is bank1",13,5000);
HAL_Delay(50);
#else
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
BSP_LED_Toggle(LED2);
HAL_UART_Transmit(&hlpuart1,(uint8_t*)"this is bank2",13,5000);
HAL_Delay(1000);
#endif
}
}
Demo板载芯片是512K的FLASH,因此双Bank下每个区域也有256K,一般的应用程序搓搓有余,问题来了,假设Bank1程序突发状况进入HardFault中断,可否中断处理中使能Bank2运行程序,从而直接运行备份呢?
|