
最近在做 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() ,发生卡死的概率就变得很小。 请问题大佬有遇到过类似的问题么? 谢谢! |
USB_CDC_HOST 标准库里边USBH_DeAllocate_AllChannel()函数的疑问?
STM32部署机器学习算法硬件至少要使用哪个系列的芯片?
重新配置SCB->VTOR = 0x08010000后,再次复位,程序异常,发现不进tick中断,IIC读数卡死在准备查询循环中。
STM32407 使用串口闲时中断+DMA方式接收最大接收字节是多少
uboot初始化IIC1,跳转到应用程序中后,先读一字节AT24C04的数据,然后初始化IIC1(未复位),再读一字节AT24C04时,有概率一直检测到IIC处于busy状态。
STM32F407的flash读写问题
keil调试阶段无法进行仿真,能进到仿真界面,但是无法执行程序,这个怎么解决?
STM32F4的IO口5V容忍问题
询问STM32F407两种USB可以实现的功能
TOF传感器(VL53L5),无法得到data ready
如果关闭后正常,说明擦除的地址不对,0x08008033这个地址是不是还在程序的代码范围内。建议看一下HEX文件或者BIN文件的大小。确定擦除FLASH的地址不要在程序的范围内。
您好, 这个擦除的地址是在程序地址以外的。 而且我尝试过 擦除flash之后,延时等待1s,然后再调用reset接口,就是可以正常复位的。 也就是说本身这个复位接口也没问题。 我怀疑是不是可能调用擦除flash接口后,即使返回了OK,但是实际硬件状态还没有恢复正常,对复位产生了影响? 我不是很了解软复位的根本原理,但是我发现NRST引脚的电平发生了变化,因此用示波器进行了监测。“擦除flash后延时1s再调reset,正常复位” , “擦除flash后立刻调reset,复位异常”的情况分别进行了截图
补发示波器监测NRST引脚图片
擦除flash后立刻调reset,复位异常
擦除flash后延时1s再调reset,复位正常
感谢回复。 我使用的是HAL库的API,API返回OK后,不是就代表擦除完成了么... 不过后面我会试下的
波形上看,擦除后直接调reset 接口,出现了多次复位波形(写多个字节时也是相似的现象),但是如果只擦除,不调reset,mcu却并没有真的被reset
后门我在线仿真实施
根据我附件上传的图片来看,刚擦除flash就立刻调用reset接口,NRST管脚的电平降低又拉高,但没有拉倒正常高电平之前又重新降低,再拉高,反复多次后,在拉高。 这时就已经卡死了... 现象上感觉看非常奇怪...
(擦除flash后 delay 1s 再调用reset接口,NRST管脚的电平就只有一次降低又拉高,且拉高到正常高电平,问题不发生)