STM32L476 flash 页擦除没有效果

Posted

技术标签:

【中文标题】STM32L476 flash 页擦除没有效果【英文标题】:STM32L476 flash Page erase has no effect 【发布时间】:2021-10-20 05:40:34 【问题描述】:

我有一个问题,我尝试将值写入 STM32L476 中的闪存页(第 256 页@0x08080000)。但是,我在闪存状态寄存器中设置了 PROGERR 错误。这意味着尝试将非零值写入未擦除到 0xFFFFFFFF 的闪存位置。

我确实像这样擦除闪存:

uint32_t page = 256;
HAL_FLASH_Unlock();
FLASH_PageErase(page, FLASH_BANK_BOTH);
FLASH_WaitForLastOperation((uint32_t) FLASH_TIMEOUT_VALUE);
CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
HAL_FLASH_Lock();

但是,当我在擦除后检查闪存内容时,它并没有改变旧的、未擦除的值。

我试着改成

uint32_t page = 256;
HAL_FLASH_Unlock();
SET_BIT(FLASH->SR, (FLASH_FLAG_ALL_ERRORS));
FLASH_WaitForLastOperation((uint32_t) FLASH_TIMEOUT_VALUE);
FLASH_PageErase(page, FLASH_BANK_BOTH);
FLASH_WaitForLastOperation((uint32_t) FLASH_TIMEOUT_VALUE);
CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
HAL_FLASH_Lock();

但无济于事。

我是否遗漏了一些明显的东西?

【问题讨论】:

注意,页码从 0 开始,但银行编号从 1 开始 【参考方案1】:

每个银行有 256 页,编号为 0-255。因此,第 256 页无效。地址 0x08080000 的闪存是 bank 2 的第 0 页。无效的页码将导致 FLASH_PageErase 断言失败或使用不同的值。

FLASH_BANK_BOTHFLASH_PageErase 无效,因此也会导致断言失败或使用不同的银行值。您一次只能擦除一个银行。否则,从 flash 运行会导致崩溃,因为您不能同时读取和写入单个 bank。

要擦除0x08080000 处的页面,您需要执行FLASH_PageErase(page, FLASH_BANK_2 ); 并将page 设置为0

【讨论】:

刚刚自己发现了这个问题。这在技术上是不正确的:FLASH_PageErase 只是用0xFF 掩盖页码并检查是否Banks & FLASH_BANK_1 != 0。所以用FLASH_BANK_BOTH256 擦除实际上是擦除bank 1 page 0。FLASH_PageErase() 不会失败。它确实删除了错误的页面。 它会屏蔽并检查第 1 页,但这是在完成 assert_param(IS_FLASH_PAGE(Page));assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks)); 之后,它们会检查有效的页面并且只设置一个银行。 虽然我实际上对它不够熟悉,无法知道这些检查是否在非调试版本中被排除(似乎取决于USE_FULL_ASSERT)。无论哪种方式,都很好地自己解决问题并提供有用的答案。 啊,是的,USE_FULL_ASSERT 独立于 STM32CubeIDE 中的构建配置,目前在项目中没有设置。【参考方案2】:

发现问题。它与 STM32L476 上的双组闪存有关。擦除第 256 页会改为擦除 bank 1 中的第 0 页。

正确检查并删除正确的页面如下所示:

uint32_t page = 256;
HAL_FLASH_Unlock();
FLASH_PageErase(page & 0xFF, (page & 0x100) == 0 ? FLASH_BANK_1 : FLASH_BANK_2);
FLASH_WaitForLastOperation((uint32_t) FLASH_TIMEOUT_VALUE);
CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
HAL_FLASH_Lock();

【讨论】:

以上是关于STM32L476 flash 页擦除没有效果的主要内容,如果未能解决你的问题,请参考以下文章

STM32L476应用开发之一:初次使用

最终启动序列中的错误 - STM32L476 的 Eclipse 系统工作台调试

STM32L476 和 CubeMX 上带有 DMA 的 SD 卡没有中断

使用 STM32L476RG 时出现 UART 溢出错误

STM32L476的RTC使用问题记录

STM32L476应用开发之二:模拟量数据采集