用C在闪存中写入一个值

当前,我正在尝试在正在使用的微控制器的闪存上写一个短字符串。目的是使程序将固件版本写入特定的地址,以便引导加载程序可以读取该版本并检查是否有更新。恩智浦提供的驱动程序示例似乎可以正常工作(我可以读写该变量)。但是,当我将此代码放在程序上时,运行kStatus_FTFx_accessError和下一个函数时出现错误103 flaSH_Erase。据我了解,这意味着我设置的地址不正确。

这是我的内存映射(链接文件):

MEMORY
{
  m_interrupts          (RX)  : ORIGIN = 0x00000000,LENGTH = 0x00000400
  m_flash_config        (RX)  : ORIGIN = 0x00000400,LENGTH = 0x00002000
  m_text                (RX)  : ORIGIN = 0x00005000,LENGTH = 0x001FFBF0
  m_data                (RW)  : ORIGIN = 0x1FFF0000,LENGTH = 0x00030000
  m_data_2              (RW)  : ORIGIN = 0x20000000,LENGTH = 0x00030000
}

我正在运行的功能:

#include "flashStorage.h"
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "board.h"
#include "clock_config.h"
#include "fsl_flash.h"
#if defined(FSL_FEATURE_HAS_L1CACHE) && FSL_FEATURE_HAS_L1CACHE
#include "fsl_cache.h"
#endif /* FSL_FEATURE_HAS_L1CACHE */
#include "pin_mux.h"


#define BUFFER_LEN 4


/*! @brief flash driver Structure */
static flash_config_t s_flashDriver;
/*! @brief flash cache driver Structure */
static ftfx_cache_config_t s_cacheDriver;
/*! @brief Buffer for program */
static uint32_t s_buffer[BUFFER_LEN];
/*! @brief Buffer for readback */
static uint32_t s_buffer_rbc[BUFFER_LEN];


/***********************************************************************/
/* LOCAL FUNCTION PROTOTYPES                                           */
/***********************************************************************/


