memorystm32swapflash-memorystm32ldiscovery

How to swap two regions in FLASH memory for STM32L475 board?


I am working on STM32L475 IoT kit which is an ARM M4 Cortex device. I want to swap two regions of flash memory. The board I am using has two banks for flash memory each having a size of 512KB.So I have 1 MB Flash memory. I read that for swapping contents of flash memory you have to first unlock it, then erase it and then write it and lock the flash memory after the operation is over.

There is another restriction that at a time only 2KB of memory can be copied which is defined as a page. So only page by page copying of memory is possible. For my application I have to swap application 1 and 2 which are stored in FLASH memory,if some conditions are met. Though both the applications have been allotted 384 KB of memory each but both of them actually use less memory than that(say 264 KB for example).

I tried to follow the above steps but its not working. Here is the code which I tried:-

enter image description here

    #define APPLICATION_ADDRESS     0x0800F000
    #define APPLICATION2_ADDRESS    0x0806F800
    #define SWAP_ADDRESS            0x0806F000

    boolean swap(void)
    {
      char *app_1=( char*) APPLICATION_ADDRESS;//points to the 1st address of application1
      char *app_2=(char*) APPLICATION2_ADDRESS;//points to the 1st address of application2

        int mem1 = getMemorySize((unsigned char*)APPLICATION_ADDRESS);//returns the number of bytes in Application1
        int mem2 = getMemorySize((unsigned char*)APPLICATION2_ADDRESS);//returns the number of bytes in Application2
        int limit;
        if(mem1>mem2)
            limit= mem1;
        else
            limit= mem2;

        Unlock_FLASH();

       int lm = limit/2048;

        for(int i=1; i<=lm; i++,app_1+=2048,app_2+=2048)
        {
            int *swap = (int *)SWAP_ADDRESS;

            Erase_FLASH(swap);
            Write_FLASH(app_1, swap);
            Erase_FLASH(app_1);
            Write_FLASH(app_2, app_1);
            Erase_FLASH(app_2);
            Write_FLASH(swap, app_2);
        }

            Lock_FLASH();
        return TRUE;
    }

    void Unlock_FLASH(void)
    {
        while ((FLASH->SR & FLASH_SR_BSY) != 0 );
            // Check if the controller is unlocked already
            if ((FLASH->CR & FLASH_CR_LOCK) != 0 ){
            // Write the first key
            FLASH->KEYR = FLASH_FKEY1;
            // Write the second key
            FLASH->KEYR = FLASH_FKEY2;
            }
    }

    void Erase_FLASH(int *c)
    {
        FLASH->CR |= FLASH_CR_PER; // Page erase operation
    FLASH->ACR = c;     // Set the address to the page to be written
    FLASH->CR |= FLASH_CR_STRT;// Start the page erase

    // Wait until page erase is done
    while ((FLASH->SR & FLASH_SR_BSY) != 0);
    // If the end of operation bit is set...
    if ((FLASH->SR & FLASH_SR_EOP) != 0){
        // Clear it, the operation was successful
        FLASH->SR |= FLASH_SR_EOP;
    }
    //Otherwise there was an error
    else{
        // Manage the error cases
    }
    // Get out of page erase mode
    FLASH->CR &= ~FLASH_CR_PER;
    }

    void Write_FLASH(int *a, int *b)
   {
    for(int i=1;i<=2048;i++,a++,b++)
    {
    FLASH->CR |= FLASH_CR_PG;                   // Programing mode
    *(__IO uint16_t*)(b) = *a;       // Write data

    // Wait until the end of the operation
    while ((FLASH->SR & FLASH_SR_BSY) != 0);
    // If the end of operation bit is set...
    if ((FLASH->SR & FLASH_SR_EOP) != 0){
        // Clear it, the operation was successful
         FLASH->SR |= FLASH_SR_EOP;
    }
    //Otherwise there was an error
    else{
        // Manage the error cases
    }
    }
    FLASH->CR &= ~FLASH_CR_PG;
}

    void Lock_FLASH(void)
    {
        FLASH->CR |= FLASH_CR_LOCK;
    } 

Here swap buffer is used to store each page(2KB) temporarily as a buffer while swapping. Also the variable limit stores the maximum size out of application 1 and 2 so that there is no error while swapping in case of unequal memory sizes as mentioned before. So basically I am swapping page by page, that is only 2 KB at a time.

Can anyone figure out whats wrong in the code?

Thanks,
Shetu


Solution

  • 2K is 2048 bytes, not 2024. Fix the increments all over the code.

    There is another restriction that at a time only 2KB of memory can be copied

    and yet another, that these memory blocks must be aligned to 2KB.

    This address

    #define APPLICATION2_ADDRESS 0x08076400
    

    is not properly aligned, it should have a value that is evenly divisible by 2048 (0x800).