📄 wdlib.c
字号:
/* wdLib.c - watchdog timer library *//* Copyright 1984-1995 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01t,24jun96,sbs made windview instrumentation conditionally compiled02s,13oct95,jdi doc: removed SEE ALSO to .pG Cross-Dev.02r,18jan95,rhp doc: say explicitly no need to cancel expired timers, and improve wdLib and wdSTart() man pages from bss comments.02u,14apr94,smb fixed class dereferencing for instrumentation macros02t,15mar94,smb modified instrumentation macros02s,24jan94,smb added instrumentation macros02r,10dec93,smb added instrumentation02q,24feb93,jdi doc tweaks from review by kdl.02p,20jan93,jdi documentation cleanup for 5.1.02o,13nov92,jcf package init called with with watchdog creation.02n,29jul92,jcf package init called with with object initialization.02m,04jul92,jcf private headers.02l,26may92,rrr the tree shuffle02k,04oct91,rrr passed through the ansification filter -changed functions to ansi style -changed includes to have absolute path from h/ -changed VOID to void -changed copyright notice02j,30mar91,jdi documentation cleanup; doc review by jcf.02i,05oct90,dnw made wdInit() and wdTerminate() be NOMANUAL.02h,01oct90,jcf fixed wdDestroy() to invalidate with ISR mutual exclusion.02g,29aug90,jcf documentation.02f,10aug90,dnw changed wdCancel() from void to STATUS.02e,02aug90,jcf documentation.02d,17jul90,dnw changed to new objAlloc() call.02c,03jul90,jcf documentation. removed erroneous log message.02b,26jun90,jcf updated class structure, change over to objAlloc ()02a,17apr90,jcf integrated into wind 2.0.01j,01sep88,gae documentation.01i,04nov87,ecs documentation.01h,25mar87,jlf documentation01g,21dec86,dnw changed to not get include files from default directories.01f,05sep86,jlf minor documentation.01e,14apr86,rdc changed memAllocates to mallocs.01d,07sep84,jlf added copyright notice and comments.01c,02aug84,dnw changed calls to vxInt... to int...01b,11jul84,ecs changed calls to vxIntLock/vxIntUnlock to restore old level.01a,22may84,dnw written*//*DESCRIPTIONThis library provides a general watchdog timer facility. Any task maycreate a watchdog timer and use it to run a specified routine inthe context of the system-clock ISR, after a specified delay.Once a timer has been created with wdCreate(), it can be started withwdStart(). The wdStart() routine specifies what routine to run, aparameter for that routine, and the amount of time (in ticks) beforethe routine is to be called. (The timeout value is in ticks asdetermined by the system clock; see sysClkRateSet() for moreinformation.) After the specified delay ticks have elapsed (unlesswdCancel() is called first to cancel the timer) the timeout routine isinvoked with the parameter specified in the wdStart() call. Thetimeout routine is invoked whether the task which started the watchdogis running, suspended, or deleted.The timeout routine executes only once per wdStart() invocation; thereis no need to cancel a timer with wdCancel() after it has expired, orin the expiration callback itself.Note that the timeout routine is invoked at interrupt level, rather thanin the context of the task. Thus, there are restrictions on what theroutine may do. Watchdog routines are constrained to the same rulesas interrupt service routines. For example, they may not take semaphores,issue other calls that may block, or use I/O system routines like printf().EXAMPLEIn the fragment below, if maybeSlowRoutine() takes more than 60 ticks,logMsg() will be called with the string as a parameter, causing the message tobe printed on the console. Normally, of course, more significant correctiveaction would be taken..CS WDOG_ID wid = wdCreate (); wdStart (wid, 60, logMsg, "Help, I've timed out!"); maybeSlowRoutine (); /@ user-supplied routine @/ wdCancel (wid);.CEINTERNAL: WINDVIEW INSTRUMENTATIONLevel 1: wdCreate() causes EVENT_WDCREATE wdDestroy() causes EVENT_WDDELETE wdStart() causes EVENT_WDSTART wdCancel() causes EVENT_WDCANCELLevel 2: N/ALevel 3: N/AINCLUDE FILES: wdLib.hSEE ALSO: logLib,.pG "Basic OS"*/#include "vxWorks.h"#include "taskLib.h"#include "errno.h"#include "intLib.h"#include "private/classLibP.h"#include "private/objLibP.h"#include "private/wdLibP.h"#include "private/windLibP.h"#include "private/workQLibP.h"#include "private/eventP.h"/* locals */LOCAL BOOL wdLibInstalled;LOCAL OBJ_CLASS wdClass; /* non-instrumented class *//* globals */CLASS_ID wdClassId = &wdClass;/* windview definitions */#ifdef WV_INSTRUMENTATIONLOCAL OBJ_CLASS wdInstClass;CLASS_ID wdInstClassId = &wdInstClass;#endif/********************************************************************************* wdLibInit - initialize watchdog library** This routine initializes the watchdog object class. No watchdog operation* will work until this is called. This routine is called during system* configuration within kernelInit(). This routine should only be called once.** NOMANUAL*/STATUS wdLibInit (void) { if ((!wdLibInstalled) && (classInit (wdClassId, sizeof (WDOG), OFFSET (WDOG, objCore), (FUNCPTR) wdCreate, (FUNCPTR) wdInit, (FUNCPTR) wdDestroy) == OK)) {#ifdef WV_INSTRUMENTATION /* initialise the instrumented class for level 1 event logging */ wdClassId -> initRtn = wdInstClassId; classInstrument (wdClassId, wdInstClassId); wdInstClassId->instRtn = (FUNCPTR) _func_evtLogO;#endif wdLibInstalled = TRUE; } return ((wdLibInstalled) ? OK : ERROR); }/********************************************************************************* wdCreate - create a watchdog timer** This routine creates a watchdog timer by allocating a WDOG structure in* memory.** RETURNS: The ID for the watchdog created, or NULL if memory is insufficient.** SEE ALSO: wdDelete()*/WDOG_ID wdCreate (void) { WDOG_ID wdId;#ifdef WV_INSTRUMENTATION int level;#endif if ((!wdLibInstalled) && (wdLibInit () != OK)) return (NULL); /* package init problem */ wdId = (WDOG_ID) objAlloc (wdClassId); /* initialize allocated watchdog */ if ((wdId != NULL) && (wdInit (wdId) != OK)) { objFree (wdClassId, (char *) wdId); return (NULL); }#ifdef WV_INSTRUMENTATION /* windview - level 1 event logging */ level = intLock (); EVT_OBJ_1 (OBJ, wdId, wdClassId, EVENT_WDCREATE, wdId); intUnlock (level); #endif return (wdId); }/********************************************************************************* wdInit - initialize a watchdog timer** This routine initializes a static watchdog or a watchdog embedded in a* larger object.** RETURNS: OK, or ERROR if the watchdog could not be initialized.** NOMANUAL*/STATUS wdInit ( WDOG *pWdog /* pointer to watchdog to initialize */ ) { if ((!wdLibInstalled) && (wdLibInit () != OK)) return (ERROR); /* package init problem */ pWdog->status = WDOG_OUT_OF_Q; /* initially out of q */ pWdog->deferStartCnt = 0; /* no pending starts */#ifdef WV_INSTRUMENTATION /* windview - connect instrumented class for level 1 event logging */ if (wvObjIsEnabled) objCoreInit (&pWdog->objCore, wdInstClassId); else#endif objCoreInit (&pWdog->objCore, wdClassId); /* initialize core */ return (OK); }/********************************************************************************* wdDelete - delete a watchdog timer** This routine de-allocates a watchdog timer. The watchdog will be removed* from the timer queue if it has been started. This routine complements* wdCreate().** RETURNS: OK, or ERROR if the watchdog timer cannot be de-allocated.** SEE ALSO: wdCreate()*/STATUS wdDelete ( WDOG_ID wdId /* ID of watchdog to delete */ ) { return (wdDestroy (wdId, TRUE)); /* delete watchdog */ }/********************************************************************************* wdTerminate - terminate a watchdog timer** This routine terminates a watchdog timer. The watchdog will be removed* from the timer queue if it has been started. This routine differs from* wdDelete() in that associated memory is not de-allocated. This routine* complements wdInit().** RETURNS: OK, or ERROR if the watchdog cannot be terminated.** NOMANUAL*/STATUS wdTerminate ( WDOG_ID wdId /* ID of watchdog to terminate */ ) { return (wdDestroy (wdId, FALSE)); /* terminate watchdog */ }/********************************************************************************* wdDestroy - terminate a watchdog timer** This routine terminates a watchdog timer and optionally de-allocates* associated memory. If the watchdog has been started, it will be removed* from the timer queue. This routine underlies wdDelete(), and* wdTerminate().** RETURNS: OK, or ERROR if the watchdog cannot be destroyed.** NOMANUAL*/STATUS wdDestroy ( WDOG_ID wdId, /* ID of watchdog to terminate */ BOOL dealloc /* dealloc associated memory */ ) { int level; if (INT_RESTRICT () != OK) /* restrict isr use */ return (ERROR); level = intLock (); /* LOCK INTERRUPTS */ if (OBJ_VERIFY (wdId, wdClassId) != OK) /* validate watchdog ID */ { intUnlock (level); /* UNLOCK INTERRUPTS */ return (ERROR); }#ifdef WV_INSTRUMENTATION /* windview - level 1 event logging */ EVT_OBJ_1 (OBJ, wdId, wdClassId, EVENT_WDDELETE, wdId);#endif objCoreTerminate (&wdId->objCore); /* invalidate watchdog */ kernelState = TRUE; /* KERNEL ENTER */ intUnlock (level); /* UNLOCK INTERRUPTS */ windWdCancel (wdId); /* cancel watchdog */ wdId->status = WDOG_DEAD; /* dead dog */ TASK_SAFE (); /* TASK SAFE */ windExit (); /* EXIT KERNEL */ if (dealloc) objFree (wdClassId, (char *) wdId); /* deallocate watchdog */ TASK_UNSAFE (); /* TASK UNSAFE */ return (OK); }/********************************************************************************* wdStart - start a watchdog timer* * This routine adds a watchdog timer to the system tick queue. The* specified watchdog routine will be called from interrupt level after* the specified number of ticks has elapsed. Watchdog timers may be* started from interrupt level. * * To replace either the timeout <delay> or the routine to be executed,* call wdStart() again with the same <wdId>; only the most recent* wdStart() on a given watchdog ID has any effect. (If your* application requires multiple watchdog routines, use wdCreate() to* generate separate a watchdog ID for each.) To cancel a watchdog* timer before the specified tick count is reached, call wdCancel().* * Watchdog timers execute only once, but some applications require* periodically executing timers. To achieve this effect, the timer* routine itself must call wdStart() to restart the timer on each* invocation.* * WARNING: The watchdog routine runs in the context of the* system-clock ISR; thus, it is subject to all ISR restrictions.* * RETURNS: OK, or ERROR if the watchdog timer cannot be started.** SEE ALSO: wdCancel()*/STATUS wdStart ( WDOG_ID wdId, /* watchdog ID */ int delay, /* delay count, in ticks */ FUNCPTR pRoutine, /* routine to call on time-out */ int parameter /* parameter with which to call routine */ ) { int level = intLock (); /* LOCK INTERRUPTS */ if (OBJ_VERIFY (wdId, wdClassId) != OK) { intUnlock (level); /* UNLOCK INTERRUPTS */ return (ERROR); }#ifdef WV_INSTRUMENTATION /* windview - level 1 event logging */ EVT_OBJ_2 (OBJ, wdId, wdClassId, EVENT_WDSTART, wdId, delay);#endif if (kernelState) /* already in kernel? */ { wdId->deferStartCnt ++; /* bump the start count */ wdId->wdParameter = parameter; /* update w/ new parameter */ wdId->wdRoutine = pRoutine; /* update w/ new routine */ intUnlock (level); /* UNLOCK INTERRUPTS */ workQAdd2 (windWdStart, (int)wdId, delay); /* defer the wdStart */ } else { wdId->deferStartCnt = 1; /* initialize start count */ wdId->wdParameter = parameter; /* update w/ new parameter */ wdId->wdRoutine = pRoutine; /* update w/ new routine */ kernelState = TRUE; /* KERNEL ENTER */ intUnlock (level); /* UNLOCK INTERRUPTS */ if (windWdStart (wdId, delay) != OK) /* start the watchdog */ { windExit (); /* KERNEL EXIT */ return (ERROR); } windExit (); /* KERNEL EXIT */ } return (OK); }/********************************************************************************* wdCancel - cancel a currently counting watchdog** This routine cancels a currently running watchdog timer by* zeroing its delay count. Watchdog timers may be canceled from interrupt* level.** RETURNS: OK, or ERROR if the watchdog timer cannot be canceled.** SEE ALSO: wdStart()*/STATUS wdCancel ( WDOG_ID wdId /* ID of watchdog to cancel */ ) { int level = intLock (); /* LOCK INTERRUPTS */ if (OBJ_VERIFY (wdId, wdClassId) != OK) { intUnlock (level); /* UNLOCK INTERRUPTS */ return (ERROR); }#ifdef WV_INSTRUMENTATION /* windview - level 1 event logging */ EVT_OBJ_1 (OBJ, wdId, wdClassId, EVENT_WDCANCEL, wdId);#endif if (kernelState) { intUnlock (level); /* UNLOCK INTERRUPTS */ workQAdd1 ((FUNCPTR)windWdCancel, (int)wdId); } else { kernelState = TRUE; /* KERNEL_ENT */ intUnlock (level); /* UNLOCK INTERRUPTS */ windWdCancel (wdId); /* cancel watchdog */ windExit (); /* KERNEL EXIT */ } return (OK); }/********************************************************************************* wdTick - obsolete routine** This routine is provided for backward compatibility and is simply a NOP* if called.** NOMANUAL*/void wdTick (void) { /* obsolete */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -