当前位置: 首页 > news >正文

STC15单片机-看门狗介绍

什么是看门狗

在工业控制/ 汽车电子/航空航天等需要高可靠性的系统中,为了防止“系统在异常情况下,受到干扰,MCU/CPU程序跑飞,导致系统长时间异常工作”,通常是引进看门狗,如果MCU/CPU不在规定的时间内按要求访问看门狗,就认为MCU/CPU处于异常状态,看门狗就会强迫MCU/CPU复位,使系统重新从头开始按规律执行用户程序。看门狗本质上是一种定时电路或者软件定时器机制。

基本原理:

看门狗,又叫 watchdog timer,是一个定时器电路,一般有一个输入,叫喂狗(kicking the dog or service the dog),一个输出到MCU的RST端,MCU正常工作的时候,每隔一段时间输出一个信号到喂狗端,给 WDT 清零,如果超过规定的时间不喂狗,(一般在程序跑飞时),WDT 定时超过,就会给出一个复位信号到MCU,使MCU复位, 防止MCU死机。看门狗的作用就是防止程序发生死循环,或者说程序跑飞。

工作原理:在系统运行以后也就启动了看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去清看门狗,那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。所以在使用有看门狗的芯片时要注意清看门狗。

看门狗实现方法

硬件实现

硬件看门狗是利用了一个定时器,来监控主程序的运行,也就是说在主程序的运行过程中,我们要在定时时间到之前对定时器进行复位如果出现死循环,或者说PC指针不能回来。那么定时时间到后就会使单片机复位。常用的WDT芯片如MAX813,5045,IMP 813等,价格4~10元不等。有些单片机内部已经集成看门狗定时器,如STC15系列,只需在使用时配置相应的看门狗寄存器即可

大体工作方式:硬件看门狗芯片会有接收单片机的置位信号和控制单片机复位的引脚。单片机可以根据看门狗芯片信号需求,可以通过io口进行喂狗;如果程序异常,看门狗会由于收不到单片机给的信号而发出单片机复位信号给单片机,让单片机进行复位。

软件实现

软件看门狗技术的原理和这差不多,只不过是用软件的方法实现,我们还是以51系列来讲,我们知道在51单片机中有两个定时器,我们就可以用这两个定时器来对主程序的运行进行监控。我们可以对T0设定一定的定时时间,当产生定时中断的时候对一个变量进行赋值,而这个变量在主程序运行的开始已经有了一个初值,在这里我们要设定的定时值要小于主程序的运行时间,这样在主程序的尾部对变量的值进行判断,如果值发生了预期的变化,就说明T0中断正常,如果没有发生变化则使程序复位。

对于T1我们用来监控主程序的运行,我们给T1设定一定的定时时间,在主程序中对其进行复位,如果不能在一定的时间里对其进行复位,T1 的定时中断就会使单片机复位。在这里T1的定时时间要设的大于主程序的运行时间,给主程序留有一定的的余量。而T1的中断正常与否我们再由T0定时中断子程序来监视。这样就够成了一个循环,T0监视T1,T1监视主程序,主程序又来监视T0,从而保证系统的稳定运行。

看门狗分类

在STM32单片机中,有两类看门狗,分别是独立看门狗窗口看门狗,两者的区别有:

1.时钟源的区别

独立看门狗使用的是内部低速时钟,其频率为40kHz,但是这个40KHz不是准确的,其大致的范围是(30-60)KHz。该时钟与外设时钟无关,所以不受系统晶振影响

窗口看门狗使用的是PCLK1的时钟,该时钟与晶振相关

2.喂狗时间不同

独立看门狗喂狗时只要下限大于0就可以,上限是0xFFF.

窗口看门狗必须在一个区域内喂狗才可以,上限是0x7F,下限是0x40。

3.计数器不同

独立看门狗的计数器是12位递减的,即最大值是0xFFF。

窗口看门狗的计数器是7位递减的,即最大值是0x7F。

4.产生结果不同

独立看门狗时,如果超时不喂狗,则直接产生复位,程序从头执行

