简体   繁体   English

如何为STM32L475板交换FLASH存储器中的两个区域?

[英]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. 我正在研究STM32L475 IoT套件,它是ARM M4 Cortex设备。 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. 我正在使用的板上有两个用于闪存的存储区,每个存储区的大小为512KB。所以我有1 MB的闪存。 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. 还有一个限制,一次只能复制2KB的内存,这被定义为一个页面。 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. 对于我的应用程序,如果满足某些条件,我必须交换存储在闪存中的应用程序1和2。 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). 尽管两个应用程序均分配了384 KB的内存,但实际上它们都使用的内存少于该应用程序(例如264 KB)。

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. 在此,交换缓冲区用于在交换时将每个页面(2KB)临时存储为缓冲区。 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. 同样,变量限制存储了应用程序1和2的最大大小,因此,如前所述,在内存大小不相等的情况下进行交换时不会出错。 So basically I am swapping page by page, that is only 2 KB at a time. 所以基本上我是一页一页地交换,一次只交换2 KB。

Can anyone figure out whats wrong in the code? 任何人都可以找出代码中的错误吗?

Thanks, 谢谢,
Shetu 舍图

2K is 2048 bytes , not 2024. Fix the increments all over the code. 2K是2048字节 ,而不是2024。固定整个代码的增量。

There is another restriction that at a time only 2KB of memory can be copied 还有一个限制,一次只能复制2KB的内存

and yet another, that these memory blocks must be aligned to 2KB . 另外,这些存储块必须对齐2KB

This address 这个地址

#define APPLICATION2_ADDRESS 0x08076400

is not properly aligned, it should have a value that is evenly divisible by 2048 (0x800). 未正确对齐,则其值应可被2048(0x800)整除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM