【发布时间】:2026-01-19 08:20:02
【问题描述】:
我正在尝试使用 ST32 H743ZI2 进行银行交换。我浪费了很多时间来修复它,但我没有得到它。也许是因为我是 STM32 控制器的新手。
我从 STM32CubeH7 固件示例中复制了银行交换代码,并对 CubeMX 中的 gpio 配置进行了一些修改。我这样做是因为我想将代码包含在没有 stm32h7xx_nucleo 标头的现有项目中。
遵循 Bank1 的代码:
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
while (1)
{
/* Wait for BUTTON_USER is released */
if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == 1)
{
while (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == 1);
/* Get the Dual boot configuration status */
HAL_FLASHEx_OBGetConfig(&OBInit);
/* Get FLASH_WRP_SECTORS write protection status */
OBInit.Banks = FLASH_BANK_1;
HAL_FLASHEx_OBGetConfig(&OBInit);
/* Check Swap FLASH banks status */
if ((OBInit.USERConfig & OB_SWAP_BANK_ENABLE) == OB_SWAP_BANK_DISABLE)
{
/*Swap to bank2 */
/*Set OB SWAP_BANK_OPT to swap Bank2*/
OBInit.OptionType = OPTIONBYTE_USER;
OBInit.USERType = OB_USER_SWAP_BANK;
OBInit.USERConfig = OB_SWAP_BANK_ENABLE;
HAL_FLASHEx_OBProgram(&OBInit);
/* Launch Option bytes loading */
HAL_FLASH_OB_Launch();
/*
as the CPU is executing from the FLASH Bank1, and the I-Cache is enabled :
Instruction cache must be invalidated after bank switching to ensure that
CPU will fetch correct instructions from the FLASH.
*/
SCB_InvalidateICache();
HAL_NVIC_SystemReset();
}
else
{
/* Swap to bank1 */
/*Set OB SWAP_BANK_OPT to swap Bank1*/
OBInit.OptionType = OPTIONBYTE_USER;
OBInit.USERType = OB_USER_SWAP_BANK;
OBInit.USERConfig = OB_SWAP_BANK_DISABLE;
HAL_FLASHEx_OBProgram(&OBInit);
/* Launch Option bytes loading */
HAL_FLASH_OB_Launch();
/*
as the CPU is executing from the FLASH Bank1, and the I-Cache is enabled :
Instruction cache must be invalidated after bank switching to ensure that
CPU will fetch correct instructions from the FLASH.
*/
SCB_InvalidateICache();
}
}
else
{
#ifdef FLASH_BANK1
/* Toggle LED1 */
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
/*Turn Off LED2*/
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, 0);
#else
/* Toggle LED2 */
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_1);
/* Turn off LED1 */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, 0);
#endif
/* Insert 100 ms delay */
HAL_Delay(100);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
bank1 和bank2 的代码是相同的,除了链接描述文件。 我将 Flash 分成两个区域,每个区域有 1024kb。在下面你可以看到bank1的代码。
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
}
在 bank2 的链接脚本中,我将闪存起始地址更改为 0x08100000。
现在我有以下问题。如果我加载 bank1 的订单代码和 bank2 的代码,请按 Button1 并按 Reset 按钮,我会收到以下错误消息:
在没有可用调试信息或程序代码之外的地址“0x81006fe”处中断。
我已经用STM32 Utility成功检查了是否放置了一些代码。
如果我以相反的顺序加载代码,银行就会被交换一次。如果 Button1 在系统重置之前被按下,则独立..
我已经检查了一些论坛,但没有成功。
有谁知道问题出在哪里?
【问题讨论】:
-
您确定在交换银行时应该更改链接描述文件吗?我的意思是银行交换的意思是根据OB中的交换位将它们重新定位到相同的地址。
-
我完全不确定。在 STM32 的示例中,他们更改了链接描述文件。我认为这是为了在启动时将向量表重新定位到所选银行的起始地址。我理解的方式是只有虚拟地址发生变化。
-
但是在这种情况下,您应该将所有源代码编译为与位置无关的代码,否则所有绝对跳转都会失败。对我来说这听起来有点奇怪。
-
@Damiano 我将自己定位于 STM32 手册,例如 STM32H7-Flash。在第 6 页有 STM32H743 的内存布局。我可以把虚拟地址和物理地址混在一起吗...
-
阅读 AN4826 我很确定内存中的闪存组地址已被交换。因此,如果不将闪存大小减半,则不应更改链接描述文件。不知道您找到的示例的用途是什么。试试看。
标签: stm32 swap flash-memory bank