窗口看门狗会在计数器到达0x40时产生中断,在0X3F时产生复位,所以可以把窗口看门狗看成是一种中断。

两者使用举例

独立看门狗可以用来防止程序跑飞,在程序中开启看门狗,定时喂狗,尤其在通讯中使用广泛,当逻辑处理不当,使程序一直处于发送或接收状态不退出时,这时独立看门狗可以使程序复位,程序从头执行。

窗口看门狗可以产生中断,利用这一特点可以用来进行数据保存,当产生窗口看门狗中断时,可以用来保存数据。

看门狗能检测的错误类型

  1. 栈或堆溢出,程序跑飞

  2. 某段程序异常无法返回或陷入死循环

  3. 强电磁干扰破坏数据导致系统异常,常工作在强电磁干扰环境中的电子系统容易出现故障

  4. bug导致的系统宕机,或者死循环

  5. 多任务系统中死锁

  6. ……

看门狗定时溢出后的处理方式

  1. 系统复位,这是一般的处理方法,也最简单的方法,系统死机了,重启就好
  2. 失效安全,就是设备即使出现致命故障了,也要防止造成安全事故。举个例子,一个正在下降的电梯,加入看门狗检测到程序异常了,安全的做法是赶紧停止电机转动,否则电梯仍一直下降的话,就会造成人员伤亡等严重后果,这在IEC61508 功能安全标准,或者医疗安全标准、汽车安全标准中都有体现。
  3. 这一种做法值得推荐,芯片复位后,利用芯片复位状态寄存器值,对由于看门狗复位事件计数,事不过三,如果连续三次此类复位,则保守做法就是将系统切换到安全状态或显示错误消息,这样可以避免无限重新启动。
  4. 取决于具体的设计策略,看具体的应用场景,对出现异常要如何处理

看门狗定时时间长短以及喂狗频率

定时过短

看门狗定时器定时时间设置过短,则系统容易误判,可能会导致频繁复位或进入失效安全模式。因为任何一条安全链的好坏取决于它最薄弱的一环,如果选择一个太短的超时间隔。固件的循环时间是动态的,尤其外部的异步事件比较多,或者有中断嵌套的情况,则波动会比较大,所以需要考虑最坏情况,系统循环一次要多久。

定时过长

一种方法是选择一个几秒钟长的间隔。当您仅尝试复位一个确实挂起的系统,但不希望对系统的时间进行详细研究时,可以采用此策略。这是一个健壮的方法。但有些系统需要快速恢复,这就造成故障诊断过慢的危害了,尤其在一些对安全要求极高的场合,比如核电系统,汽车电子系统、医疗器械系统等等。

通俗点来讲就是,系统如果进入死循环或宕机了,没有及时喂狗,但看门狗溢出时间还没到,就不能及时复位系统,对一些要及时恢复的系统来说,看门狗溢出时间不易太长

喂狗频率

设计者必须清楚看门狗的溢出时间以决定在合适的时候,清看门狗。清看门狗也不能太过频繁否则会造成资源浪费。程序正常运行时,软件每隔一定的时间(小于定时器的溢出周期)给定时器置数,即可预防溢出中断而引起的误复位。

喂狗频率不好规定某个数值,因为不同的系统要求不同,对这一部分的介绍文章也较少,可能更多的是看工程师的经验吧

STC15单片机看门狗控制寄存器

在这里插入图片描述

看门狗溢出时间 = ( 12 x Pre-scale x 32768)/ 振荡器频率

在这里插入图片描述

例如在晶振频率是11.0592MHz的单片机中,想让看门狗溢出时间为2.2755S,则PS2、PS1、PS0分别为1、0、1,对应的Pre-scale的值就是64,根据公式,溢出时间=(12 x 64 x32768)/11059200 = 2.2755 s

程序

一个看门狗初始化函数,一个喂狗函数

/*
 * @name   Init
 * @brief  看门狗初始化
 * @param  None
 * @retval None      
*/
static void Init()
{
	WDT_CONTR = 0x3d;	  	// 0011 1101   看门狗溢出时间   2.2755s ,空闲模式计数,喂狗、使能
 	WDT_CONTR |= 0x10;  	//喂狗
}

