使用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 : 讀失敗/寫入的數(shù)據(jù)不能讀出
- Erase -> Read :擦除前的數(shù)據(jù)被讀出
- Erase -> Write(8Byte) ->延遲或者復(fù)位-> Read :讀取成功
FlexNVM 直接讀取失敗,當(dāng)寫入數(shù)據(jù)到 FlexNVM后,執(zhí)行延遲或者復(fù)位操作,可以正確的讀取到寫入的數(shù)據(jù)。MKE14F 推測預(yù)取緩沖區(qū)相關(guān)的函數(shù):
mscm_flash_prefetch_speculation_enable。用Bootloader將固件寫入到 Flash中,在引導(dǎo)加載程序中,未使用緩存。這種情況下,是否需要在引導(dǎo)加載程序中應(yīng)用以下功能函數(shù)?
Flash_cache_clear_process與mscm_flash_prefetch_speculation_enable
解答:
檢查 LMEM_PCCLCR寄存器的LCIVB ,如果有 cache命中事件,則 LCIVB應(yīng)該是 "1", 如果 cache沒有命中,則 LCIVB 是 "0"。
程序 Flash和 數(shù)據(jù)Flash的空間分別是 0x0000-0x7FFFF(512k, bank0) 和0x10000000-0x10010000 (64k flexNVM, bank1) 。程序Flash 可以用來存儲代碼和數(shù)據(jù),F(xiàn)lexNVM是非易失性的存儲器,可以執(zhí)行程序代碼,保存數(shù)據(jù)或者備份的 EEPROM數(shù)據(jù)。
> 解決方案:
- 替代 Flash 驅(qū)動,從v2.1.0 更換到 v2.3.1,如下是 v2.3.1的 Flash驅(qū)動。
- 應(yīng)用強制寫模式
LMEM->PCCCR |= LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_PCCR2_MASK |LMEM_PCCCR_PCCR3_MASK;
當(dāng)使用以下代碼使緩存無效后讀取FlexNVM區(qū)域時,沒有出現(xiàn)讀取失敗現(xiàn)象。如下是解決方案:
> Cache Invalidate 方法
// 寫數(shù)據(jù)到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 讀取數(shù)據(jù) |
為什么應(yīng)用緩存失效后讀取失敗會消失?緩存無效清除了讀取失敗現(xiàn)象。但這似乎不是一個解決方案。根本原因是cache 是使能的,但是 FlexNVM 在 write-through 模式下不能工作。數(shù)據(jù)不會寫入目標(biāo)地址,而是寫入高速緩存,讀取的數(shù)據(jù)從高速緩存中讀取,因此讀取的數(shù)據(jù)和寫入的數(shù)據(jù)可能不同。根據(jù)修改后的SDK FlexNVM示例復(fù)制了問題,發(fā)現(xiàn)有兩種方法可以解決問題:
1) 在SystemInit 函數(shù)中禁止 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;
上述兩種方法都可以解決讀失敗的問題。
審核編輯:湯梓紅
-
寄存器
+關(guān)注
關(guān)注
31文章
5294瀏覽量
119816 -
FlaSh
+關(guān)注
關(guān)注
10文章
1614瀏覽量
147655
原文標(biāo)題:MKE14F512VLL16 FlexNVM 操作
文章出處:【微信號:嵌入式 MCU,微信公眾號:嵌入式 MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論