各个复位标志解析,让我们对MCU的程序的健康更有把控

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 各个复位标志解析,让我们对MCU的程序的健康更有把控

作者:良知犹存

转载授权以及围观:欢迎添加微信公众号:Conscience_Remains

总述

   曾经开发的时候遇到这样情况,我们开发的设备需要长时间工作上报信息,但是我们在后台查看上报数据,发现设备总是有断开的情况。因为是远程的设备无法进行现场查看,这个时候我们就用到了MCU的复位的状态解析上报,辅助我们进行诊断故障的来源,可能是程序到死循环,可能是程序hardfault,也可能硬件电源不稳定导致的复位。

   综合上面的要求,我们分析一下STM32相应的寄存器,以及讲解相关函数使用方法。


一、MCU寄存器介绍

4edc953e2c684bbe819ffa954c899c08.png   在stm32开发手册里面选择 RCC寄存器 中的  控制状态寄存器 书签,就可以看到相应的介绍:

其中包含了:低功耗复位标志、窗口看门狗复位标志、独立看门狗复位标志、软件复位标志、上电/掉电复位标志、NRST引脚复位标志。

   在RCC功能的这一栏下级菜单 系统复位 里面有对复位比较详细的介绍:

4edc953e2c684bbe819ffa954c899c08.png

这些复位标志能够被我们解析并保存上报的话,我们就可以通过复位标志的信息进而判断MCU崩溃的原因。下面我来进行介绍相应的标志以及组合判断。

在RCC_CSR所有复位源,复位的时候都会使引脚复位置位,上电复位只产生引脚复位,其余的复位都产生一个引脚复位,和一个相应的自身复位。

所以程序解析的时候先检测是否有pin复位

void GetResetFlag(void)
{
    devfaultcode.resetfault = 0;
    if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
    {
        dprintf("*RCC_FLAG_PINRST\r\n"); 
        devfaultcode.resetfault = 0xF001; 
    }
    if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
    {
        printf("*RCC_FLAG_IWDGRST\r\n");       
        devfaultcode.resetfault = 0xF002;      
    }
    if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET)
    {
        printf("*RCC_FLAG_WWDGRST\r\n");
        devfaultcode.resetfault = 0xF003;      
    }   
    if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
    {
        printf("*RCC_FLAG_PORRST\r\n"); 
        devfaultcode.resetfault = 0xF004;      
    }
    if(RCC_GetFlagStatus(RCC_FLAG_SFTRST) != RESET)
    {
        printf("*RCC_FLAG_SFTRST\r\n"); 
        devfaultcode.resetfault = 0xF005;      
    }   
    if(RCC_GetFlagStatus(RCC_FLAG_LPWRRST) != RESET)
    {
        printf("*RCC_FLAG_LPWRRST\r\n"); 
        devfaultcode.resetfault = 0xF006;      
    }   
    RCC_ClearFlag(); //Clears the RCC reset flags.
    ErrListInsert(ErrHead,devfaultcode.resetfault); 
    printf("devfaultcode:%d\r\n",devfaultcode.resetfault);
}

以上代码通过建立一个单向链表把采集到的复位标志进行保存发送到服务器端。


二、中断故障函数

   在开发过程中,我们会遇到hardfault这样的bug,但是如果是远程上报信息,仅凭复位标志是无法检测的,一般hardfault会有软件复位标志和看门狗复位标志(如果设备开启看门狗)。

   而我选择了另一种方式,因为这些故障标志在程序复位之后就会消失,所以我在故障发生的时间进行变量记录保存到FLASH,通过自定义的故障码表,再在程序中进行故障出现位置进行故障码的存入,再利用各种通讯方式上报,后台就可以对于设备出现的各种问题按表对照,如同汽车的故障码表一样。

void HardFault_Handler(void)
{
  devfaultcode.resetfault = 0xF007;    
  writeFlash();
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {    
    printf("HardFault\r\n"); 
  }
}
/**
  * @brief  This function handles Memory Manage exception.
  * @param  None
  * @retval None
  */
void MemManage_Handler(void)
{
  devfaultcode.resetfault = 0xF008;     
  writeFlash();
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
    printf("MemManageFault\r\n"); 
  }
}
/**
  * @brief  This function handles Bus Fault exception.
  * @param  None
  * @retval None
  */
