we are trying to erase the flash from our customer boot loader program and the erase code is running from RAM. we are seeing a strange behaviour, it runs perfectly fine when we load/run the boot loader from CCS for the first time, but after a software reset the erase code does not erase the flash. Even though there is no error in FCRIS register but the flash contents don't get erased. we verified that the second time also the erase code was running from RAM only. we do disable the interrupts using ROM_IntMasterDisable() before erase code.
linker script:
==============
--retain=g_pfnVectors
MEMORY
{
FLASH (RX) : origin = FLASH_BL_BASE, length = FLASH_BL_LENGTH_EXCLUDING_FUNCS // Flash space for bootloader
FLASH_ACCESS_FUNCS(R) : origin = FLASH_ACCESS_FUNCS_BASE, length = FLASH_ACCESS_FUNCS_LENGTH // Flash space for flash access functions that need to be copied to RAM
FLASH_APP (RWX) : origin = FLASH_APP_BASE, length = FLASH_END // Flash space for IO_Module application
SRAM (RWX) : origin = RAM_BASE, length = RAM_BL_LENGTH // RAM space for bootloader
RAM_FLASH_ACCESS_FUNCS(RWX) : origin = RAM_FLASH_ACCESS_FUNCS_BASE, length = FLASH_ACCESS_FUNCS_LENGTH //RAM space for the Internal Flash access functions to be moved
}
/* Section allocation in memory */
SECTIONS
{
.intvecs: > FLASH_BL_BASE
.text : > FLASH
.cinit : > FLASH
.const : > FLASH
.pinit : > FLASH
.init_array : > FLASH
.vtable : > RAM_BASE
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
.RAMCODE : load = FLASH_ACCESS_FUNCS, run = RAM_FLASH_ACCESS_FUNCS
}
__STACK_TOP = __stack + 4096;
Erase Code:
==============
#pragma CODE_SECTION(eraseInternalFlash,".RAMCODE")
bool eraseInternalFlash( uint32_t startAddr, uint32_t nBytes )
{
bool retCode = false;
BL_ASSERT(startAddr > FLASH_APP_BASE);
BL_ASSERT(nBytes < FLASH_IMAGE_MAX_SIZE );
uint32_t endAddr = startAddr + nBytes;
while(endAddr >= startAddr)
{
//
// Check the arguments.
//
ASSERT(!(startAddr & (FLASH_ERASE_SIZE - 1)));
//
// Clear the flash access and error interrupts.
//
HWREG(FLASH_FCMISC) = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |
FLASH_FCMISC_ERMISC);
//
// Erase the block.
//
HWREG(FLASH_FMA) = startAddr;
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
//
// Wait until the block has been erased.
//
while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE)
{
}
//
// Return an error if an access violation or erase error occurred.
//
if(HWREG(FLASH_FCRIS) & (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS |
FLASH_FCRIS_ERRIS))
{
retCode = false;
break;
}
startAddr += ERASE_BLOCK;
}
if(startAddr >= endAddr)
retCode = true;
return retCode;
}