S32K實現FlexNVM模擬EEPROM,並實現在一個固定地址更新數據

接上一篇FlexRAM模擬EEPROM,這篇我們用FlexNVM模擬EEPROM.

Question1: 在操作Flash的時候,會將代碼運行到RAM區內,目前沒有找到實際代碼,沒搞清楚。

Question2:在操作Flash的時候,Demo例程中總會出現,後門密鑰訪問加密安全字節,也沒搞清楚。

但是,通過看了一個禮拜的手冊和Demo例程,將代碼中可以實現功能的部分摘抄下來,以供交流

/* Including necessary module. Cpu.h contains other modules needed for compiling.*/
#include "Cpu.h"

  volatile int exit_code = 0;

 flash_ssd_config_t   flashSSDConfig;

 /* Data source for program operation */
 #define BUFFER_SIZE         0x10u          /* Size of data source */
 uint8_t sourceBuffer[BUFFER_SIZE]={1,2,3,4,5,6,7,8};
 uint8_t sourceReadBuffer[2]={0};
/* User includes (#include below this line is not maintained by Processor Expert) */
 void CCIF_Handler(void);

 START_FUNCTION_DECLARATION_RAMSECTION

 void CCIF_Callback(void)

 END_FUNCTION_DECLARATION_RAMSECTION
/*!
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/

 /**
  * 時間:2020.03.20
  * 實現FlexNVM 的 EEPROM模擬,實現一個最小扇區 2K的讀寫
  * 試驗結果:FlexNVM模擬的EEPROM,每次刷寫程序的時候必須先檫除
  * 實現在0x10000000內存處每次燒寫加1
  * ******/
int main(void)
{


  /* Write your local variable definition here */
	 status_t ret;        /* Store the driver APIs return code */
	 uint32_t address;
	 uint32_t size;
	 uint32_t failAddr;
	   // uint32_t i;
	 flash_callback_t pCallBack;       //

#if 0
#if (FEATURE_FLS_HAS_PROGRAM_PHRASE_CMD == 1u)
    uint8_t unsecure_key[FTFx_PHRASE_SIZE] = {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFEu, 0xFFu, 0xFFu, 0xFFu};

#else   /* FEATURE_FLASH_HAS_PROGRAM_LONGWORD_CMD */

    uint8_t unsecure_key[FTFx_LONGWORD_SIZE] = {0xFEu, 0xFFu, 0xFFu, 0xFFu};    //0304 ?   0306 flash解密鑰匙

#endif  /* FEATURE_FLS_HAS_PROGRAM_PHRASE_CMD */
#endif

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  #ifdef PEX_RTOS_INIT
    PEX_RTOS_INIT();                   /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of Processor Expert internal initialization.                    ***/
   CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,
                      g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
   CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);


  /* Install interrupt for Flash Command Complete event */
   INT_SYS_InstallHandler(FTFC_IRQn, CCIF_Handler, (isr_t*) 0);     //CCIF_Handler代表了一個形參爲void,返回值爲void的函數
   INT_SYS_EnableIRQ(FTFC_IRQn);
   /* Enable global interrupt */
   INT_SYS_EnableIRQGlobal();


   /* Always initialize the driver before calling other functions  總是在調用其他函數之前初始化驅動程序*/

   ret = FLASH_DRV_Init(&Flash1_InitConfig0, &flashSSDConfig);    ////  1  初始化內存分區,flexNVM和flash的分區範圍
   DEV_ASSERT(STATUS_SUCCESS == ret);   //判斷返回值,ret==0x00正常,否則BKPT_ASM

#if 1
        /* Reprogram secure byte in Flash configuration field */
#if (FEATURE_FLS_HAS_PROGRAM_PHRASE_CMD == 1u)
        address = 0x408u;
        size = FTFx_PHRASE_SIZE;
#else   /* FEATURE_FLASH_HAS_PROGRAM_LONGWORD_CMD == 1u */
        address = 0x40Cu;
        size = FTFx_LONGWORD_SIZE;
#endif /* FEATURE_FLS_HAS_PROGRAM_PHRASE_CMD */
        ret = FLASH_DRV_Program(&flashSSDConfig, address, size, unsecure_key);
        DEV_ASSERT(STATUS_SUCCESS == ret);
#endif


#if ((FEATURE_FLS_HAS_FLEX_NVM == 1u) & (FEATURE_FLS_HAS_FLEX_RAM == 1u))
    /* Config FlexRAM as EEPROM if it is currently used as traditional RAM */
    if (flashSSDConfig.EEESize == 0u)
    {
#ifndef FLASH_TARGET

#if 0
        /* First, erase all Flash blocks if code is placed in RAM to ensure
         * the IFR region is blank before partitioning FLexNVM and FlexRAM */
        ret = FLASH_DRV_EraseAllBlock(&flashSSDConfig);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Verify the erase operation at margin level value of 1 */
        ret = FLASH_DRV_VerifyAllBlock(&flashSSDConfig, 1u);
        DEV_ASSERT(STATUS_SUCCESS == ret);
#endif


#endif /* FLASH_TARGET */



        /* Configure FlexRAM as EEPROM and FlexNVM as EEPROM backup region,
         * DEFlashPartition will be failed if the IFR region isn't blank.
         * Refer to the device document for valid EEPROM Data Size Code
         * and FlexNVM Partition Code. For example on S32K148:
         * - EEEDataSizeCode = 0x02u: EEPROM size = 4 Kbytes
         * - DEPartitionCode = 0x04u: EEPROM backup size = 64 Kbytes */
        ret = FLASH_DRV_DEFlashPartition(&flashSSDConfig, 0x02u, 0x04u, 0x0u, false, true);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Re-initialize the driver to update the new EEPROM configuration */
        ret = FLASH_DRV_Init(&Flash1_InitConfig0, &flashSSDConfig);
        DEV_ASSERT(STATUS_SUCCESS == ret);

#if 1
        /* Make FlexRAM available for EEPROM */
        ret = FLASH_DRV_SetFlexRamFunction(&flashSSDConfig, EEE_ENABLE, 0x00u, NULL);
        DEV_ASSERT(STATUS_SUCCESS == ret);
#endif

    }
    else    /* FLexRAM is already configured as EEPROM */
    {
#if 1
        /* Make FlexRAM available for EEPROM, make sure that FlexNVM and FlexRAM
         * are already partitioned successfully before */
        ret = FLASH_DRV_SetFlexRamFunction(&flashSSDConfig, EEE_ENABLE, 0x00u, NULL);
        DEV_ASSERT(STATUS_SUCCESS == ret);
#endif

    }
