STM32F103 HAL_NVIC_SystemReset()函数软件复位失败解决办法

项目场景:

通过串口传输数据进行信息配置,配置以后需要进行软件复位


问题描述

        采用HAL库的HAL_NVIC_SystemReset()软件复位函数不能进行软件复位

        查询资料后操作寄存器直接进行软件复位代码如下:

void Sys_Soft_Reset(void)
{   
	SCB->AIRCR =0X05FA0000|(uint32_t)0x04;	  
} 
   通过直接操作寄存器方法进行软件复位并没有解决问题,又采用了关闭所有中断的方法,代码如下:
__set_FAULTMASK(1);			//关闭所有中断
HAL_NVIC_SystemReset();	    //进行软件复位

        采用了关闭所有中断的方法,解决了问题,可以进行软件复位了,但是在继续写程序调试过程中又出现了,软件复位的程序卡住的现象

        


解决方案:

最后直接修改了复位函数的程序,代码如下:

源代码:

1 __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
2 {
3   __DSB();                                                          /* Ensure all outstanding memory accesses included
                                                                       buffered write are completed before reset */
4   SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
5                            (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
6                             SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
7   __DSB();                                                          /* Ensure completion of memory access */

8   for(;;)                                                           /* wait until reset */
9   {
10    __NOP();
11  }
12 }

修改之后的代码:

1 __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
2 {
3   __DSB();                                                          /* Ensure all outstanding memory accesses included
                                                                       buffered write are completed before reset */
4   SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
5                            (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
6                             SCB_AIRCR_VECTRESET_Msk    );         /* Keep priority group unchanged */
7   __DSB();                                                          /* Ensure completion of memory access */

8   for(;;)                                                           /* wait until reset */
9   {
10    __NOP();
11  }
12 }

总结:将第6行的SCB_AIRCR_SYSRESETREQ_Msk修改为SCB_AIRCR_VECTRESET_Msk解决问题。

### 解决方案分析 在FreeRTOS多线程环境下,当调用`NVIC_SystemReset()`触发系统复位后,操作系统可能因硬件或软件配置不当而无法正常启动。以下是可能导致该问题的原因及其对应的解决方案: #### 1. **硬件初始化未重新执行** 如果系统复位后未能正确重新初始化必要的硬件模块(如时钟、存储器映射等),可能会导致操作系统加载失败[^1]。 - 确保在复位后的引导代码中重新初始化所有依赖的外设。 - 特别关注时钟树配置和内存控制器设置,这些通常需要手动恢复到初始状态。 #### 2. **中断控制器状态异常** 复位后,如果中断控制器的状态未被正确重置,某些中断可能仍然处于挂起状态或优先级配置错误,从而干扰操作系统的正常运行[^3]。 - 使用`NVIC->ICPR`寄存器清除所有待处理的中断。 - 配置`NVIC_InitTypeDef`结构体以重新设定中断优先级分组和各中断源的具体优先级[^4]。 #### 3. **Flash访问模式冲突** 对于一些微控制器(如i.MXRT系列),连续读取模式下的Flash配置可能在软复位后失效,进而影响程序加载过程[^2]。 - 在复位逻辑中加入针对Flash控制器的额外初始化步骤,确保其工作模式与应用程序需求一致。 #### 4. **堆栈指针丢失或损坏** `NVIC_SystemReset()`会清零部分寄存器,包括堆栈指针(SP)。如果后续代码尝试使用未经初始化的堆栈,则会导致崩溃。 - 检查复位向量表中的初始堆栈指针值是否正确指向有效的RAM区域。 - 可通过链接脚本或启动代码显式指定默认堆栈地址。 #### 示例代码:复位前保存并恢复上下文 ```c #include "core_cm4.h" void SaveContext(void) { __disable_irq(); // 关闭全局中断以防数据竞争 volatile uint32_t *pStackTop = (uint32_t *)__get_MSP(); while (*pStackTop == 0xFFFFFFFF); // 找到有效堆栈顶部 /* 将当前MSP及其他关键寄存器备份至非易失性存储 */ } void RestoreContext(void) { /* 从非易失性存储恢复先前保存的MSP和其他必要参数 */ __set_MSP(*(volatile uint32_t *)RESTORE_ADDRESS); __enable_irq(); // 开启全局中断继续正常流程 } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值