/***********************************************************************/
/* GLOBAL FUNCTIONS                                                    */
/***********************************************************************/
void flaSH_WriteflashMemory(void)
{
    ftfx_security_state_t securityStatus = kFTFx_SecurityStateNotSecure; /* Return protection status */
    status_t result;    /* Return code from each flash driver function */
    uint32_t destAdrss; /* Address of the target location */
    uint32_t i,failAddr,failDat;

    uint32_t pflashBlockBase = 0;
    uint32_t pflashTotalSize = 0;
    uint32_t pflashSectorSize = 0;

    memset(&s_flashDriver,sizeof(flash_config_t));
    memset(&s_cacheDriver,sizeof(ftfx_cache_config_t));
    result = flaSH_Init(&s_flashDriver);
    if (kStatus_FTFx_Success != result)
    {
        PRINTF("error " );         //error_trap();

        //error_trap();
    }
    /* Setup flash cache driver structure for device and initialize variables. */
    result = FTFx_CACHE_Init(&s_cacheDriver);
    if (kStatus_FTFx_Success != result)
    {
        PRINTF("error " );         //error_trap();

        //error_trap();
    }
    /* Get flash properties*/
    flaSH_GetProperty(&s_flashDriver,kflaSH_PropertyPflash0BlockBaseAddr,&pflashBlockBase);
    flaSH_GetProperty(&s_flashDriver,kflaSH_PropertyPflash0TotalSize,&pflashTotalSize);
    flaSH_GetProperty(&s_flashDriver,kflaSH_PropertyPflash0SectorSize,&pflashSectorSize);

    /* Check security status. */
    result = flaSH_GetSecurityState(&s_flashDriver,&securityStatus);
    if (kStatus_FTFx_Success != result)
    {
        PRINTF("error " );         //error_trap();

        //error_trap();
    }
    /* Test pflash basic opeation only if flash is unsecure. */
    if (kFTFx_SecurityStateNotSecure == securityStatus)
    {
        /* Pre-preparation work about flash Cache/Prefetch/Speculation. */
        FTFx_CACHE_ClearCachePrefetchSpeculation(&s_cacheDriver,true);

        /* Debug message for user. */
        /* Erase several sectors on upper pflash block where there is no code */
        PRINTF("\r\n Erase a sector of flash");

/* In case of the protected sectors at the end of the pflash just select
the block from the end of pflash to be used for operations
SECTOR_INDEX_FROM_END = 1 means the last sector,SECTOR_INDEX_FROM_END = 2 means (the last sector - 1) ...
in case of FSL_FEATURE_flaSH_HAS_PflaSH_BLOCK_SWAP it is
SECTOR_INDEX_FROM_END = 1 means the last 2 sectors with width of 2 sectors,SECTOR_INDEX_FROM_END = 2 means the last 4 sectors back
with width of 2 sectors ...
*/
#ifndef SECTOR_INDEX_FROM_END
  #define SECTOR_INDEX_FROM_END 1U
#endif

        destAdrss = 0x2400  ;
        result = flaSH_Erase(&s_flashDriver,destAdrss,pflashSectorSize,kFTFx_ApiEraseKey);
        if (kStatus_FTFx_Success != result)
        {
            PRINTF("error " );         //error_trap();

            //error_trap();
        }

        /* Verify sector if it's been erased. */
        result = flaSH_VerifyErase(&s_flashDriver,kFTFx_MarginValueUser);
        if (kStatus_FTFx_Success != result)
        {
            PRINTF("error " );         //error_trap();

            //error_trap();
        }

        /* Print message for user. */
        PRINTF("\r\n Successfully Erased Sector 0x%x -> 0x%x\r\n",(destAdrss + pflashSectorSize));

        /* Print message for user. */
        PRINTF("\r\n Program a buffer to a sector of flash ");
        /* Prepare user buffer. */
        for (i = 0; i < BUFFER_LEN; i++)
        {
            s_buffer[i] = 3;
        }

        /* Program user buffer into flash*/
        result = flaSH_Program(&s_flashDriver,(uint8_t *)s_buffer,sizeof(s_buffer));
        if (kStatus_FTFx_Success != result)
        {
            PRINTF("error " );         //error_trap();

            //error_trap();
        }

        /* Verify programming by Program Check command with user margin levels */
        result = flaSH_VerifyProgram(&s_flashDriver,sizeof(s_buffer),(const uint8_t *)s_buffer,kFTFx_MarginValueUser,&failAddr,&failDat);
        if (kStatus_FTFx_Success != result)
        {
            PRINTF("error " );         //error_trap();
        }

        for (uint32_t i = 0; i < BUFFER_LEN; i++)
                {
                    s_buffer_rbc[i] = *(volatile uint32_t *)(destAdrss + i * 4);
                    if (s_buffer_rbc[i] != s_buffer[i])
                    {
//                        error_trap();
                    }

                    PRINTF("\r\n VALUES: %d,%d,%d ",s_buffer_rbc[0],s_buffer_rbc[1],s_buffer_rbc[2],s_buffer_rbc[3] );
                }

        /* Post-preparation work about flash Cache/Prefetch/Speculation. */
        FTFx_CACHE_ClearCachePrefetchSpeculation(&s_cacheDriver,false);

#if defined(FSL_FEATURE_HAS_L1CACHE) && FSL_FEATURE_HAS_L1CACHE
        L1CACHE_InvalidateCodeCache();
#endif /* FSL_FEATURE_HAS_L1CACHE */

#if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT
        /* Clean the D-Cache before reading the flash data*/
        SCB_CleanInvalidateDCache();
#endif

    }
    else
    {
        PRINTF("\r\n Erase/Program operation will not be executed,as flash is SECURE!");
    }

}

如何准备适合写入的存储器?或在哪里写一个合适的地址?我似乎不明白为什么我正在使用的内存地址不正确,因为它没有在内存映射中使用。

硬件和编译器:

  • 微控制器:NXP开发的K66F开发板。
  • Kinetis设计工作室IDE。
  • 用于ARM嵌入式处理器的GNU工具(arm-none-eabi-gcc)
q251416140 回答:用C在闪存中写入一个值

这可能是因为您的擦除/编程功能正在从闪存中运行。从闪存执行时,控制器不允许擦除/编程闪存。作为解决方案,您可以将闪存例程复制到RAM并从那里执行。

为确保是这种情况,请查看您的地图文件并检查Flash例程的地址。

本文链接:https://www.f2er.com/3066911.html

大家都在问