如何为STM32L475板交换闪存中的两个区域?

Posted

技术标签:

【中文标题】如何为STM32L475板交换闪存中的两个区域?【英文标题】:How to swap two regions in FLASH memory for STM32L475 board? 【发布时间】:2019-12-02 13:20:07 【问题描述】:

我正在开发 STM32L475 IoT 套件,它是一个 ARM M4 Cortex 设备。我想交换两个闪存区域。我正在使用的主板有两个用于闪存的存储库,每个存储库的大小为 512KB。所以我有 1 MB 闪存。我读到要交换闪存的内容,您必须先将其解锁,然后将其擦除,然后再写入并在操作结束后锁定闪存。

还有另一个限制,即一次只能复制 2KB 的内存,这被定义为一个页面。所以只能逐页复制内存。对于我的应用程序,如果满足某些条件,我必须交换存储在闪存中的应用程序 1 和 2。虽然这两个应用程序都被分配了 384 KB 的内存,但它们实际上都使用了更少的内存(例如 264 KB)。

我尝试按照上述步骤操作,但它不起作用。这是我尝试过的代码:-

    #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;
     

这里交换缓冲区用于在交换时将每个页面(2KB)临时存储为缓冲区。此外,变量限制存储了应用程序 1 和 2 的最大大小,以便在内存大小不相等的情况下进行交换时不会出现错误,如前所述。所以基本上我是逐页交换,一次只有 2 KB。

谁能找出代码中有什么问题?

谢谢, 舍图

【问题讨论】:

【参考方案1】:

2K 是 2048 字节,而不是 2024。修复整个代码中的增量。

还有一个限制,一次只能复制 2KB 的内存

还有一点,这些内存块必须对齐到 2KB

这个地址

#define APPLICATION2_ADDRESS 0x08076400

没有正确对齐,它的值应该能被 2048 (0x800) 整除。

【讨论】:

以上是关于如何为STM32L475板交换闪存中的两个区域?的主要内容,如果未能解决你的问题,请参考以下文章

STM32L476 flash 页擦除没有效果

stm32L476 - 擦除闪存

stm32l0:执行MI命令失败。使用 vFlashErase 数据包擦除闪存时出错

灵动微MM32L052TW可替换STM32F042F6P6

如何从 TrueStudio 调试和烧写 Nucleo32 板?

了解STM32参考手册中的写入flash流程