/*总线Fault,取址或取值时的内存错误*/
void BusFault_Handler(void)
{
  devfaultcode.resetfault = 0xF009;     
  writeFlash();
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
    printf("BusFault\r\n"); 
  }
}
/**
  * @brief  This function handles Usage Fault exception.
  * @param  None
  * @retval None
  */
/*用法 Fault */
void UsageFault_Handler(void)
{
  resetfault = 0xF010;     
  writeFlash();
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
    printf("UseageFault\r\n"); 
  }
}

通过在程序设备故障码表监控程序的健康,对于任何一个开发者来说都有很多好处,这里只是我通过介绍MCU的标志位继而扩展的话题,下一次,我把我用来存放故障码的链表,再详细介绍一下使用过程。

这就是我分享的复位等一些标志的使用过程,里面代码是实践过的,如果大家有什么更好的思路,欢迎分享交流哈。


目录
相关文章
|
7月前
|
缓存 网络协议 算法
《跟闪电侠学Netty》阅读笔记 - Netty入门程序解析
《跟闪电侠学Netty》阅读笔记 - Netty入门程序解析
221 0
|
2月前
|
SQL 安全 Windows
SQL安装程序规则错误解析与解决方案
在安装SQL Server时,用户可能会遇到安装程序规则错误的问题,这些错误通常与系统配置、权限设置、依赖项缺失或版本不兼容等因素有关
|
2月前
|
XML Java 数据格式
手动开发-简单的Spring基于注解配置的程序--源码解析
手动开发-简单的Spring基于注解配置的程序--源码解析
53 0
|
2月前
|
XML Java 数据格式
手动开发-简单的Spring基于XML配置的程序--源码解析
手动开发-简单的Spring基于XML配置的程序--源码解析
87 0
|
3月前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与应用在软件开发的浩瀚海洋中,PHP以其独特的魅力和强大的功能吸引了无数开发者。作为一门历史悠久且广泛应用的编程语言,PHP不仅拥有丰富的内置函数和扩展库,还支持面向对象编程(OOP),为开发者提供了灵活而强大的工具集。在PHP的众多特性中,设计模式的应用尤为引人注目,它们如同精雕细琢的宝石,镶嵌在代码的肌理之中,让程序更加优雅、高效且易于维护。今天,我们就来深入探讨PHP中使用频率颇高的一种设计模式——策略模式。
本文旨在深入探讨PHP中的策略模式,从定义到实现,再到应用场景,全面剖析其在PHP编程中的应用价值。策略模式作为一种行为型设计模式,允许在运行时根据不同情况选择不同的算法或行为,极大地提高了代码的灵活性和可维护性。通过实例分析,本文将展示如何在PHP项目中有效利用策略模式来解决实际问题,并提升代码质量。
|
4月前
|
存储 并行计算 API
ViperGPT解析:结合视觉输入与文本查询生成和执行程序
ViperGPT是一个创新的混合视觉和语言处理模型,通过生成和执行代码来解决视觉查询问题,具有高度模块化、灵活性和优秀的外部知识查询能力。
90 0
|
5月前
|
数据可视化 持续交付 开发工具
RAD技术解析:快速开发应用程序的秘诀
**快速应用开发(RAD)**是一种始于90年代的敏捷方法,旨在通过迭代原型和反馈加速高质量软件交付。由James Martin提出,它包括需求规划、界面设计、快速构建和持续优化四阶段,以提高质量、降低风险、增强灵活性、降低成本和提升客户满意度。工具如ZohoCreator支持RAD,通过可视化工具和低代码平台促进高效开发,实现快速迭代和市场适应,降低项目失败风险,提高用户满意度。
106 9
|
5月前
|
调度
【浅入浅出】Qt多线程机制解析:提升程序响应性与并发处理能力
在学习QT线程的时候我们首先要知道的是QT的主线程,也叫GUI线程,意如其名,也就是我们程序的最主要的一个线程,主要负责初始化界面并监听事件循环,并根据事件处理做出界面上的反馈。但是当我们只限于在一个主线程上书写逻辑时碰到了需要一直等待的事件该怎么办?它的加载必定会带着主界面的卡顿,这时候我们就要去使用多线程。
179 6
|
6月前
|
Java 程序员
程序技术好文:解析器组合子
程序技术好文:解析器组合子
50 1
|
6月前
|
Java UED 开发者
JVM逃逸分析原理解析:优化Java程序性能和内存利用效率
JVM逃逸分析原理解析:优化Java程序性能和内存利用效率

推荐镜像

更多