/*
 * @name   Feed
 * @brief  喂狗
 * @param  None
 * @retval None
*/
static void Feed()
{
	WDT_CONTR |= 0x10;  //喂狗
}

看门狗使用注意事项

1.一定要注意并不是所有的系统都适合使用看门狗,比如说在我们的比较精密的控制系统,一旦我们程序除了一些小异常而导致芯片复位,可能会导致系统时续混乱而造成较大得设备损害!

2.对于看门狗一般用在,比如温控系统,显示系统等复位系统对整个系统影响不是很大的延时系统等!这样能够在系统异常后复位系统让系统继续运行。

3.对于部分MCU在看门狗复位之前会出发一个中断服务函数,给程序最后进行喂狗的机会。这个是系统给我们的机会,我们可以对当前MCU的状态进行保存等日志信息记录,供软件研发人员进行系统的分析。

4.同时对于喂狗每个人持有不同的态度,有些人认为需要在主程序中喂狗,有些则认为需要在中断里面喂狗;不过在中断里面喂狗存在一个问题是,对于MCU主程序处于死循环的时候,而我们的中断服务函数可以正常运行,这样无法出发看门狗复位。所以常用做法是,通过中断置位相关标志位,然后主程序检测标志位进行喂狗操作,至于更加强大的看门狗机制,我们需要在实际的项目中根据需求来制定相关策略。

参考:

https://zhuanlan.zhihu.com/p/147934002

https://mp.weixin.qq.com/s/ocScysddIu2OEBlAEHZVDg

https://mp.weixin.qq.com/s/coPJHoVs_f4jTI_PfiQFpA

相关文章:

  • C/C++教程 从入门到精通《第二十二章》——Qt控件详解
  • ECCV 2022 | k-means Mask Transformer
  • 如何做顶级“新生代农民工”?这几本书为你打开大门
  • datawhale8月组队学习《pandas数据处理与分析》(下)(文本、分类、时序数据)
  • 王道书 P191 思维拓展
  • matplotlib与django如何集成? matplotlib生成的图可以嵌入到网页吗?
  • 内卷室友系列 -- day01 计算机网络概论
  • mac显示器如何显示docker container中的gui请求
  • SpringCloud 三种服务调用方式详解
  • SpringCloud 三种服务调用方式,你知道几种?
  • 阿里二面:SpringCloud 有几种服务调用方式?
  • PHP HTTP 函数
  • springboot 整合使用redis发布订阅功能
  • mysql主从复制搭建
  • SpringCloud Alibaba实战——服务治理:实现服务调用的负载均衡
  • Babel配置的不完全指南
  • create-react-app做的留言板
  • GraphQL学习过程应该是这样的
  • JAVA_NIO系列——Channel和Buffer详解
  • js写一个简单的选项卡
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • node 版本过低
  • React-生命周期杂记
  • VuePress 静态网站生成
  • vue脚手架vue-cli
  • 测试开发系类之接口自动化测试
  • 动态魔术使用DBMS_SQL
  • 工作手记之html2canvas使用概述
  • 关于 Cirru Editor 存储格式
  • 配置 PM2 实现代码自动发布
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 算法-插入排序
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 项目管理碎碎念系列之一:干系人管理
  • 消息队列系列二(IOT中消息队列的应用)
  • 协程
  • 在Mac OS X上安装 Ruby运行环境
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 阿里云服务器如何修改远程端口?
  • 带你开发类似Pokemon Go的AR游戏
  • ​flutter 代码混淆
  • ​queue --- 一个同步的队列类​
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #ifdef 的技巧用法
  • (145)光线追踪距离场柔和阴影
  • (C#)一个最简单的链表类
  • (四)汇编语言——简单程序
  • (转载)OpenStack Hacker养成指南
  • (转载)PyTorch代码规范最佳实践和样式指南
  • **python多态
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET 反射 Reflect
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .Net 知识杂记