接上一篇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 */