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 */

 

你可能感兴趣的:(S32K144,c,飞思卡尔)