S32K flash擦除异常以及flash保护 (FLASH_DRV_CommandSequence函数异常)

出现问题

出现擦除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,十分方便。

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小昭dedug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值