Internal FLash with FreeRTOS

hudson2009 wrote on Friday, October 10, 2008:

Has any one use or have a experience using the embedded flash control (EFC on AT91SAM7x) ?

I manage to run sample basic-internalflash-project from Atmel/ How ever when I try to run it with FreeRTOS, it just crash the RTOS.

Any idea if this possible have EFC running together with FreeRTOS scheduler ?

Thanks.

woops_ wrote on Friday, October 10, 2008:

What does the EFC do? Is it to write to the flash memory while the program is running?

hudson2009 wrote on Thursday, October 23, 2008:

yes writing to flash memory while program is running.
I always end up in the

dabort_handler:
  b dabort_handler

any idea?

woops_ wrote on Thursday, October 23, 2008:

Most MCU do not permit writes to flash where the program is executing.

chaalar wrote on Thursday, October 23, 2008:

How do yo disable your interrupts?
Where do you replace(ram or flash) your flash routines or how?

Caglar

hudson2009 wrote on Thursday, October 23, 2008:

Hi Chaalar,

Thanks for your reply.

1) i am using the portDISABLE_INTERRUPTS(); (not sure it is appropriate)

2) use (.fast) to put into the SRAM as below:

e_FLASH_Result Flash_Command(e_FLASH_Cmd cmd, const int page)__attribute__ ((section (".fast")));

//*****************************************************************************
// Function: Flash_Command
//
// Description:
// Perform a flash command on the specified page number.
// This function does not take a data as a parameter - eg. flash write buffer must be
// setup already if required.
//
// Parameters:
// - cmd  : flash command to perform,
// - page : page number.
//
// Return Value:
// - e_FLASH_Result
//
//*****************************************************************************

e_FLASH_Result Flash_Command(e_FLASH_Cmd cmd, const int page)
{

    e_FLASH_Result ret_val = FLASH_FAIL;
    unsigned int fcr_val = 0x0; //Value to be placed in MC_FCR.
    unsigned int fsr_val; //FSR reg content.
    AT91S_EFC *pEfc; //pointer to EFC.
   
    pEfc = AT91C_BASE_EFC0; // Base address of EFC0 registers.

    switch(cmd)
    {
        case FLASH_LOCK_PAGE:    // Lock a page.
       
          fcr_val = (0x5A << 24) | (page << 8) | 0x2;
          break;

        case FLASH_UNLOCK_PAGE:    // Unlock a page.

          fcr_val = (0x5A << 24) | (page << 8) | 0x4;
          break;

        case FLASH_ERASE_PAGE:    // Erase a page of data - write all zeroes (not 0xff)!           
        case FLASH_WRITE_PAGE:    // Write data to a page (which should be unlocked already).
                               
          fcr_val = (0x5A << 24) | (page << 8) | 0x1;
          break;
       
        default:
               
          return ret_val;
          break;
    }

// Disable interrupts
portDISABLE_INTERRUPTS();

//AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;

    // Wait for flash to be ready.
    do
    {
        fsr_val = pEfc->EFC_FSR;    
    }
    while ((fsr_val & AT91C_MC_FRDY) == 0);
   
    // Now send command.   
    pEfc->EFC_FCR = fcr_val;
   
    // Wait for flash to be ready.
    do
    {
        fsr_val = pEfc->EFC_FSR;
    }
    while ((fsr_val & AT91C_MC_FRDY) == 0);
   
    //Check for errors and return.
    if((fsr_val = pEfc->EFC_FSR) & (AT91C_MC_PROGE | AT91C_MC_LOCKE))
    {
        return ret_val; // Error shown in PROGE or LOCKE bits.
    }   
// Restore interrupts
portENABLE_INTERRUPTS();

    return FLASH_OK;
}

chaalar wrote on Thursday, October 23, 2008:

1) I don’t know how is your linker script, but there is no .fast section in mine(default FreeRTOS linker script) I don’t know
     if linker throws error or silently discards wrong section qualifiers. So I would suggest you to be sure that your function is
     in ram. ( Either check your linker script or map file)
2) It seems that you do not touch value of MC_FMR register in your flash routines. However, it must be set to a reasonable
     for a safe flash programming. As far as I remember, for writing to flash and for re-programming NVM bits you have to
     use two different FMR settings. In your case the default may be ok, but again I would suggest a check. This can be also
    change according to your startup file. So one working with Atmel example may not work with FreeRTOS.
3) Last but not the least, you’re returning from your programming routine with interrupts disabled if something goes wrong
     with the programming. I think this is the problem you have at the moment.

Regards,
Caglar