STM32
直播中

徐生财

10年用户 848经验值
擅长:MEMS/传感技术
私信 关注
[问答]

stm32F401RC操作Flash后调NVIC_SystemReset() 卡死怎么解决?

最近在做 STM32F401RC 开发时发现,在操作Flash后直接调用NVIC_SystemReset() 会极大概率卡死,不能正常复位。代码是基于stm32Cubemx,利用Hal库开发的。

为了调查,找了一个官方的demo 简单试了下擦除Flash,然后调NVIC_SystemReset()

void EraseFlash_Sample()
{
        uint32_t FirstSector = 0, NbOfSectors = 0, Address = 0;
        uint32_t SectorError = 0;
        __IO uint32_t data32 = 0 , MemoryProgramStatus = 0;

        /*Variable used for Erase procedure*/
        static FLASH_EraseInitTypeDef EraseInitStruct;
        
          /* Unlock the Flash to enable the flash control register access *************/
  HAL_FLASH_Unlock();

  /* Erase the user Flash area
    (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/

  /* Get the 1st sector to erase */
  FirstSector = GetSector(0x08008000);
  /* Get the number of sector to erase from 1st sector*/
  NbOfSectors = GetSector(0x08008033) - FirstSector + 1;

  /* Fill EraseInit structure*/
  EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
  EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
  EraseInitStruct.Sector = FirstSector;
  EraseInitStruct.NbSectors = NbOfSectors;
  if(HAL_FLASHEx_Erase( EraseInitStruct,  SectorError) != HAL_OK)
  {
    /*
      Error occurred while sector erase.
      User can add here some code to deal with this error.
      SectorError will contain the faulty sector and then to know the code error on this sector,
      user can call function 'HAL_FLASH_GetError()'
    */
    /*
      FLASH_ErrorTypeDef errorcode = HAL_FLASH_GetError();
    */
    Error_Handler();
  }

  /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
     you have to make sure that these data are rewritten before they are accessed during code
     execution. If this cannot be done safely, it is recommended to flush the caches by setting the
     DCRST and ICRST bits in the FLASH_CR register. */
  __HAL_FLASH_DATA_CACHE_DISABLE();
  __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();

  __HAL_FLASH_DATA_CACHE_RESET();
  __HAL_FLASH_INSTRUCTION_CACHE_RESET();

  __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
  __HAL_FLASH_DATA_CACHE_ENABLE();
}


int main(void)
{
//初始化代码这里省略了xxx
    /* USER CODE BEGIN WHILE */
        HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);
        Delayms(1000);
        EraseFlash_Sample();
//        //__set_FAULTMASK(1); //这行代码加与不加效果相同
        //Delayms(1000);   //这只是用while循环加计数的方式写的一个简单的延时函数
        NVIC_SystemReset()
        while(1)
        {}
    /* USER CODE END WHILE */

}



发现几乎是百分百会卡死,无法正常复位。(验证是否正常重启的方法是控制一个LED灯闪烁,这里没有体现)
在调用NVIC_SystemReset()之前,看过Flash的寄存器,没有发现异常。
此外,如果把main函数中的  Delayms(1000); 解除注释,也就是在擦除Flash后等待1s,再调NVIC_SystemReset() ,发生卡死的概率就变得很小。
请问题大佬有遇到过类似的问题么?

回帖(1)

周志光

2024-4-7 16:40:22
楼主,您好。先确定关闭擦除后,是不是正常复位?
如果关闭后正常,说明擦除的地址不对,0x08008033这个地址是不是还在程序的代码范围内。建议看一下HEX文件或者BIN文件的大小。确定擦除FLASH的地址不要在程序的范围内。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分