cancel
Showing results for 
Search instead for 
Did you mean: 

Is bank swap on STM32H753 immediate, instead of after reset?

JMall
Associate II

I'm writing in-field update code for the STM32H753, and according to the reference manual (RM0433, Section 3.3.13) the FLASH memory bank swap takes effect only after a reset. But I wrote a test program that seems to indicate the bank swap actually happens immediately. How does FLASH bank swapping work? Are there any examples of in-field update code for the STM32H753?

Thanks.

6 REPLIES 6

The options bytes will load at reset.

Banking options may depend on interleaved, or end-on-end configuration.

Configurations in FLASH_OPTCR SWAP_BANK should occur immediately basically allowing for fork() like operation.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
JMall
Associate II

Thanks for the correction to the Reference Manual!

Singh.Harjit
Senior II

Is this limited to the STM32H753 or also the same on the STM32H743. I'm guessing they are the same die and so should be the same.

Can we get ST to confirm this is the behavior and it will stay that way?

According to the reference manual, RM0433, Rev 6:

  • Section 3.3.13, Note says: The SWAP_BANK bit in FLASH_OPTCR is read-only and cannot be modified by the application software
  • Section 3.9.7, also says this is a read only bit.

It would be wonderful if this bit is a writeable bit that swaps the banks immediately because I would like to use both banks for log data storage.

My code fits in 128kB. According to the reference manual, RM0433, Rev 6, last paragraph in section 3.3.3 FLASH architecture and integration in the system:

The embedded Flash memory is built in such a way that only one read or write operation can be executed at a time on a given bank.

This means that if I'm running out of a bank, I cannot write to it without the code blocking for writes. Since my application has high interrupt rates, I cannot do this.

To get around this, I was thinking of putting my code in the first 128kB of both banks. Then, when running from Bank 0, use all but the first 128kB of the second bank for log data. When the second bank is filled up, jump to a routine in ITCM and swap flash banks using SWAP_BANK bit in FLASH_OPTCR and continue.

Since the code in the first 128kB is the same, my code doesn't need to be relocated or anything. I might have to disable flash fetching and then re-enable it. But perhaps not. Similarly, I might not have to run code out of ITCM to do the flash bank swapping.

JMall
Associate II

Hi, Singh.

I have also tested this on a Nucleo-H743ZI dev board, and it behaves the same way as on my project's STM32H753. On both MCUs my testing indicates that the bank swap takes effect immediately.

Good luck with your project!

Singh.Harjit
Senior II

Since I will soon be writing code to write to the internal flash, a few questions for you:

Can you share some details about your code. Things like, did you write it from scratch or are you using some other code?

Any chance it will be publicly available - so, I can take a look at it to see if it will meet my needs and if so, use it?

Thanks.

JMall
Associate II

Hi.

The code I'm writing is for a client, so I can't release it. However it is identical to the example code provided by STMicro in their firmware H7 release version 1.5.0. It's in the directory:

STM32Cube_FW_H7_V1.5.0\Projects\NUCLEO-H743ZI\Examples\FLASH\FLASH_SwapBank

which looks like:

      /* 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();
      }
      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();
      }

Also, since you plan on having exactly the same code in the first sector of both banks, I think you won't need to run the code out of ITCM to do the swap safely. Just using something like the code from the example should work fine I think.

Good luck.