MKE14F512VLL16 FlexNVM操作步骤说明

电子说

1.3w人已加入

描述

    使用MKE14F512VLL16 来初始化/读/写 FlexNVM。FlexNVM没有被正确的处理。
FlexNVM 操作步骤如下:
——Flash 初始化
    . RunDFlashHandler() -> SetupDFlash() -> FLASH_Init()
——Flash 擦除
    . RunDFlashHandler() -> if (gFlash.data.u08Mode == DFLASH_ERASE) -> SetCoreAsRunMode()/FLASH_Erase()/SetCoreAsHSRunMode()
——Flash 写
    . RunDFlashHandler() -> else if (gFlash.data.u08Mode == DFLASH_WRITE) -> SetCoreAsRunMode() / FLASH_Program() & ReadE2PDFlash() / SetCoreAsHSRunMode()
——Flash 读
    . RunDFlashHandler() -> else if (gFlash.data.u08Mode == DFLASH_READ) -> ReadE2PDFlash()

> FlexNVM 操作问题描述
  - Erase -> Write(8Byte) -> Read : 读失败/写入的数据不能读出
  - Erase -> Read : 擦除前的数据被读出
  - Erase -> Write(8Byte) -> 延迟或者复位 -> Read : 读取成功

    FlexNVM 直接读取失败,当写入数据到 FlexNVM后,执行延迟或者复位操作,可以正确的读取到写入的数据。MKE14F 推测预取缓冲区相关的函数:

mscm_flash_prefetch_speculation_enable。用Bootloader将固件写入到 Flash中,在引导加载程序中,未使用缓存。这种情况下,是否需要在引导加载程序中应用以下功能函数?

Flash_cache_clear_process与mscm_flash_prefetch_speculation_enable

解答:

    检查 LMEM_PCCLCR寄存器的  LCIVB ,如果有 cache命中事件,则 LCIVB应该是 "1", 如果 cache没有命中,则 LCIVB 是 "0"。

寄存器

    程序 Flash和 数据Flash的空间分别是 0x0000-0x7FFFF(512k, bank0) 和0x10000000-0x10010000 (64k flexNVM, bank1) 。程序Flash 可以用来存储代码和数据,FlexNVM是非易失性的存储器,可以执行程序代码,保存数据或者备份的 EEPROM数据。

> 解决方案:
  - 替代 Flash 驱动,从v2.1.0 更换到 v2.3.1,如下是 v2.3.1的 Flash驱动。

寄存器

  - 应用强制写模式
LMEM->PCCCR |= LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_PCCR2_MASK |LMEM_PCCCR_PCCR3_MASK;

    当使用以下代码使缓存无效后读取FlexNVM区域时,没有出现读取失败现象。如下是解决方案:

> Cache Invalidate 方法


// 写数据到 FlexNVM
/* Enables the processor code bus to invalidate all lines in both ways.
and Initiate the processor code bus code cache command. */
LMEM->PCCCR |= LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_GO_MASK;
/* Wait until the cache command completes. */
while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U)
{
}
/* As a precaution clear the bits to avoid inadvertently re-running this command. */
LMEM->PCCCR &= ~(LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK);
// 从 FlexNVM 读取数据

    为什么应用缓存失效后读取失败会消失?缓存无效清除了读取失败现象。但这似乎不是一个解决方案。根本原因是 cache 是使能的,但是 FlexNVM 在 write-through 模式下不能工作。数据不会写入目标地址,而是写入高速缓存,读取的数据从高速缓存中读取,因此读取的数据和写入的数据可能不同。根据修改后的SDK FlexNVM示例复制了问题,发现有两种方法可以解决问题:

1) 在SystemInit 函数中禁止 Cache功能

void SystemInit (void) {
#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access */
#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */

#if (DISABLE_WDOG)
WDOG->CNT = WDOG_UPDATE_KEY;
WDOG->TOVAL = 0xFFFF;
WDOG->CS = (uint32_t) ((WDOG->CS) & ~WDOG_CS_EN_MASK) | WDOG_CS_UPDATE_MASK;
#endif /* (DISABLE_WDOG) */

/* Initialize Cache */
/* Enable Code Bus Cache */
/* set command to invalidate all ways, enable write buffer
and write GO bit to initiate command */
// LMEM->PCCCR |= LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK;
// LMEM->PCCCR |= LMEM_PCCCR_GO_MASK;
// /* Wait until the command completes */
// while (LMEM->PCCCR & LMEM_PCCCR_GO_MASK) {
// }
// /* Enable cache, enable write buffer */
// LMEM->PCCCR |= (LMEM_PCCCR_ENWRBUF_MASK | LMEM_PCCCR_ENCACHE_MASK);
__ISB();

}

2) 在 LMEM_PCCCR 寄存器中使能 PCCR3 和 PCCR2 位来为FlexNVM启用强制写入模式。

LMEM->PCCCR |= LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_PCCR2_MASK |LMEM_PCCCR_PCCR3_MASK;

    上述两种方法都可以解决读失败的问题。

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分