#endif /* (FEATURE_FLS_HAS_FLEX_NVM == 1u) & (FEATURE_FLS_HAS_FLEX_RAM == 1u) */


#if 0
    /* Set callback function before a long time consuming flash operation
         * (ex: erasing) to let the application code do other tasks while flash in operation.
         * In this case we use it to enable interrupt for Flash Command Complete event
          */
        pCallBack = (flash_callback_t)CCIF_Callback;
        flashSSDConfig.CallBack = pCallBack;

        /* Erase the sixth PFlash sector */
        address = 6u * FEATURE_FLS_PF_BLOCK_SECTOR_SIZE;
        size = FEATURE_FLS_PF_BLOCK_SECTOR_SIZE;
        ret = FLASH_DRV_EraseSector(&flashSSDConfig, address, size);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Disable Callback */
        flashSSDConfig.CallBack = NULL_CALLBACK;

        /* Verify the erase operation at margin level value of 1, user read */
        ret = FLASH_DRV_VerifySection(&flashSSDConfig, address, size / FTFx_DPHRASE_SIZE, 1u);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Write some data to the erased PFlash sector */
        size = BUFFER_SIZE;
        ret = FLASH_DRV_Program(&flashSSDConfig, address, size, sourceBuffer);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Verify the program operation at margin level value of 1, user margin */
        ret = FLASH_DRV_ProgramCheck(&flashSSDConfig, address, size, sourceBuffer, &failAddr, 1u);
        DEV_ASSERT(STATUS_SUCCESS == ret);
#endif


#if (FEATURE_FLS_HAS_FLEX_NVM == 1u)

#if 0
        /* Erase a sector in DFlash */
        address = flashSSDConfig.DFlashBase;
        size = FEATURE_FLS_DF_BLOCK_SECTOR_SIZE;
        ret = FLASH_DRV_EraseSector(&flashSSDConfig, address, size);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Verify the erase operation at margin level value of 1, user read */
        ret = FLASH_DRV_VerifySection(&flashSSDConfig, address, size / FTFx_PHRASE_SIZE, 1u);
        DEV_ASSERT(STATUS_SUCCESS == ret);
#endif

        /* Write some data to the erased DFlash sector */
        address = flashSSDConfig.DFlashBase;
        size = BUFFER_SIZE;
        sourceReadBuffer[1]=*(uint8_t*)address;

        if(sourceReadBuffer[0]!=*(uint8_t*)address)    //如果當前數據沒有更新,便是255
        {
        	if(255==*(uint8_t*)address){
        		sourceBuffer[0]=0;
        	}
        	else{
        		sourceBuffer[0]=(*(uint8_t *)address)+1;
        	}

        }
        else if(0==*(uint8_t*)address)
        {
        	sourceBuffer[0]=(*(uint8_t*)address)+1;
        }
        /* Erase a sector in DFlash */
        address = flashSSDConfig.DFlashBase;
        size = FEATURE_FLS_DF_BLOCK_SECTOR_SIZE;
        ret = FLASH_DRV_EraseSector(&flashSSDConfig, address, size);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        ret = FLASH_DRV_Program(&flashSSDConfig, address, size, sourceBuffer);      //寫入到0x1000 0000
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Verify the program operation at margin level value of 1, user margin */
        ret = FLASH_DRV_ProgramCheck(&flashSSDConfig, address, size, sourceBuffer, &failAddr, 1u);
        DEV_ASSERT(STATUS_SUCCESS == ret);
#endif /* FEATURE_FLS_HAS_FLEX_NVM */





  /* Write your code here */
  /* For example: for(;;) { } */

  /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;) {
    if(exit_code != 0) {
      break;
    }
  }
  return exit_code;
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/


 START_FUNCTION_DEFINITION_RAMSECTION
   void CCIF_Callback(void)
   {
       /* Enable interrupt for Flash Command Complete */
       if ((FTFx_FCNFG & FTFx_FCNFG_CCIE_MASK) == 0u)
       {
           FTFx_FCNFG |= FTFx_FCNFG_CCIE_MASK;
       }
   }

 END_FUNCTION_DEFINITION_RAMSECTION

 void CCIF_Handler(void)
 {
     /* Disable Flash Command Complete interrupt */  // 禁用 flash命令完成中斷
     FTFx_FCNFG &= (~FTFx_FCNFG_CCIE_MASK);

     return;
 }
/* END main */

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章