OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5094|回复: 8

STM32G031 FLASH 擦除操作 报错,进错误中断

[复制链接]

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2019-9-9
在线时间
20 小时
发表于 2022-2-22 17:16:26 | 显示全部楼层 |阅读模式
int main(void)
{
  APP_Init();
  HAL_StatusTypeDef  flash_status;
  u32 u32flash_err = 0;
  while (1)
  {

                FLASH_EraseInitTypeDef flash_init;
                flash_init.TypeErase = FLASH_TYPEERASE_PAGES;
                flash_init.Banks = FLASH_BANK_1;
                flash_init.Page = 0x08005000;
                flash_init.NbPages = 1;
                flash_status = HAL_FLASHEx_Erase(&flash_init, &u32flash_err);        //擦除这个扇区
                if(flash_status != HAL_OK)
                {
                        printf("flash =  %d \r\n",u32flash_err);
                }
          
         APP_PollingTask();

  }

}



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2019-9-9
在线时间
20 小时
 楼主| 发表于 2022-2-22 17:18:14 | 显示全部楼层
就这么简单的一个测试函数,不知道错在哪里,看了很久感觉是HAL库的问题。
/**
  * @brief  FLASH Erase structure definition
  */
typedef struct
{
  uint32_t TypeErase;   /*!< Mass erase or page erase.
                             This parameter can be a value of @Ref FLASH_Type_Erase */
  uint32_t Banks;       /*!< Select bank to erase.
                             This parameter must be a value of @ref FLASH_Banks
                             (FLASH_BANK_BOTH should be used only for mass erase) */
  uint32_t Page;        /*!< Initial Flash page to erase when page erase is enabled
                             This parameter must be a value between 0 and (FLASH_PAGE_NB - 1) */
  uint32_t NbPages;     /*!< Number of pages to be erased.
                             This parameter must be a value between 1 and (FLASH_PAGE_NB - value of initial page)*/
} FLASH_EraseInitTypeDef;





/**
  * @brief  Perform a mass erase or erase the specified FLASH memory pages.
  * @param[in]  pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
  *         contains the configuration information for the erasing.
  * @param[out]  PageError Pointer to variable that contains the configuration
  *         information on faulty page in case of error (0xFFFFFFFF means that all
  *         the pages have been correctly erased)
  * @retval HAL Status
  */
HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
{
  HAL_StatusTypeDef status;
  uint32_t index;

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

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

  /* Reset error code */
  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;

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

  if (status == HAL_OK)
  {
#if !defined(FLASH_DBANK_SUPPORT)
    /* For single bank product force Banks to Bank 1 */
    pEraseInit->Banks = FLASH_BANK_1;
#endif

    if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASS)
    {
      /* Proceed to Mass Erase */
      FLASH_MassErase(pEraseInit->Banks);

      /* Wait for last operation to be completed */
      status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
    }
    else
    {
      /*Initialization of PageError variable*/
      *PageError = 0xFFFFFFFFU;

      for (index = pEraseInit->Page; index < (pEraseInit->Page + pEraseInit->NbPages); index++)
      {
        /* Start erase page */
        FLASH_PageErase(pEraseInit->Banks, index);

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

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

      /* If operation is completed or interrupted, disable the Page Erase Bit */
      CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
    }
  }

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

  /* return status */
  return status;
}

回复 支持 反对

使用道具 举报

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2019-9-9
在线时间
20 小时
 楼主| 发表于 2022-2-22 17:22:58 | 显示全部楼层
对页的操作原函数如下:STM32G0系列对字节写入改成了64位写一次,不知道为什么这样操作,有点坑,
并且看到一位前辈说,STM32G0无法重复的写内存,如果第一次在内存中写入0xFF后,没有进行擦除操作是没法继续写入的,
所以在操作中加了擦除操作,就出现了上述的问题, HAL库提供的擦除函数 ,一擦出直接返回erro,看了其他F系列芯片好像没这个问题

