1

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?

VC.One
  • 14,790
  • 4
  • 25
  • 57
  • 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 Aug 23 '21 at 13:50
  • 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 Aug 23 '21 at 14:48
  • 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 Aug 24 '21 at 06:37
  • @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 Aug 24 '21 at 07:25
  • 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 Aug 24 '21 at 08:46
  • @Damiano It's look like a other description for the example I use. I changed both linkerscripts back to flash address 0x08000000 and size to 2048kb. I load Bank2 Application with STM32 Utility at address 0x081 and Application for Bank1 with STM32 Cube IDE to 0x08. The swap from Bank1 to Bank2 is working now but i get a hard fault after first bank swap. I analyzed the hard fault und STM32Cube Programmer tells me its a "Failed integrity check on exception return (INVPC)". I reproduced the hard fault while debuging in CubeIDE there I jump in the NMI_Handler... I'm a little confused – scheinwerfer Aug 24 '21 at 10:00
  • have you checked the contents of the two banks? Do you see the vector table on the start of both banks? The addresses inside the vector table are correct (both of them should point to the the lower half of the flash memory) – Damiano Aug 24 '21 at 11:35
  • I checked both banks for their value. At wich time the vector table have to point on this address? I tried to learn about the vector table but i didnt find some good documents. The vector table is at 0x08 and 0x081 but filled with 0x20020000.This is the address of stack pointer i think. On my previous tries I tried to relocate vector table in application2 in following code: ` SCB->VTOR = FLASH_BANK2_BASE | VECT_TAB_OFFSET` I changed FLASH_BANK2_BASE back to ...BANK_1... The swap works without error from 0x080 to 0x081 without an error now but it did not swap back... – scheinwerfer Aug 24 '21 at 14:08
  • @Damiano Thank you for your help and time! The bank swap is working now. – scheinwerfer Aug 24 '21 at 14:22

1 Answers1

1

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