多任务系统看门狗的实现

发布者:数字行者最新更新时间:2007-10-11 来源: 中国电子设计网关键字:定时  复位  喂狗  中断 手机看文章 扫描二维码
随时随地手机看文章
看门狗分硬件看门狗和软件看门狗。硬件看门狗是利用一个定时器电路,其定时输出连接到电路的复位端,程序在一定时间范围内对定时器清零(俗称“喂狗”),因此程序正常工作时,定时器总不能溢出,也就不能产生复位信号。如果程序出现故障,不在定时周期内复位看门狗,就使得看门狗定时器溢出产生复位信号并重启系统。软件看门狗原理上一样,只是将硬件电路上的定时器用处理器的内部定时器代替,这样可以简化硬件电路设计,但在可靠性方面不如硬件定时器,比如系统内部定时器自身发生故障就无法检测到。当然也有通过双定时器相互监视,这不仅加大系统开销,也不能解决全部问题,比如中断系统故障导致定时器中断失效。

看门狗本身不是用来解决系统出现的问题,在调试过程中发现的故障应该要查改设计本身的错误。加入看门狗目的是对一些程序潜在错误和恶劣环境干扰等因素导致系统死机而在无人干预情况下自动恢复系统正常工作状态。看门狗也不能完全避免故障造成的损失,毕竟从发现故障到系统复位恢复正常这段时间内怠工。同时一些系统也需要复位前保护现场数据,重启后恢复现场数据,这可能也需要一笔软硬件的开销。

图1:(a) 多任务系统看门狗示意图 ;(b) 相应的看门狗复位逻辑图。

在单任务系统中看门狗工作原理如上所述,容易实现。在多任务系统中情况稍为复杂。假如每个任务都像单任务系统那么做,如图1(a)所示,只要有一个任务正常工作并定期“喂狗”,看门狗定时器就不会溢出。除非所有的任务都故障,才能使得看门狗定时器溢出而复位,如图1(b)。

而往往我们需要的是只要有一个任务故障,系统就要求复位。或者选择几个关键的任务接受监视,只要一个任务出问题系统就要求复位,如图2(a)所示,相应的看门狗复位逻辑如图2(b)所示。

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

图2:(a) 多任务系统看门狗示意图;(b) 正确的看门狗复位逻辑图。

在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次。

图3:系统复位逻辑图。

硬件看门狗监视TaskMonitor任务,TaskMonitor任务又监视其他的被监视任务Task1~Taskn,形成这样一种链条。这种方式系统的故障图表示如图3所示。被监视任务Task1~Taskn及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长时间得不到调度,使得看门狗错误复位。良好的任务划分,配置是不应该出现这种高优先级任务长期执行状况的。

关键字:定时  复位  喂狗  中断 引用地址:多任务系统看门狗的实现

上一篇:多任务系统看门狗的实现
下一篇:基于时间触发模式的电子控制系统设计

推荐阅读最新更新时间:2024-03-30 21:24

