C++怎么在系统异常复位时读取复位标志位(RCC Reset Flags)判断死机原因

夏静姑娘_2412

夏静姑娘_2412

2026-10-22

675人浏览

原创

复位后须立即读取rcc_csr寄存器,因lpwrrstf、wwdgrstf、iwdgrstf等标志仅在复位退出后短暂有效,一旦执行rcc_clearflag()或hal_rcc_getresetsource()等操作即被清零;正确做法是在startup文件跳转main前、systeminit开头或hal_init之前完成读取,并用__attribute__((section(".noinit")))持久化保存原始值。

c++怎么在系统异常复位时读取复位标志位(rcc reset flags)判断死机原因

复位后第一时间读取 RCC_CSR 寄存器,别等 main() 才开始

系统异常复位(如看门狗超时、软件复位、电源掉电)发生后,RCC 的复位标志位(RCC_CSR 寄存器中 RCC_CSR_LPWRRSTF、RCC_CSR_WWDGRSTF、RCC_CSR_IWDGRSTF 等)只在复位退出后短暂有效——一旦执行了 RCC_ClearFlag() 或任意复位相关初始化(比如 HAL_RCC_OscConfig()),这些标志就会被清零。很多开发者在 main() 里才去查,结果读到全是 0。

正确做法是:把读取逻辑放在启动文件(如 startup_stm32f4xx.s)跳转到 main() 之前,或在 SystemInit() 开头强制插入。如果你用的是 HAL 库,务必在 HAL_Init() 和 SystemClock_Config() 之前完成读取。

  • RCC->CSR 是只读寄存器,直接读取即可,无需使能时钟
  • 不要调用 __HAL_RCC_CLEAR_RESET_FLAGS() 或 HAL_RCC_GetResetSource() —— 它们内部会清标志
  • 若使用 CMSIS,可直接用 RCC->CSR & RCC_CSR_IWDGRSTF 判断,避免宏展开引入隐式清除

区分 IWDG/WWDG/LPWRRSTF,别只看一个 bit

不同复位源对应不同标志位,但它们可能共存(比如低功耗唤醒失败同时触发 LPWRRSTF 和 IWDGRSTF)。单独检查 RCC_CSR_IWDGRSTF 不足以确认是独立看门狗导致的死机——得排除其他干扰。

典型组合判断逻辑如下(复位后立即执行):

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
uint32_t csr = RCC->CSR;
if (csr & RCC_CSR_IWDGRSTF) {
    // 可能是 IWDG 超时,但需先确认没被其他复位覆盖
    if (!(csr & (RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF | RCC_CSR_PINRSTF))) {
        // 排除软复位、上电、引脚复位干扰,才较可信
    }
}
if (csr & RCC_CSR_WWDGRSTF) {
    // WWDG 早于窗口下限触发,通常意味着中断未及时喂狗或中断被屏蔽
}
if (csr & RCC_CSR_LPWRRSTF) {
    // 深度睡眠唤醒失败或 VDDA 电压跌落,注意和 PVD 标志配合看
}
  • RCC_CSR_PINRSTF 表示 NRST 引脚手动复位,不是死机证据
  • RCC_CSR_SFTRSTF 是 NVIC_SystemReset() 触发的,属于可控复位
  • RCC_CSR_PORRSTF 上电复位,一般出现在首次上电,但掉电重启也可能出现

HAL_RCC_GetResetSource() 为什么不能直接用

HAL_RCC_GetResetSource() 看起来方便,但它内部第一行就是 __HAL_RCC_CLEAR_RESET_FLAGS(),也就是读完立刻清空所有标志。你拿到返回值的同时,硬件状态已丢失——下次再想查就只能靠日志或调试器回溯。

更麻烦的是,它把多个标志“或”在一起返回枚举值(如 RCC_RESET_FLAG_IWDG),掩盖了多标志共存的可能性。实际死机分析中,共存标志往往才是关键线索(比如 IWDGRSTF + LPWRRSTF 暗示低功耗模式下 IWDG 喂狗失败,可能因时钟配置错误导致 IWDG 频率异常)。

  • 自己读 RCC->CSR 并保存原始值到 RAM(如 __attribute__((section(".noinit"))) 变量),比依赖 HAL 封装更可靠
  • 如果必须用 HAL,至少把它拆开:先手动读寄存器,再调用 HAL 函数做辅助解析,但绝不让它清标志
  • 注意某些芯片(如 STM32H7)RCC_CSR 分成两个寄存器(RCC_CSR 和 RCC_SR),HAL 可能未完全适配

复位标志读取后怎么持久化,避免被覆盖

MCU 复位后 SRAM 默认不清零(除非启用 __HAL_RCC_CLEAR_FLAG(RCC_FLAG_SFTRST) 类似操作或调用了 memset 初始化),但标准启动流程(如 system_stm32f4xx.c 中的 SystemInit())之后,C 运行环境会执行 .data/.bss 段初始化,可能覆盖你存的标志值。

  • 用 __attribute__((section(".backupram"), used)) 把变量放到备份域(如 RTC_BKP_DRx),但需提前使能 LSE 和备份域写入
  • 更简单:定义为 static __attribute__((section(".noinit"))) uint32_t g_rcc_csr_backup;,并在启动代码最开头(C 环境初始化前)赋值
  • 调试阶段可直接用 printf 输出到串口(确保 UART 时钟已由 HSI 提供,不依赖 PLL),但注意有些调试器复位后串口引脚状态不稳定

真正容易被忽略的是:JTAG/SWD 在复位过程中可能拉低 NRST 或干扰 SWCLK,导致你看到的“复位标志”其实是调试器触发的软复位,而非真实死机。验证前先断开调试器,用独立电源+按键复位观察。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2248

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1019

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

580

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1409

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1217

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习