STM32L496 - FLASH页擦除无效

发布于 2025-01-20 17:50:42 字数 2440 浏览 1 评论 0原文

我有一个最初为 STM32L432 构建的项目,我正在将其移植到 STM32L496。但是,我遇到一个问题,ST 作为 HAL 的一部分提供的 HAL_FLASHEx_Erase 函数在一个设备上工作,但在另一个设备上不起作用。这些微控制器的两个闪存空间的组织方式几乎相同(相同的 72 位宽数据读/写)。唯一的区别是 L496 有第二组 FLASH。我看到一些用户遇到了这样的问题;我并没有尝试使用 Bank 2 或接近它;我的最后一个地址是 0x801FFFF。

我可以使用 STCube 编程器手动擦除 FLASH,它会用 FF 填充它。这样就满足了FLASH在写入之前先“擦除”的要求,我就可以写入一块数据了。但我无法通过代码再次修改它。当我第一次写入时,我无法清除刚刚写入的数据块(使用 IAR 中的内存窗口视图进行验证)。

同样,完全相同的代码适用于一个 L 系列,但不适用于另一个 L 系列。有人有什么想法吗?

HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
{
  HAL_StatusTypeDef status = HAL_ERROR;
  uint32_t page_index = 0;

  /* Process Locked */
  __HAL_LOCK(&pFlash);

  /* Check the parameters */
  assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));

  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);

if (status == HAL_OK)
{
  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;

  if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  {
    /* Mass erase to be done */
    FLASH_MassErase(pEraseInit->Banks);

    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);

#if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
  /* If the erase operation is completed, disable the MER1 and MER2 Bits */
  CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));
#else
  /* If the erase operation is completed, disable the MER1 Bit */
  CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1));
#endif      
}
else
{
  /*Initialization of PageError variable*/
  *PageError = 0xFFFFFFFF;
  
  for(page_index = pEraseInit->Page; page_index < (pEraseInit->Page + pEraseInit->NbPages); page_index++)
  {
    FLASH_PageErase(page_index, pEraseInit->Banks);

    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);

    /* If the erase operation is completed, disable the PER Bit */
    CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));

    if (status != HAL_OK)
    {
      /* In case of error, stop erase procedure and return the faulty address */
      *PageError = page_index;
      break;
    }
  }
}

/* Flush the caches to be sure of the data consistency */
FLASH_FlushCaches();
}

/* Process Unlocked */
__HAL_UNLOCK(&pFlash);

return status;

}

I have a project originally built for the STM32L432 that I am porting to the STM32L496. However, I am having an issue where the HAL_FLASHEx_Erase function provided by ST as part of the HAL works on one device but not the other. The two FLASH spaces of these micros are organized virtually identically (same 72-bit wide data read/writes). Only difference is the L496 has a second bank of FLASH. I have seen some users run into issues with this; I am NOT attempting to use Bank 2 or come anywhere close to it; my last address is at 0x801FFFF.

I can manually erase the FLASH using the STCube Programmer, which fills it with FFs. This then satisfies the requirement for the FLASH to be "erased" before writing, and I can write one block of data. But I cannot modify it again via code. As soon as I write the first time, I cannot clear the block of data that I'd just written (verified using the Memory window view in IAR).

Again, exact same piece of code works for one L-series, but not another. Anyone have any ideas?

HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
{
  HAL_StatusTypeDef status = HAL_ERROR;
  uint32_t page_index = 0;

  /* Process Locked */
  __HAL_LOCK(&pFlash);

  /* Check the parameters */
  assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));

  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);

if (status == HAL_OK)
{
  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;

  if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  {
    /* Mass erase to be done */
    FLASH_MassErase(pEraseInit->Banks);

    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);

#if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
  /* If the erase operation is completed, disable the MER1 and MER2 Bits */
  CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));
#else
  /* If the erase operation is completed, disable the MER1 Bit */
  CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1));
#endif      
}
else
{
  /*Initialization of PageError variable*/
  *PageError = 0xFFFFFFFF;
  
  for(page_index = pEraseInit->Page; page_index < (pEraseInit->Page + pEraseInit->NbPages); page_index++)
  {
    FLASH_PageErase(page_index, pEraseInit->Banks);

    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);

    /* If the erase operation is completed, disable the PER Bit */
    CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));

    if (status != HAL_OK)
    {
      /* In case of error, stop erase procedure and return the faulty address */
      *PageError = page_index;
      break;
    }
  }
}

/* Flush the caches to be sure of the data consistency */
FLASH_FlushCaches();
}

/* Process Unlocked */
__HAL_UNLOCK(&pFlash);

return status;

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文