s3c2440学习之路-012-1 Undefined未定义中断
1 未定义中断的原理 1.1 ARM的指令组成 ARM的指令是由32位组成的,是有一定的组成格式的,如果不符合组成格式的话,那就这条指令就无法被识别,就是未定义指令了。指令的 ~ 是条件位,当条件位为1110B时,就表明该指令一定背执行。这里特别指出 ~ 是因为后面的例子种将会使用到。 1.2 执行未定中断的过程 当发现未定义指令时ARM会做什么呢,如同s3c2440学习之路-012-0 异常中断基础知识 的1.4 小节所说的, 程序会自动跳到0x4的位置去执行代码。 具体的执行过程如下: 执行某条命令,发现不符合ARM的命令格式,产生未定义异常 发生异常时硬件的处理,即进入异常 2.1将返回地址保存在LR(R14)
[单片机]
s3c2440学习之路-012-1 Undefined未定义<font color='red'>中断</font>
STM32定时器的编码器模式
/pre pre name= code class= objc /pre pre name= code class= objc /********************************************************************************** * @file: stm32定时器的编码器模式 * @date: 2015.8.2 * @author: shenhuixiang * @version: 1.0.0 **********************************************************************************
[单片机]
MSP430 TIMER_A定时器设置示例
直接设置: TA0CCTL0 = CCIE; // CCR0 interrupt enabled TA0CCR0 = 1000;//意思是周期为1000ms=1Hz TA0CTL = TASSEL_2 + MC_1 + TACLR; // 选择时钟源SMCLK,+递增模式upmode:计时器递增计数到 TAxCCR0+clear TAR 间接?(利用封装好的函数) void SMCLK_XT2_4Mhz(void) { P7SEL |= BIT2+BIT3; // Port select XT2 UCSCTL6 &= ~XT2OFF; // En
[单片机]
MSP430 TIMER_A<font color='red'>定时</font>器设置示例
STM8 定时器TIM1 计时
ST公司的STM8单片机的TIM1定时器,是一个16位高级控制定时器,可用于实现基本的定时,PWM波的产生,这里主要分析下基本的计时功能。 我们先看ST提供的库函数中TIM1定时器的初始化函数 void TIM1_TimeBaseInit(uint16_t TIM1_Prescaler, TIM1_CounterMode_TypeDef TIM1_CounterMode, uint16_t TIM1_Period, uint8_t TIM1_RepetitionCounter) 其中,TIM1_Prescaler是一个16位的分频配置,可输入值为0
[单片机]
STM32的中断优先级详解
中断优先级设置步骤: 系统运行后先设置中断优先级分组。在主函数调用函数: void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); 整个系统执行过程中,只设置一次中断分组。 针对每个中断,设置对应的抢占优先级和响应优先级: void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);//配置过程 NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断,此处可改为任何有中断功能
[单片机]
关于中断时的堆栈溢出
pic16f876堆栈只有8级,每发生一次子程序调用(或中断),将当前13位地址压到堆栈,PC=子程序起始地址低8位+PCLATH(或04H),子程序返回时将13位地址从堆栈中弹出=PC。 堆栈的操作由CPU控制不可监控,溢出不报警,子程序调用(或中断)超过8次嵌套时,最先压到堆栈的13位地址被冲掉,子程序返回时将回不到调用前的PC,程序。 一般使用不会达到8次嵌套,但如果有5、6 次子程序嵌套,而中断服务程序中有1、2次子程序调用便相当危险。调试时很难完全模拟所有实际情况, 一般的避免方法: 1、一般的子程序调用不要超过6次子程序嵌套,在开始编程前最好画一下流程。 2、尽量避免在不可确定发生时刻的中断(如串口接收、定时器)程序中加
[单片机]
STM8S003外部中断识别机械式编码器正反转
最近在项目上,用到鼠标上用的编码器,按照厂家给的编程方法,发现容易产生误判,故而自己用外部中断的方式来做,发现这样误判的情况会得到很大的改善,现发上来与大家分享。 #include stm8s103f3p.h #include stm8s_bitsdefine.h #include typedef.h #define CodeA PB_IDR_0 #define CodeB PB_IDR_1 uint8_t CodeB_last,CodeB_current,whe_ch,ADJ; void UART1_Init(void) { UART1_CR2=0x00; UART1_CR1=0x00;
[单片机]
Windows98下硬件中断驱动程序的开发
摘 要: 介绍了Windows98的内核管理机制和应用程序权限级别,简述了在Windows98下进行虚拟驱动程序开发的几种工具和编程方法,并给出了借助VToolsD用C++语言编写的处理硬件中断的程序实例。 关键词: 虚拟设备驱动程序 VToolsD 中断服务例程 美国微软公司出品的Windows98以其友好的图形用户界面,在我国赢得了广泛的市场。在给广大办公环境工作人员带来方便的同时,也给不少工程技术人员带来了一些麻烦。一些原本在DOS下很容易编出的控制硬件的程序,现在在Windows98下就不那么容易实现了。作为一个完善的操作系统也必须能控制硬件,象DOS那样直接与硬件打交道是Windows98
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
最新工业控制文章
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved