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