Content originally posted in LPCWare by mroe on Mon Aug 04 18:31:10 MST 2014
Hello,
I am trying to use IAP to store a variable in NV Flash RAM that will retain its state after reboot.
I am using my own linker script and storing the variable at location 0x6000 far away from anything else.
This the memory is being properly written to when I initially debug the application, but not after reboot.  After rebooting, the code crashes when I try to erase the iap sector before writing to it.
Here is the relevant portion of my iap code:
int iap_erase_sector(unsigned int sector_start, unsigned int sector_end)
{
    unsigned int command[5];
    unsigned int result[4];
    command[0] = ERASE_SECTOR; // 52
    command[1] = (unsigned int)sector_start;
    command[2] = (unsigned int)sector_end;
    command[3] = SystemCoreClock / 1000;
    iap_entry(command, result);
    return result[0];
}
int iap_prepare_sector(unsigned int sector_start, unsigned int sector_end)
{
    unsigned int command[5];
    unsigned int result[4];
    command[0] = PREPARE_SECTOR; // 50
    command[1] = (unsigned int) sector_start;
    command[2] = (unsigned int) sector_end;
    iap_entry(command, result);
    return result[0];
}
int iap_copy_ram_to_flash(void* ram_address, void* flash_address, unsigned int count)
{
    unsigned int command[5];
    unsigned int result[4];
    command[0] = COPY_RAM_TO_FLASH; // 51
    command[1] = (unsigned int)flash_address;
    command[2] = (unsigned int)ram_address;
    command[3] = count;
    command[4] = SystemCoreClock / 1000;
    iap_entry(command, result);
    return result[0];
}
int iap_write(void *ram_address, void *flash_address, unsigned int count, unsigned int sector, unsigned int sector_size)
{
   int iap_status = 0; // CMD_SUCCESS
    SystemCoreClockUpdate();
    iap_status = iap_prepare_sector(sector, sector_size);
    if (iap_status != 0) return iap_status;
    // after reboot, this crashes when I try to erase the sector
    iap_status = iap_erase_sector(sector, sector_size);
    if (iap_status != 0) return iap_status;
    iap_status = iap_prepare_sector(sector, sector_size);
    if (iap_status != 0) return iap_status;
    iap_status = iap_copy_ram_to_flash(ram_address, flash_address, count);
    if (iap_status != 0) return iap_status;
    return iap_status;
}
Here is the relevant section of my linker script:
    .var (0x6000) :
    {
        KEEP(*(.var*))
    } > MFlash32
Here is the relevant section of my calling code:
__CRP const unsigned int CRP_WORD = CRP_NO_CRP;
static unsigned char var_temp[] = {0, 1, 1, 1, 1, 1, 1, 1, 1};
__attribute__ ((section(".var"))) unsigned char var[256];
int main()
{
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 16);
if (var[0] == 0)
{
                // after reboot, this crashes when I try to erase the sector
                // iap_write(ram_address, flash_address, count, sector, sector_size)
iap_write(&var_temp, (void *)0x6000, 256, 6, 7);
}
while (1)
{
}
return 0;
}
Thanks in advance for your help.