首页 > 编程知识 正文

stm32低功耗模式看门狗(stm32休眠了还要看门狗)

时间:2023-05-05 23:14:35 阅读:75314 作者:4387

摘要看门狗一般分为硬件看门狗和软件看门狗,主要用于解决程序CPU异常、程序运行中挂起等问题,提高系统可靠性。

硬件看门狗利用了计时器电路,其计时器输出与电路的复位端子连接,程序会在一定时间内清除计时器。 因此,程序正常运行时,计时器不能溢出或生成复位信号。 如果程序发生故障,且在计时器周期内不复位看门狗,看门狗计时器就会溢出并产生复位信号,系统将重新启动。 看门狗原理上是相同的,只要用处理器的内部计时器取代硬件电路上的计时器,就可以简化硬件电路的设计,但在可靠性上比硬件计时器差,例如系统内部的计时器本身发生故障时就无法检测到当然,也有双计时器的相互监视,但这不仅增加了开销,也不能解决中断系统故障导致的计时器中断失效等所有问题。

看门狗本身并不是用来解决系统问题的,调试过程中发现的故障必须检查设计本身的错误。加入看门狗目的是对一些程序潜在错误和恶劣环境干扰等因素导致系统死机而在无人干预情况下自动恢复系统正常工作状态。看门狗也不能完全避免故障造成的损失,坚持在发现故障和系统复位恢复正常之间懈怠工作。 此外,某些系统还需要在重置前保护现场数据,并在重新启动后恢复现场数据。 这可能还需要硬件和软件开销。

单任务系统程序一般是一个大循环,没有任务调度。 在初始化阶段打开看门狗,在大循环程序内部的适当位置清除看门狗计时器即可,实现起来比较容易。

独立的看门狗一般用于检测和解决程序引起的故障。 例如,一个程序正常运行的时间为50ms,如果在运行这个程序后立即喂狗,独立看门狗的定时溢出时间为60ms,比我们必须监视的程序的50ms多一点。 如果超过60ms还没有喂狗,我们监视的程序发生故障,飞走了,就会引起系统复位,让程序重新运行。

硬件设计:

1-IWDG,内部资源,不需要外部硬件

2-KEY一个

3-LED个可以是开发板附带的RGB灯

main函数如下,其他参照正点原子手册

