出现问题
出现擦除flash异常,一直在FLASH_DRV_CommandSequence卡死复位
但是出现比较奇怪的现象,通过DEBUG在线调试,打断点,一步一步调试可以正常对flash正常擦除读写,但是脱离在线调试就出现不能正常擦除读写。
出现这种还是看下官网例程怎么写的?打开S32DS ,NXP的官方例程
CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,
g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);
/* Init source data */
for (i = 0u; i < BUFFER_SIZE; i++)
{
sourceBuffer[i] = i;
}
/* Disable cache to ensure that all flash operations will take effect instantly,
* this is device dependent */
/* Install interrupt for Flash Command Complete event */
INT_SYS_InstallHandler(FTFC_IRQn, CCIF_Handler, (isr_t*) 0);
INT_SYS_EnableIRQ(FTFC_IRQn);
/* Enable global interrupt */
INT_SYS_EnableIRQGlobal();
/* Always initialize the driver before calling other functions */
ret = FLASH_DRV_Init(&Flash_InitConfig0, &flashSSDConfig);
DEV_ASSERT(STATUS_SUCCESS == ret);
//#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)
{
/* 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 S32K144:
* - EEEDataSizeCode = 0x02u: EEPROM size = 4 Kbytes
* - DEPartitionCode = 0x08u: EEPROM backup size = 64 Kbytes */
ret = FLASH_DRV_DEFlashPartition(&flashSSDConfig, 0x02u, 0x08u, 0x0u, false, true);
DEV_ASSERT(STATUS_SUCCESS == ret);
/* Re-initialize the driver to update the new EEPROM configuration */
ret = FLASH_DRV_Init(&Flash_InitConfig0, &flashSSDConfig);
DEV_ASSERT(STATUS_SUCCESS == ret);
/* Make FlexRAM available for EEPROM */
ret = FLASH_DRV_SetFlexRamFunction(&flashSSDConfig, EEE_ENABLE, 0x00u, NULL);
DEV_ASSERT(STATUS_SUCCESS == ret);
}
else /* FLexRAM is already configured as EEPROM */
{
/* 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);
}
/* 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 last PFlash sector */
address = FEATURE_FLS_PF_BLOCK_SIZE - 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);
最关键,也比较特别的地方
void CCIF_Handler(void);
/* If target is flash, insert this macro to locate callback function into RAM */
START_FUNCTION_DECLARATION_RAMSECTION
void CCIF_Callback(void)
END_FUNCTION_DECLARATION_RAMSECTION
void CCIF_Handler(void)
{
/* Disable Flash Command Complete interrupt */
FTFx_FCNFG &= (~FTFx_FCNFG_CCIE_MASK);
return;
}
/*!
\brief Callback function for Flash operations
*/
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
START_FUNCTION_DEFINITION_RAMSECTION、END_FUNCTION_DEFINITION_RAMSECTION这是成对使用的,表示中间这部分代码要放在RAM中执行。如果目标是flash,请插入此宏以将回调函数定位到RAM中。因为操作flash这部分代码是没有在加载在RAM中,导致操作flash出现异常,所以操作flash时要添加前面两个宏,把程序加载到RAM中,特别是操作FTFx_FCNFG这个寄存器。
介绍S32K Flash
对Flash擦除,bit0置为1的过程,擦除完的扇区基本是0xffff…。写入数据,一般是将1置为0.
S32K144芯片有512K,地址0-0x0007_ffff,每个扇区的大小是4K,共有128个扇区,这里Flash是Program Flash(P_Flash 程序Flash)。还有Data Flash(D_Flash 数据Flash),有16个扇区,64K。4K的EEPROM
flash保护
对于未加密芯片,,可以通过调试接口(JTAG、SWD和USBDM等)访问芯片内部的存储器;而对于加密芯片,通过外部调试接口只能进行整体擦除操作,但无法执行读取或写入Flash的指令,运行MCU程序对Flash访问则不受任何影响。
通过对Flash安全配置域设置,可以配置程序Flash保护寄存器FTFS_FPROT、Flash安全寄存器FTFS_FSEC及Flash_选项寄存器FTFS_FOPT,EEPROM保护寄存器是FEPROT(最小的保护单元,整个EEPROM的1/8),D-Flash保护寄存器是FEPROT,从而限制对Flash存储空间的访问。Flash存储器的地址0x0000_0400~0x0000_0410为Flash配置域,16个字节,含义如下。
通过配置寄存器PROT0~3可以对整个P-Flash进行保护,保护的最小单元为整个PFlash的1/32,比如S32K144有512KB的P-Flash,其最小保护单元为16KB,而S32K116只
有128KB P-Flash,所以其保护的最小单元为4KB。保护的规则是只增加不减少,即当前未保
护的区域可以增加保护,但当前已经保护的区域则不能解保护
0x400~0x407:存储器8个字节的后门解密秘钥(backdoor key),用于使能后门
解密时临时解密MCU;
0x408~0x40B:P-Flash保护(Protection)配置字节,其值在MCU复位过程中由
硬件自动加载到P-Flash保护寄存器(FPTOT0~3)作为其初始值; FPTOT
0x40C:Flash加密(Security)配置字节,其值在MCU复位过程中由硬件自动加载
到P-Flash加密寄存器(FSEC)作为其初始值; FDPROT
0x40D:Flash非易失选项配置字节,其值在MCU复位过程中由硬件自动加载到
Flash非易失选项寄存器(FOPT)作为其初始值; FEPROT
0x40E:EEPROM保护配置字节,其值在MCU复位过程中由硬件自动加载到
EEPROM保护寄存器(FEPROT)作为其初始值; FOPT
0x40F:D-Flash保护配置字节,其值在MCU复位过程中由硬件自动加载到DFlash保护寄存器(FDPROT)作为其初始值 FSEC
通过修改启动文件,即可设置保护Flash,十分方便。