void STMFLASH_Write(u32 WriteAddr,uint64_t *pBuffer,int WordSize)       
{
        static u32 u32sector_addr;           //扇区地址
        u32 u32retain_addr;
        u32 u32flash_err = 0;
        u16 i;   
        u32 offaddr;   //去掉0X08000000后的地址
        FLASH_EraseInitTypeDef flash_init;
        HAL_StatusTypeDef  flash_status;
        if(WriteAddr<STM32_ADDR_FLASH_SECTOR_0||(WriteAddr>=(STM32_ADDR_FLASH_SECTOR_0+1024*STM32_FLASH_SIZE)))return;//非法地址
       
        HAL_FLASH_Unlock();                                        //解锁
        offaddr=WriteAddr-STM32_ADDR_FLASH_SECTOR_0;                //实际偏移地址.
        u32retain_addr= offaddr/STM_SECTOR_SIZE;                        //扇区地址  0~63 for STM32G031
       
        if(u32sector_addr != u32retain_addr)
        {
                u8FlashErase_Flag = 1;
                u32sector_addr = u32retain_addr;
        }
       
        if(u8FlashErase_Flag)                                //需要擦除
        {
                u8FlashErase_Flag = 0;
                u32sector_addr = u32sector_addr*0x800 + STM32_ADDR_FLASH_SECTOR_0;
                flash_init.TypeErase = FLASH_TYPEERASE_PAGES;
                flash_init.Banks = FLASH_BANK_1;
                flash_init.Page = u32sector_addr;
                flash_init.NbPages = 1;
                flash_status = HAL_FLASHEx_Erase(&flash_init, &u32flash_err);        //擦除这个扇区
               
                if(flash_status != HAL_OK)
                {
                        printf("flash =  %d \r\n",u32flash_err);
                }
        }
               
        for(i = 0; i< WordSize; i++ )
        {
                if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, WriteAddr+(i*8), pBuffer[i]) != HAL_OK)        //一次写入64字节
                {
                        printf("写入异常!\r\n");
                }       
        }

         
        HAL_FLASH_Lock();                //上锁
}



回复 支持 反对

使用道具 举报

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2019-9-9
在线时间
20 小时
 楼主| 发表于 2022-2-23 13:38:44 | 显示全部楼层
问题解决了, 本质原因是因为Flash标志位PGSERR和PGAERR上电置位,一直置位无法改变,想不明白为什么。后续看了论坛很多其他小伙伴的问题,都和我对不上,都快放弃了,最后发现是 为了调试方便看门狗初始化被我关了,但是我依然在while中喂狗,把喂狗屏蔽就可以了,好吧,以后不用的代码一定要屏蔽
回复 支持 反对

使用道具 举报

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2019-9-9
在线时间
20 小时
 楼主| 发表于 2022-2-23 13:39:19 | 显示全部楼层
Heart丶 发表于 2022-2-22 17:22
对页的操作原函数如下:STM32G0系列对字节写入改成了64位写一次,不知道为什么这样操作,有点坑,
并且看 ...

这里的page参数不对,不能填地址,填页码号
回复 支持 反对

使用道具 举报

0

主题

10

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
288
金钱
288
注册时间
2020-9-1
在线时间
36 小时
发表于 2022-3-9 14:35:44 | 显示全部楼层
楼上说的正确,楼主PAGE参数有问题,可以参考ST例程。
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2022-3-9
在线时间
26 小时
发表于 2022-3-24 15:52:37 | 显示全部楼层
你好,想请教个问题,我使用的是STM32G030C8T6进行片内Flash的写过程中,MCU一直死机,是由什么原因引起的呢
回复 支持 反对

使用道具 举报

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2019-9-9
在线时间
20 小时
 楼主| 发表于 2022-4-4 10:19:43 | 显示全部楼层
tanganrong 发表于 2022-3-9 14:35
楼上说的正确,楼主PAGE参数有问题,可以参考ST例程。

这个有点忘了,最开始写确实是参数不对,后面改了一版,但STM32G0系列的HAL_FLASHEx_Erase函数和STM32F系列的不一样了,参数设置不太相同,这个大家注意一下
回复 支持 反对

使用道具 举报

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2019-9-9
在线时间
20 小时
 楼主| 发表于 2022-4-4 10:20:49 | 显示全部楼层
ZJHZXK 发表于 2022-3-24 15:52
你好,想请教个问题,我使用的是STM32G030C8T6进行片内Flash的写过程中,MCU一直死机,是由什么原因引起的 ...

在每次写前加一个delay
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 17:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表