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

作者: 良知犹存

作者:良知犹存

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

总述

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

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

一、MCU寄存器介绍

​​

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

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

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

​​

这些复位标志能够被们解析并保存上报的话,们就可以通过复位标志的信息进而判断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的标志位继而扩展的话题,下一次,把用来存放故障码的链表,再详细介绍一下使用过程。

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

更多分享,扫码关注

原文作者:良知犹存

原文链接:https://www.cnblogs.com/conscience-remain/p/13320794.html

更多推荐

更多
  • Spark编程-结构化流式编程指南 概述,简单例子,编程模型,使用 Dataset 和 DataFrame 的API,连续处理,额外信息,基本概念,处理 Eventtime 和 Late Data,faulttolerance 语义,创建流式 DataFrame 和流式
  • Spark编程-20 Spark 配置Spark 属性,Environment Variables环境变量,Configuring Logging配置 Logging,Overriding configuration directory覆盖配置目录,Inhe
  • Spark编程-在Mesos上运行Spark 运行原理,安装 Mesos,连接 Spark 到 Mesos,Mesos 运行模式,Mesos Docker 支持,集成 Hadoop 运行,使用 Mesos 动态分配资源,配置,故障排查和调试,从源码安装,第三方软件包,验证,上传 S
  • Spark编程-Running Spark on YARN 启动 Spark on YARN,准备,配置,调试应用,在安全集群中运行,添加其他的 JARs,配置外部的 Shuffle Service,用 Apache Oozie 来运行应用程序,Kerberos 故障排查,使用 Spark Hi
  • Spark编程-Spark 调优 数据序列化,内存调优,其它考虑,,内存管理概论,确定内存消耗,优化数据结构,序列化 RDD 存储,GC优化,并行级别,Reduce任务内存使用,广播大变量,数据局部性, 由于大多数Spark计算都在内存中,所以集群中的任何资源(C
  • Spark编程-Spark Standalone模式 安装 Spark Standalone 集群,手动启动一个集群,集群启动脚本,提交应用程序到集群中,启动 Spark 应用程序,Resource Scheduling资源调度,监控和日志,与 Hadoop 集成,配置网络安全端口,高可用
  • Spark编程-Monitoring and Instrumentation Web 界面,Metrics,高级工具,事后查看,REST API,环境变量,Spark配置选项,API 版本控制策略, 有几种方法来监视 Spark 应用程序:Web UI,metrics 和外部工具。 Web 界面每
  • Spark编程-Spark提交任务Submitting Applications 打包应用依赖,用 sparksubmit 启动应用,Master URLs,从文件中加载配置,高级的依赖管理,更多信息, 在 script in Spark的 `bin` 目录中的`spark-submit` 脚本用与在集群上启动
  • Spark编程-作业调度 概述,跨应用调度,应用内调度,动态资源分配,公平调度资源池,资源池默认行为,配置资源池属性,配置和部署,资源分配策略,优雅的关闭Executor(执行器),概述Spark 有好几计算资源调度的方式。首先,回忆一下 [集群
  • Spark编程-Spark 概述 安全,下载,运行示例和 Shell,在集群上运行,进一步学习链接, Apache Spark 是一个快速的,通用的集群计算系统。它对 Java,Scala,Python 和 R 提供了的高层 API,并有一个经优化的支持通用执行图
  • 近期文章

    更多
    文章目录

      推荐作者

      更多