STM32H5 Daul Bank Implementation

前言

之前實做過L4 Daul bank,這邊針對H5在實做一次,但因H5的Daul bank架構邏輯與L4不同這邊在踩了坑後發現他會直接映射到另一個空間,這邊就針對H5這系列IC做深入介紹Daul bank,讓大家都可以避開坑洞快速順利完成專案

架構

因H5裡面的Daul bank初始就是開啟的,所以和G4或L4不同,他是一開始就切割成2塊獨立的區域在舊的L4或G4上是使用下圖去BFB去判讀轉跳

實作

在取得目前所在Bank位置來說因與G4或L4不同不是判讀BFB,所以這邊要修改一下

uint8_t getActiveBank() {

	
	    /* Get the boot configuration status */
	     HAL_FLASHEx_OBGetConfig(&OBInit);

	     /* Check Swap Flash banks  status */
	     if ((OBInit.USERConfig & OB_SWAP_BANK_ENABLE) == OB_SWAP_BANK_DISABLE)
	     {
	    	 /*Active Bank is bank 1 */
	    	 printf("Active Bank is bank 1\n");
	    	 return BANK1_ACTIVE;

	     }
	     else
	     {
	    	 /*Active Bank is bank 2 */
	    	 printf("Active Bank is bank 2\n");
	    	 return BANK2_ACTIVE;

	     }
}

在取得不同Bank後轉跳這邊基本上透過reset會比較快速,因為如果透過address指向,必須2 bank code差異不能太大且個數據address需要固定住位置避免MCU邏輯異常(這塊範例code其實就有提供)

void BT_SWAP_thread_entry(FLASH_OBProgramInitTypeDef OBInit)
{
		      /* Get the boot configuration status */
//		      __disable_irq();
             HAL_FLASH_OB_Unlock();
		      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;

		        if (HAL_FLASHEx_OBProgram(&OBInit) != HAL_OK) {
		                printf("OBINT Fail\n\r ");
		                while (1) {

		                }
		            }
		        /* Launch Option bytes loading */
		        if (HAL_FLASH_OB_Launch() != HAL_OK) {
		            	printf("OBLaunch Fail\n\r ");
		                while (1) {

		                }
		            }
		        HAL_FLASH_OB_Lock();

		        /* Reset the MCU */
		//        __enable_irq();
		//        __disable_irq();
		        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;
		        if (HAL_FLASHEx_OBProgram(&OBInit) != HAL_OK) {
		                printf("OBINT Fail\n\r ");
		                while (1) {

		                }
		            }
		        /* Launch Option bytes loading */
		        if (HAL_FLASH_OB_Launch() != HAL_OK) {
		            	printf("OBLaunch Fail\n\r ");
		                while (1) {

		                }
		            }
		        HAL_FLASH_OB_Lock();
		        /* Reset the MCU */
		        HAL_NVIC_SystemReset();

		      }

}

注意要點

因H5是個別獨立的Bank,所以轉換Bank是會連同起始address一起轉換,如下圖會連同所存取的Flash資訊憶起轉換,所以在判讀資料時候如果2個Bank有個存不同Data需要指向不同位置,而優先判讀是看在哪個Bank

這邊可以參考以下部分code擷取,第一不需要判讀在哪個Bank,然後針對不同Bank讀取不同Data做資料分析

	uint32_t DateBank1=0;
    uint8_t Data1_m=0,Data1_h=0,Data2_m=0,Data2_h=0;
    uint32_t DateBank2=0;
    uint8_t bank_inform=0;
    uint32_t QuadWord[4] = {0,0,0,0};//{bank_inform,bank_flag,0,0}
		bank_inform=getActiveBank();
	printf("Bank=%d\n\r",bank_inform);
	if(bank_inform==1)
	{
	  DateBank1 = *(__IO uint32_t *)0x0807C004;//bank 1 VERSION data
	  DateBank2 = *(__IO uint32_t *)0x0817C004;//bank 2 VERSION data need modify 0x080FC004 on 1M flash size
	}
	else
	{
	  DateBank2 = *(__IO uint32_t *)0x0807C004;//bank 1 VERSION data
	  DateBank1 = *(__IO uint32_t *)0x0817C004;//bank 2 VERSION data need modify 0x080FC004 on 1M flash size
	}

另一個要點是雖然Address變更但在擦除Flash部分還是依照原先規則
舉例目前在Bank1 要清除Bank1 第63 sectors程式會使用以下宣告

		  EraseInitStruct.TypeErase     = FLASH_TYPEERASE_SECTORS;
		  EraseInitStruct.Banks         = 1;
		  EraseInitStruct.Sector        = 63;
		  EraseInitStruct.NbSectors     = 1;

		  if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK)
		printf("Erase fail\n\r");

如果目前切換到Bank2 要清除Bank1 第63 sectors程式宣告方式也會與在Bank1相同如下,並不會因為不同Bank不同

		  EraseInitStruct.TypeErase     = FLASH_TYPEERASE_SECTORS;
		  EraseInitStruct.Banks         = 1;
		  EraseInitStruct.Sector        = 63;
		  EraseInitStruct.NbSectors     = 1;

		  if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK)
		printf("Erase fail\n\r");

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart