Flash Erase, Write and Verify Succeed but Data is not Saved on MKE14Z32

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Flash Erase, Write and Verify Succeed but Data is not Saved on MKE14Z32

跳至解决方案
1,417 次查看
murphybeale
Contributor II

Title says it all; I am able to erase, verifyErase, progam and verifyProgram the last sector of the MKE14Z32's flash using MCUXpresso's flash driver. No errors are observed or returned. Everything "works" correctly except that after the write the contents at 0x7C00 (start of last page) are unchanged.

Things I have checked:

`FLASH_GetSecurityState(&flash_driver, &security_state);` returns UNSECURE.
`FLASH_IsProtected(&flash_driver, 0x7C00, 0x400, &protection_state);` returns UNPROTECTED.
The core is in RUN mode (see: https://stackoverflow.com/questions/58951792/writing-a-value-on-the-flash-memory-in-c, second answer).
I am performing and erase before each write.
There is no code in the last sector and the linker script has been updated to account for this region. No hardfaults are generated.

My gut tells me that there is some other kind of write protection mechanism that I am missing but I am at a loss as to what.

So, what could cause all flash operations to succeed while simultaneously being ignored?

Code:

破坏者
#include <string.h>

#include "fsl_flash.h"

#include "board.h"
#include "flash.h"

static flash_config_t flash_driver = {0};
static ftfx_cache_config_t cache_driver = {0};
static uint32_t flash_base;
static uint32_t flash_total_size;
static uint32_t flash_sector_size;

int32_t flash_init(void)
{
    status_t ret;

    // Init flash management structure
    ret = FLASH_Init(&flash_driver);
    if (kStatus_FTFx_Success != ret)
        return -1;

    // Init cache
    ret = FTFx_CACHE_Init(&cache_driver);
    if (kStatus_FTFx_Success != ret)
        return -1;

    // Query information about this particular flash
    FLASH_GetProperty(&flash_driver, kFLASH_PropertyPflash0BlockBaseAddr, &flash_base);
    FLASH_GetProperty(&flash_driver, kFLASH_PropertyPflash0TotalSize, &flash_total_size);
    FLASH_GetProperty(&flash_driver, kFLASH_PropertyPflash0SectorSize, &flash_sector_size);

#if 0
    // Default state is insecure
    {
        ftfx_security_state_t securityStatus;

        ret = FLASH_GetSecurityState(&flash_driver, &securityStatus);
        if (kStatus_FTFx_Success != ret)
            return -1;
    }
#endif

#if 0
    // Default state is unprotected
    {
        flash_prot_state_t protection_state;

        ret = FLASH_IsProtected(&flash_driver, 0x7C00, 0x400, &protection_state);
        if (kStatus_FTFx_Success != ret)
            return -1;
    }
#endif

    return 0;
}

int32_t flash_get_sector_count(void)
{
    return flash_total_size / flash_sector_size;
}

int32_t flash_erase_sector(uint32_t sect)
{
    status_t ret;
    uint32_t dest_addr = flash_base + (sect * flash_sector_size);

    // Erase...
    ret = FLASH_Erase(&flash_driver, dest_addr, flash_sector_size, kFTFx_ApiEraseKey);
    if (kStatus_FTFx_Success != ret)
        return -1;

    // ...and verify
    ret = FLASH_VerifyErase(&flash_driver, dest_addr, flash_sector_size, kFTFx_MarginValueUser);
    if (kStatus_FTFx_Success != ret)
        return -1;

    return 0;
}

int32_t flash_write_sector(uint32_t sect, uint8_t *buf, uint32_t sz)
{
    status_t ret;
    int32_t retval = 0;
    uint32_t dest_addr = flash_base + (sect * flash_sector_size);

    // DEBUG
#if 0
    // Reports unprotected
    flash_prot_state_t protection_state;

    ret = FLASH_IsProtected(&flash_driver, dest_addr, sz, &protection_state);
    if (kStatus_FTFx_Success != ret)
        return -1;
#endif

    FTFx_CACHE_ClearCachePrefetchSpeculation(&cache_driver, true);

    // Program...
    ret = FLASH_Program(&flash_driver, dest_addr, buf, sz);
    if (kStatus_FTFx_Success != ret) {
        retval = -1;
        goto err_exit;
    }

    // ...and verify
    ret = FLASH_VerifyProgram(&flash_driver, dest_addr, sz, buf, kFTFx_MarginValueUser, NULL, NULL);
    if (kStatus_FTFx_Success != ret) {
        retval = -1;
        goto err_exit;
    }

err_exit:
    FTFx_CACHE_ClearCachePrefetchSpeculation(&cache_driver, false);

    return retval;
}

int32_t flash_read_sector(uint32_t sect, uint8_t *buf, uint32_t sz)
{
    uint32_t src_addr = flash_base + (sect * flash_sector_size);

    memcpy(buf, (uint8_t *)src_addr, sz);
    return 0;
}
标签 (1)
标记 (1)
0 项奖励
回复
1 解答
1,221 次查看
murphybeale
Contributor II

This turned out to be a problem with the debugger I am using (I don't use the MCUXpresso IDE; just the toolchain) showing a cached memory state.

PSA: Always make sure your tools are showing you what you think they are.

在原帖中查看解决方案

0 项奖励
回复
3 回复数
1,222 次查看
murphybeale
Contributor II

This turned out to be a problem with the debugger I am using (I don't use the MCUXpresso IDE; just the toolchain) showing a cached memory state.

PSA: Always make sure your tools are showing you what you think they are.

0 项奖励
回复
1,380 次查看
murphybeale
Contributor II

The plot thickens.  If I change from the last flash page (31) to the second from last (30), everything works as expected.  Is there anything special about the last page of flash?

0 项奖励
回复
1,230 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I checked the reference manual of KE14Z32, I have not found any description that the last page of flash has special utilization.

Maybe your tools has written data in the last page.

Pls read the data in the last page with either debugger or blhost.

BTW, with blhost tools, you can mass-erase all the flash, then read the last page, then check if the last page has erased or not.

The KE14Z32 has ROM flashloader, you can use blhost tools to read/erase/program.

Hope it can help you

BR

XiangJun Rong

 

0 项奖励
回复