intmain(void ) ({ /* LED端口初始化) */LED_GPIO_Config ); elay_ms(500; /*检查是否为独立的看门狗复位*/if (RCC _ getflagstatus (RCC _ flag _ iwdgrst )!=reset((/*重置独立看门狗(/*亮起红灯) */LED_RED; /*清除标志*/RCC_ClearFlag (; /*如果不喂狗继续复位,除了前面的延时外,如果看到红灯闪烁,在1s小时内喂狗,持续绿灯的*/} else { /*就不是独立的看门狗复位(通电复位和手动钥匙复位等) (/)初始化按钮(*/Key_Init ); //IWDG 1s超时溢出iwdg _ config (4,625 ); //while部分是我们需要在项目中具体编写的代码,这部分程序可以通过独立的看门狗进行监视。 //如果知道这部分代码的执行时间,例如500ms,则独立看门狗的//溢出时间为600ms,比500ms稍多。 如果被监控的程序运行不正常,//运行结束后就会运行喂狗的程序,但也不排除程序会跳回来,正好喂狗,//弯曲成正相反。 因此,为了制定更准确的监视程序,可以使用**窗口监控**。 窗口监控规定://在规定的窗口时间内喂狗。 while(1) if(key_scan(key1_gpio_port,KEY1_PIN )==KEY_ON ) /喂狗,不喂狗系统复位,复位后红灯亮}}程序首先检查是否为独立看门狗复位,独立看门狗复位时亮红灯。 如果一直不喂狗的话,康明斯会保持复位状态,在前面的延时会看到红灯闪烁。 1S小时内给狗喂食的话,绿灯会持续点亮。

多任务系统中一般与嵌入式操作系统、设置一个优先级级别最高的任务作为监视器配合使用,监控各APP应用任务是否正常运行。该监视器即为软件看门狗,该任务为其他任务设置计时器,喂软狗,其他任务为3358ww.Sina.com/

通过在多任务系统上创建监视任务监视器,可以提高优先级

于被监视的任务群Task1、Task2…Taskn。TaskMonitor在Task1~Taskn正常工作情况下,一定时间内对硬件看门狗定时器清零。如果被监视任务群有一个Task_x出现故障,TaskMonitor就不对看门狗定时器清零,也就达到了被监视任务出现故障时系统自动重启的目的。另外任务TaskMonitor自身出故障时,也不能及时对看门狗定时器清零,看门狗也能自动复位重启。接下来需要解决一个问题是:监视任务如何有效监视被监视的任务群。

在TaskMonitor中定义一组结构体来模拟看门狗定时器组

  typedef struct  {  UINT32 CurCnt, LastCnt;  BOOL RunState;  int taskID;  } STRUCT_WATCH_DOG;

该结构体包括被监视的任务号taskID,用来模拟“喂狗”的变量CurCnt、LastCnt(具体含义见下文),看门狗状态标志RunState用来控制当前任务是否接受监视。

被监视的任务Task1~Taskn调用自定义函数CreateWatchDog(int taskid)来创建看门狗,被监视任务一段时间内要求“喂狗”,调用ResetWatchDog(int taskid),这个“喂狗”动作实质就是对看门狗定时器结构体中的变量CurCnt加1操作。TaskMonitor大部分时间处于延时状态,假设硬件看门狗定时是2秒,监视任务可以延时1.5秒,接着对创建的看门狗定时器组一一检验,延时前保存CurCnt的当前值到LastCnt,延时后比较CurCnt与LastCnt是否相等,都不相等系统才是正常的。需要注意的是CurCnt和LastCnt数据字节数太小,而“喂狗”过于频繁,可能出现CurCnt加1操作达到一个循环而与LastCnt相等。

如果有任意一组的CurCnt等于LastCnt,认为对应接受监视的任务没有“喂狗”动作,也就检测到该任务出现故障需要重启,这时候TaskMonitor不对硬件看门狗定时器清零,或者延时很长的时间,比如10秒,足以使得系统重启。反之,系统正常,Task1~Taskn定期对TaskMonitor“喂狗”,TaskMonitor又定期对硬件看门狗“喂狗”,系统就得不到复位。还有一点,被监视任务可以通过调用PauseWatchDog(int taskid)来取消对应的看门狗,实际上就是对STRUCT_WATCH_DOG结构体中的RunState操作,该标志体现看门狗有效与否。

这种方式可监视的最大任务数由STRUCT_WATCH_DOG结构数据的个数决定。程序中应该有一个变量记录当前已创建的看门狗数,判断被监视任务Task1~Taskn是否“喂狗”只需比较CurCnt与LastCnt的值n次。

硬件看门狗监视TaskMonitor任务,TaskMonitor任务又监视其他的被监视任务Task1Taskn,形成这样一种链条。这种方式系统的故障图表示如图3所示。被监视任务Task1Taskn及TaskMonitor都是或的关系,因此被监视的任一任务发生故障,硬件电路看门狗就能复位。

为实现多任务系统的看门狗监视功能额外增加了TaskMonitor任务,这个任务占用执行时间多少也是一个重要问题。假设TaskMonitor任务一个监视周期延时1.5秒,此外需要执行保存当前计数值,判断是否“喂狗”等语句,它的CPU占用时间是很小的。用一个具体的试验证实,使用50M工作频率的CPU(S3C4510),移植vxWorks操作系统,cache不使能条件下监视10个任务,每个监视周期占用220~240微秒。可见该任务绝大多数时间都处于任务延时状态。

被监视任务可能有获取消息、等待一个信号量等的语句,往往这个消息、信号量的等待是无限期的等待。这就需要将这类语句作一些修改。比如在vxWorks中将一次无期限的获取信号量操作。
  
  semTake(semID, WAIT_FOREVER); // WAIT_FOREVER为无限时间等待
  分解为

  do  {   ResetWatchDog; // “喂狗”操作  }  while(semTake(semID, sysClkRateGet( )) != OK); // 1s内的等待信号量操作

多次的时间范围内的获取信号量操作,这样才能保证及时“喂狗”。

另外需要注意的是系统中是否有的任务优先级比TaskMonitor高并且长时间处于执行状态,TaskMonitor长时间得不到调度,使得看门狗错误复位。良好的任务划分,配置是不应该出现这种高优先级任务长期执行状况的。

转自:博客1
博客2

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。