在C中的闪存上写入值

在C中的闪存上写入值,c,embedded,nxp-microcontroller,C,Embedded,Nxp Microcontroller,目前我正在尝试在我使用的微控制器的闪存上写一个短字符串。目标是程序在特定地址写入固件版本,以便引导加载程序可以读取并检查是否有更新。NXP提供的驱动程序示例似乎有效(我可以写入和读取变量)。但是,当我将此代码放在我的程序中时,运行FLASH\u Erase和下一个函数时,会出现错误103kStatus\u FTFx\u AccessError。据我所知,这意味着我设置的地址不正确 这是我的内存映射(链接器文件): 我正在运行的函数: #include "FlashStorage.h" #incl

目前我正在尝试在我使用的微控制器的闪存上写一个短字符串。目标是程序在特定地址写入固件版本,以便引导加载程序可以读取并检查是否有更新。NXP提供的驱动程序示例似乎有效(我可以写入和读取变量)。但是,当我将此代码放在我的程序中时,运行
FLASH\u Erase
和下一个函数时,会出现错误103
kStatus\u FTFx\u AccessError
。据我所知,这意味着我设置的地址不正确

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

我正在运行的函数:

#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, 0, sizeof(flash_config_t));
    memset(&s_cacheDriver, 0, 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, destAdrss, pflashSectorSize, 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, (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, destAdrss, (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, destAdrss, 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, %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!");
    }

}
#包括“FlashStorage.h”
#包括“fsl_设备_寄存器.h”
#包括“fsl_debug_console.h”
#包括“board.h”
#包括“clock_config.h”
#包括“fsl_flash.h”
#如果已定义(FSL\u功能\u具有\u l1缓存)&&FSL\u功能\u具有\u l1缓存
#包括“fsl_cache.h”
#endif/*FSL\u功能\u具有\u l1缓存*/
#包括“pin_mux.h”
#定义缓冲区4
/*! @Flash驱动程序结构简介*/
静态flash_配置_t s_flash驱动程序;
/*! @闪存缓存驱动程序结构简介*/
静态ftfx_缓存配置_t s_缓存驱动程序;
/*! @程序的简短缓冲区*/
静态uint32_t s_缓冲区[缓冲区长度];
/*! @用于回读的简短缓冲区*/
静态uint32 s_t s_buffer_rbc[buffer_LEN];
/***********************************************************************/
/*局部函数原型*/
/***********************************************************************/
/***********************************************************************/
/*全局函数*/
/***********************************************************************/
无效闪存\写入闪存(无效)
{
ftfx_security_state_t securityStatus=kFTFx_SecurityStateNotSecure;/*返回保护状态*/
状态\u t结果;/*来自每个闪存驱动程序功能的返回代码*/
uint32\u t destadss;/*目标位置的地址*/
uint32_t i,故障地址,故障数据;
uint32_t pflashBlockBase=0;
uint32_t pflashTotalSize=0;
uint32\u t pflashSectorSize=0;
memset(&s_flashDriver,0,sizeof(flash_config_t));
memset(&s_cacheDriver,0,sizeof(ftfx_cache_config_t));
结果=FLASH_Init(&s_flashDriver);
如果(kStatus\u FTFx\u Success!=结果)
{
PRINTF(“error”);//error_trap();
//错误_trap();
}
/*为设备设置闪存缓存驱动程序结构并初始化变量*/
结果=FTFx_CACHE_Init(&s_cacheDriver);
如果(kStatus\u FTFx\u Success!=结果)
{
PRINTF(“error”);//error_trap();
//错误_trap();
}
/*获取flash属性*/
FLASH_GetProperty(&s_flashDriver,kFLASH_propertyFlash0BlockBaseAddr,&pflashBlockBase);
FLASH_GetProperty(&s_flashDriver,kFLASH_propertyFlash0TotalSize,&pflashTotalSize);
FLASH_GetProperty(&s_flashDriver、kFLASH_propertyFlash0SectorSize和pflashSectorSize);
/*检查安全状态*/
结果=FLASH\u GetSecurityState(&s\u flashDriver和&securityStatus);
如果(kStatus\u FTFx\u Success!=结果)
{
PRINTF(“error”);//error_trap();
//错误_trap();
}
/*仅当闪存不安全时,测试pflash基本操作*/
if(KFTX_SecurityStateNotSecure==securityStatus)
{
/*有关闪存缓存/预取/推测的预准备工作*/
FTFx_CACHE_clearcacheprefetchProjection(&s_cacheDriver,true);
/*用户的调试消息*/
/*清除上部pflash块上没有代码的几个扇区*/
PRINTF(“\r\n擦除闪存的扇区”);
/*对于pFlash末尾的受保护扇区,只需选择
从pFlash末端开始用于操作的块
扇区索引自扇区结束=1表示最后一个扇区,
扇区索引自扇区结束=2表示(最后一个扇区-1)。。。
如果FSL\u功能\u闪存\u有\u闪存\u块\u交换,则为
扇区指数=1表示宽度为2个扇区的最后2个扇区,
扇区索引从扇区结束=2表示最后4个扇区返回
宽度为2个扇区。。。
*/
#ifndef扇区索引(从末尾开始)
#从1U端定义扇区索引
#恩迪夫
destadss=0x2400;
结果=闪存擦除(&s\U闪存驱动程序、destadss、pflashSectorSize、kFTFx\U APIREASEKEY);
如果(kStatus\u FTFx\u Success!=结果)
{
PRINTF(“error”);//error_trap();
//错误_trap();
}
/*验证扇区是否已被擦除*/
结果=闪存验证擦除(&s_闪存驱动程序、destadss、pflashSectorSize、kFTFx_MarginValueUser);
如果(kStatus\u FTFx\u Success!=结果)
{
PRINTF(“error”);//error_trap();
//错误_trap();
}
/*为用户打印消息*/
PRINTF(“\r\n已成功擦除扇区0x%x->0x%x\r\n”,destadss,(destadss+pflashSectorSize));
/*为用户打印消息*/
PRINTF(“\r\n将缓冲区编程到闪存扇区”);
/*准备用户缓冲区*/
对于(i=0;i#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, 0, sizeof(flash_config_t));
    memset(&s_cacheDriver, 0, 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, destAdrss, pflashSectorSize, 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, (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, destAdrss, (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, destAdrss, 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, %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!");
    }

}