使用 HAL 时如何擦除 STM32F405RG 中的内部闪存页面(不是扇区!)?

How can I erase an internal flash Page (not sector!) in my STM32F405RG while using HAL?

我在尝试管理 STM32F4 微控制器中的内部闪存时遇到了死胡同。有很多示例,但大多数使用 SPL API 或低级寄存器操作。我正在使用 HAL 库。而且我找不到只擦除一页的功能(在 stm32f4xx_hal_flash.cstm32f4xx_hal_flash_ex.c 中)。 建议的函数,例如 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange) 不允许您仅擦除一页 (2048 kByte),而只能擦除整个扇区(或多个扇区)。 当我尝试使用类似的东西时:

void Internal_Flash_Erase(unsigned int pageAddress) {
while (FLASH->SR & FLASH_SR_BSY);
if (FLASH->SR & FLASH_SR_EOP) {
    FLASH->SR = FLASH_SR_EOP;
}

FLASH->CR |= FLASH_CR_PER;
FLASH->AR = pageAddress;
FLASH->CR |= FLASH_CR_STRT;
while (!(FLASH->SR & FLASH_SR_EOP));
FLASH->SR = FLASH_SR_EOP;
FLASH->CR &= ~FLASH_CR_PER;

}

由于HAL中没有FLASH->AR(地址寄存器),所以出现编译错误。 我发现阅读 RM0090 Reference manual 现在我需要使用 FLASH->CR 而不是 AR 并设置位 FLASH_CR_SNB [3:6] 来选择扇区号。

现在我不知道如何只擦除一页。有必要在内部闪存中创建大容量存储设备以实现以下功能: usbd_storage_if.c 中的 int8_t STORAGE_Write_FS (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) 将 USB 堆栈调用转换为内部闪存。

你不能。您可以擦除的最小部分是一个扇区。

我引用参考手册:

3.6.3 Erase

The Flash memory erase operation can be performed at sector level or on the whole Flash> memory (Mass Erase). Mass Erase does not affect the OTP sector or the configuration sector.

这就是扇区大小不同的原因。考虑到何时可能需要擦除闪存数据,设计您的软件以巧妙地使用这些扇区非常重要。

您可能需要在 RAM 中缓冲整个扇区,以便以类似文件系统的粒度实现闪存写入。

通常: 复制table中的一个flash扇区,修改table中的页,擦除扇区,将table复制到flash扇区

显然我发现了我的错误。我找到的示例适用于 STM32F103xx。而 STM32F103xx 闪存实际上被分成页面(1 或 2 KB)。可以擦除 "sector" 等于擦除 "page"。但是在STM32F4xx的情况下flash-memory被划分为扇区的情况有所不同。