1
votes

I am trying to do a bank swap with the ST32 H743ZI2. I wasted much of time to fix it but I didn't get it. Maybe because I'm new in STM32 controllers.

I copied the bank swap code from STM32CubeH7 Firmware Examples and did a few modifications regarding to gpio configuration in CubeMX. I did them because I want to implicate the code in a existing project without the stm32h7xx_nucleo headers.

Following the Code for 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 */
}

The code for bank1 and bank2 are equal except linkerscript. I split Flash in two areas which have 1024kb each. In following you can see the code for 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
}

In linkerscript for bank2 I changed flash start address to 0x08100000.

Now I have following problem. If I load in order code for bank1 and code for bank2 press the Button1 and Press the Resetbutton I get following error message:

Break at address "0x81006fe" with no debug information available, or outside of program code.

I already successfully checked if there is placed some code with STM32 Utility.

If I load the codes in reverse order the banks get swapped once. Independently if Button1 gets pressed before system reset or not..

I already checked some forums without success.

Does anyone know where the problem could be?

1
Are you sure that you should change the linker script if you swap banks? I mean the meaning of bank swapping is to relocate them at the same address depending on the swap bit in the OB.Damiano
I'm not sure at all. In example of STM32 they changed the linker script. I thinks it's for relocating the vector table to start address of selected bank while boot from. The way I understood it is there are only changes in the virtual address.scheinwerfer
But in this case you should compile all the sources as position independent code, otherwise all absolute jumps will fail. It sounds a little strange to me.Damiano
@Damiano I oriented myself on stm32 manuals like the STM32H7-Flash. On page 6 there's a memory layout of STM32H743. May I mixed up virtual and physical address...scheinwerfer
Reading AN4826 I'm quite sure that flash banks addresses in memory are swapped. So you should not change the linker script if not to halve flash size. Don't know what the example you found is intended for. Try it.Damiano

1 Answers

1
votes

There were two problems in code.

  1. Linker script was splited up in two parts. Linker script had to rebuild in original state regarding to flash. The code for bank2(0x081000000) needs to locate with an extern software like stm32 utility now.

  2. Vector table was relocate at wrong address in system_stm32h7xx.c