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:-
#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
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).