Add support for statically allocated watchdog timer structures
This commit is contained in:
parent
09396b39eb
commit
fd484c4de9
@ -2705,33 +2705,35 @@ int up_timer_start(FAR const struct timespec *ts);
|
||||
or <code>kill()</code> to communicate with NuttX tasks.
|
||||
</p>
|
||||
<ul>
|
||||
<li><a href="#wdcreate">4.3.5.1 wd_create</a></li>
|
||||
<li><a href="#wdcreate">4.3.5.1 wd_create/wd_static</a></li>
|
||||
<li><a href="#wddelete">4.3.5.2 wd_delete</a></li>
|
||||
<li><a href="#wdstart">4.3.5.3 wd_start</a></li>
|
||||
<li><a href="#wdcancel">4.3.5.4 wd_cancel</a></li>
|
||||
<li><a href="#wdgettime">4.3.5.5 wd_gettime</a></li>
|
||||
</ul>
|
||||
|
||||
<h4><a name="wdcreate">4.3.5.1 wd_create</a></h4>
|
||||
<h4><a name="wdcreate">4.3.5.1 wd_create/wd_static</a></h4>
|
||||
|
||||
<p>
|
||||
<b>Function Prototype:</b>
|
||||
<pre>
|
||||
#include <nuttx/wdog.h>
|
||||
WDOG_ID wd_create(void);
|
||||
void wd_static(FAR struct wdog_s *wdog);
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<b>Description:</b> The wd_create function will create a watchdog
|
||||
by allocating the appropriate resources for the watchdog.
|
||||
<b>Description:</b> The <code>wd_create()</code> function will create a timer by allocating the appropriate resources for the watchdog. The <code>wd_create()</code> function returns a pointer to a fully initialized, dynamically allocated <code>struct wdog_s</code> instance (which is <code>typedef</code>'ed as <code>WDOG_ID</code>);
|
||||
</p>
|
||||
<p>
|
||||
<code>wd_static()</code> performs the equivalent initialization of a statically allocated <code>struct wdog_s</code> instance. No allocation is performed in this case. The initializer definition, <code>WDOG_INITIALIZER</code> is also available for initialization of static instances of <code>struct wdog_s</code>. NOTE: <code>wd_static()</code> is also implemented as a macro definition.
|
||||
</p>
|
||||
<p>
|
||||
<b>Input Parameters:</b> None.
|
||||
<p>
|
||||
<b>Returned Value:</b>
|
||||
<ul>
|
||||
<li>Pointer to watchdog that may be used as a handle in subsequent
|
||||
NuttX calls (i.e., the watchdog ID), or NULL if insufficient resources
|
||||
are available to create the watchdogs.
|
||||
<li>Pointer to watchdog that may be used as a handle in subsequent NuttX calls (i.e., the watchdog ID), or NULL if insufficient resources are available to create the watchdogs.
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
@ -2760,10 +2762,11 @@ initialization time).
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<b>Description:</b> The wd_delete function will deallocate a
|
||||
watchdog. The watchdog will be removed from the timer queue if
|
||||
has been started.
|
||||
<b>Description:</b> The wd_delete function will deallocate a watchdog timer previously allocated via <code>wd_create()</code>. The watchdog timer will be removed from the timer queue if has been started.
|
||||
<p>
|
||||
<p>
|
||||
This function need not be called for statically allocated timers (but it is not harmful to do so).
|
||||
</p>
|
||||
<b>Input Parameters:</b>
|
||||
<ul>
|
||||
<li><code>wdog</code>. The watchdog ID to delete. This is actually a
|
||||
|
@ -48,11 +48,59 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ********************************************************/
|
||||
|
||||
#ifndef CONFIG_PREALLOC_WDOGS
|
||||
# define CONFIG_PREALLOC_WDOGS 32
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_WDOG_INTRESERVE
|
||||
# if CONFIG_PREALLOC_WDOGS > 16
|
||||
# define CONFIG_WDOG_INTRESERVE 4
|
||||
# elif CONFIG_PREALLOC_WDOGS > 8
|
||||
# define CONFIG_WDOG_INTRESERVE 2
|
||||
# else
|
||||
# define CONFIG_WDOG_INTRESERVE 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_WDOG_INTRESERVE >= CONFIG_PREALLOC_WDOGS
|
||||
# error CONFIG_WDOG_INTRESERVE >= CONFIG_PREALLOC_WDOGS
|
||||
#endif
|
||||
|
||||
/* Watchdog Definitions *************************************************/
|
||||
/* Flag bits for the flags field of struct wdog_s */
|
||||
|
||||
#define WDOGF_ACTIVE (1 << 0) /* Bit 0: 1=Watchdog is actively timing */
|
||||
#define WDOGF_ALLOCED (1 << 1) /* Bit 1: 0=Pre-allocated, 1=Allocated */
|
||||
#define WDOGF_STATIC (1 << 2) /* Bit 2: 0=[Pre-]allocated, 1=Static */
|
||||
|
||||
#define WDOG_SETACTIVE(w) do { (w)->flags |= WDOGF_ACTIVE; } while (0)
|
||||
#define WDOG_SETALLOCED(w) do { (w)->flags |= WDOGF_ALLOCED; } while (0)
|
||||
#define WDOG_SETSTATIC(w) do { (w)->flags |= WDOGF_STATIC; } while (0)
|
||||
|
||||
#define WDOG_CLRACTIVE(w) do { (w)->flags &= ~WDOGF_ACTIVE; } while (0)
|
||||
#define WDOG_CLRALLOCED(w) do { (w)->flags &= ~WDOGF_ALLOCED; } while (0)
|
||||
#define WDOG_CLRSTATIC(w) do { (w)->flags &= ~WDOGF_STATIC; } while (0)
|
||||
|
||||
#define WDOG_ISACTIVE(w) (((w)->flags & WDOGF_ACTIVE) != 0)
|
||||
#define WDOG_ISALLOCED(w) (((w)->flags & WDOGF_ALLOCED) != 0)
|
||||
#define WDOG_ISSTATIC(w) (((w)->flags & WDOGF_STATIC) != 0)
|
||||
|
||||
/* Initialization of statically allocated timers ****************************/
|
||||
|
||||
#define wd_static(w) \
|
||||
do { (w)->next = NULL; (w)->flags = WDOGF_STATIC; } while (0)
|
||||
|
||||
#ifdef CONFIG_PIC
|
||||
# define WDOG_INITIAILIZER { NULL, NULL, NULL, 0, WDOGF_STATIC, 0 }
|
||||
#else
|
||||
# define WDOG_INITIAILIZER { NULL, NULL, 0, WDOGF_STATIC, 0 }
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/* The arguments are passed as uint32_t values. For systems where the
|
||||
* sizeof(pointer) < sizeof(uint32_t), the following union defines the
|
||||
* alignment of the pointer within the uint32_t. For example, the SDCC
|
||||
@ -76,6 +124,23 @@ typedef union wdparm_u wdparm_t;
|
||||
|
||||
typedef CODE void (*wdentry_t)(int argc, uint32_t arg1, ...);
|
||||
|
||||
/* This is the internal representation of the watchdog timer structure. The
|
||||
* WDOG_ID is a pointer to a watchdog structure.
|
||||
*/
|
||||
|
||||
struct wdog_s
|
||||
{
|
||||
FAR struct wdog_s *next; /* Support for singly linked lists. */
|
||||
wdentry_t func; /* Function to execute when delay expires */
|
||||
#ifdef CONFIG_PIC
|
||||
FAR void *picbase; /* PIC base address */
|
||||
#endif
|
||||
int lag; /* Timer associated with the delay */
|
||||
uint8_t flags; /* See WDOGF_* definitions above */
|
||||
uint8_t argc; /* The number of parameters to pass */
|
||||
uint32_t parm[CONFIG_MAX_WDOGPARMS];
|
||||
};
|
||||
|
||||
/* Watchdog 'handle' */
|
||||
|
||||
typedef FAR struct wdog_s *WDOG_ID;
|
||||
|
@ -91,16 +91,16 @@
|
||||
|
||||
int wd_cancel(WDOG_ID wdog)
|
||||
{
|
||||
wdog_t *curr;
|
||||
wdog_t *prev;
|
||||
irqstate_t saved_state;
|
||||
int ret = ERROR;
|
||||
FAR struct wdog_s *curr;
|
||||
FAR struct wdog_s *prev;
|
||||
irqstate_t state;
|
||||
int ret = ERROR;
|
||||
|
||||
/* Prohibit timer interactions with the timer queue until the
|
||||
* cancellation is complete
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
state = irqsave();
|
||||
|
||||
/* Make sure that the watchdog is initialized (non-NULL) and is still
|
||||
* active.
|
||||
@ -114,7 +114,7 @@ int wd_cancel(WDOG_ID wdog)
|
||||
*/
|
||||
|
||||
prev = NULL;
|
||||
curr = (wdog_t*)g_wdactivelist.head;
|
||||
curr = (FAR struct wdog_s *)g_wdactivelist.head;
|
||||
|
||||
while ((curr) && (curr != wdog))
|
||||
{
|
||||
@ -168,6 +168,6 @@ int wd_cancel(WDOG_ID wdog)
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
irqrestore(saved_state);
|
||||
irqrestore(state);
|
||||
return ret;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@
|
||||
|
||||
WDOG_ID wd_create (void)
|
||||
{
|
||||
FAR wdog_t *wdog;
|
||||
FAR struct wdog_s *wdog;
|
||||
irqstate_t state;
|
||||
|
||||
/* These actions must be atomic with respect to other tasks and also with
|
||||
@ -113,7 +113,7 @@ WDOG_ID wd_create (void)
|
||||
* count of free timers all with interrupts disabled.
|
||||
*/
|
||||
|
||||
wdog = (FAR wdog_t*)sq_remfirst(&g_wdfreelist);
|
||||
wdog = (FAR struct wdog_s *)sq_remfirst(&g_wdfreelist);
|
||||
DEBUGASSERT(g_wdnfree > 0);
|
||||
g_wdnfree--;
|
||||
irqrestore(state);
|
||||
@ -139,7 +139,7 @@ WDOG_ID wd_create (void)
|
||||
/* We do not require that interrupts be disabled to do this. */
|
||||
|
||||
irqrestore(state);
|
||||
wdog = (FAR wdog_t *)kmalloc(sizeof(wdog_t));
|
||||
wdog = (FAR struct wdog_s *)kmalloc(sizeof(struct wdog_s));
|
||||
|
||||
/* Did we get one? */
|
||||
|
||||
|
@ -132,9 +132,11 @@ int wd_delete(WDOG_ID wdog)
|
||||
sched_kfree(wdog);
|
||||
}
|
||||
|
||||
/* This was a pre-allocated timer. */
|
||||
/* This was a pre-allocated timer. This function should not be called for
|
||||
* statically allocated timers.
|
||||
*/
|
||||
|
||||
else
|
||||
else if (!WDOG_ISSTATIC(wdog))
|
||||
{
|
||||
/* Put the timer back on the free list and increment the count of free
|
||||
* timers, all with interrupts disabled.
|
||||
|
@ -98,10 +98,10 @@ int wd_gettime(WDOG_ID wdog)
|
||||
* that we are looking for
|
||||
*/
|
||||
|
||||
wdog_t *curr;
|
||||
FAR struct wdog_s *curr;
|
||||
int delay = 0;
|
||||
|
||||
for (curr = (wdog_t*)g_wdactivelist.head; curr; curr = curr->next)
|
||||
for (curr = (FAR struct wdog_s *)g_wdactivelist.head; curr; curr = curr->next)
|
||||
{
|
||||
delay += curr->lag;
|
||||
if (curr == wdog)
|
||||
|
@ -83,7 +83,7 @@ uint16_t g_wdnfree;
|
||||
* in the pool is a configuration item.
|
||||
*/
|
||||
|
||||
static FAR wdog_t g_wdpool[CONFIG_PREALLOC_WDOGS];
|
||||
static struct wdog_s g_wdpool[CONFIG_PREALLOC_WDOGS];
|
||||
|
||||
/************************************************************************
|
||||
* Private Functions
|
||||
@ -114,7 +114,7 @@ static FAR wdog_t g_wdpool[CONFIG_PREALLOC_WDOGS];
|
||||
|
||||
void wd_initialize(void)
|
||||
{
|
||||
FAR wdog_t *wdog = g_wdpool;
|
||||
FAR struct wdog_s *wdog = g_wdpool;
|
||||
int i;
|
||||
|
||||
/* Initialize watchdog lists */
|
||||
|
@ -115,22 +115,22 @@ typedef void (*wdentry4_t)(int argc, uint32_t arg1, uint32_t arg2,
|
||||
|
||||
static inline void wd_expiration(void)
|
||||
{
|
||||
FAR wdog_t *wdog;
|
||||
FAR struct wdog_s *wdog;
|
||||
|
||||
/* Check if the watchdog at the head of the list is ready to run */
|
||||
|
||||
if (((FAR wdog_t*)g_wdactivelist.head)->lag <= 0)
|
||||
if (((FAR struct wdog_s *)g_wdactivelist.head)->lag <= 0)
|
||||
{
|
||||
/* Process the watchdog at the head of the list as well as any
|
||||
* other watchdogs that became ready to run at this time
|
||||
*/
|
||||
|
||||
while (g_wdactivelist.head &&
|
||||
((FAR wdog_t*)g_wdactivelist.head)->lag <= 0)
|
||||
((FAR struct wdog_s *)g_wdactivelist.head)->lag <= 0)
|
||||
{
|
||||
/* Remove the watchdog from the head of the list */
|
||||
|
||||
wdog = (FAR wdog_t*)sq_remfirst(&g_wdactivelist);
|
||||
wdog = (FAR struct wdog_s *)sq_remfirst(&g_wdactivelist);
|
||||
|
||||
/* If there is another watchdog behind this one, update its
|
||||
* its lag (this shouldn't be necessary).
|
||||
@ -138,7 +138,7 @@ static inline void wd_expiration(void)
|
||||
|
||||
if (g_wdactivelist.head)
|
||||
{
|
||||
((FAR wdog_t*)g_wdactivelist.head)->lag += wdog->lag;
|
||||
((FAR struct wdog_s *)g_wdactivelist.head)->lag += wdog->lag;
|
||||
}
|
||||
|
||||
/* Indicate that the watchdog is no longer active. */
|
||||
@ -227,13 +227,13 @@ static inline void wd_expiration(void)
|
||||
|
||||
int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...)
|
||||
{
|
||||
va_list ap;
|
||||
FAR wdog_t *curr;
|
||||
FAR wdog_t *prev;
|
||||
FAR wdog_t *next;
|
||||
int32_t now;
|
||||
irqstate_t saved_state;
|
||||
int i;
|
||||
va_list ap;
|
||||
FAR struct wdog_s *curr;
|
||||
FAR struct wdog_s *prev;
|
||||
FAR struct wdog_s *next;
|
||||
int32_t now;
|
||||
irqstate_t state;
|
||||
int i;
|
||||
|
||||
/* Verify the wdog */
|
||||
|
||||
@ -249,7 +249,7 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...)
|
||||
* the critical section is established.
|
||||
*/
|
||||
|
||||
saved_state = irqsave();
|
||||
state = irqsave();
|
||||
if (WDOG_ISACTIVE(wdog))
|
||||
{
|
||||
wd_cancel(wdog);
|
||||
@ -309,7 +309,7 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...)
|
||||
else
|
||||
{
|
||||
now = 0;
|
||||
prev = curr = (FAR wdog_t*)g_wdactivelist.head;
|
||||
prev = curr = (FAR struct wdog_s *)g_wdactivelist.head;
|
||||
|
||||
/* Advance to positive time */
|
||||
|
||||
@ -342,17 +342,17 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...)
|
||||
|
||||
/* Insert the new watchdog in the list */
|
||||
|
||||
if (curr == (FAR wdog_t*)g_wdactivelist.head)
|
||||
if (curr == (FAR struct wdog_s *)g_wdactivelist.head)
|
||||
{
|
||||
/* Insert the watchdog at the head of the list */
|
||||
|
||||
sq_addfirst((FAR sq_entry_t*)wdog, &g_wdactivelist);
|
||||
sq_addfirst((FAR sq_entry_t *)wdog, &g_wdactivelist);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Insert the watchdog in mid- or end-of-queue */
|
||||
|
||||
sq_addafter((FAR sq_entry_t*)prev, (FAR sq_entry_t*)wdog,
|
||||
sq_addafter((FAR sq_entry_t *)prev, (FAR sq_entry_t *)wdog,
|
||||
&g_wdactivelist);
|
||||
|
||||
}
|
||||
@ -394,7 +394,7 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...)
|
||||
sched_timer_resume();
|
||||
#endif
|
||||
|
||||
irqrestore(saved_state);
|
||||
irqrestore(state);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -426,7 +426,7 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...)
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
unsigned int wd_timer(int ticks)
|
||||
{
|
||||
FAR wdog_t *wdog;
|
||||
FAR struct wdog_s *wdog;
|
||||
int decr;
|
||||
|
||||
/* Check if there are any active watchdogs to process */
|
||||
@ -435,7 +435,7 @@ unsigned int wd_timer(int ticks)
|
||||
{
|
||||
/* Get the watchdog at the head of the list */
|
||||
|
||||
wdog = (FAR wdog_t*)g_wdactivelist.head;
|
||||
wdog = (FAR struct wdog_s *)g_wdactivelist.head;
|
||||
|
||||
#ifndef CONFIG_SCHED_TICKLESS_ALARM
|
||||
/* There is logic to handle the case where ticks is greater than
|
||||
@ -462,7 +462,7 @@ unsigned int wd_timer(int ticks)
|
||||
/* Return the delay for the next watchdog to expire */
|
||||
|
||||
return g_wdactivelist.head ?
|
||||
((FAR wdog_t*)g_wdactivelist.head)->lag : 0;
|
||||
((FAR struct wdog_s *)g_wdactivelist.head)->lag : 0;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -474,7 +474,7 @@ void wd_timer(void)
|
||||
{
|
||||
/* There are. Decrement the lag counter */
|
||||
|
||||
--(((FAR wdog_t*)g_wdactivelist.head)->lag);
|
||||
--(((FAR struct wdog_s *)g_wdactivelist.head)->lag);
|
||||
|
||||
/* Check if the watchdog at the head of the list is ready to run */
|
||||
|
||||
|
@ -51,63 +51,11 @@
|
||||
/************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************/
|
||||
/* Configuration ********************************************************/
|
||||
|
||||
#ifndef CONFIG_PREALLOC_WDOGS
|
||||
# define CONFIG_PREALLOC_WDOGS 32
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_WDOG_INTRESERVE
|
||||
# if CONFIG_PREALLOC_WDOGS > 16
|
||||
# define CONFIG_WDOG_INTRESERVE 4
|
||||
# elif CONFIG_PREALLOC_WDOGS > 8
|
||||
# define CONFIG_WDOG_INTRESERVE 2
|
||||
# else
|
||||
# define CONFIG_WDOG_INTRESERVE 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_WDOG_INTRESERVE >= CONFIG_PREALLOC_WDOGS
|
||||
# error CONFIG_WDOG_INTRESERVE >= CONFIG_PREALLOC_WDOGS
|
||||
#endif
|
||||
|
||||
/* Watchdog Definitions *************************************************/
|
||||
/* Flag bits for the flags field of struct wdog_s */
|
||||
|
||||
#define WDOGF_ACTIVE (1 << 0) /* Watchdog is actively timing */
|
||||
#define WDOGF_ALLOCED (1 << 1) /* 0:Pre-allocated, 1:Allocated */
|
||||
|
||||
#define WDOG_SETACTIVE(w) do { (w)->flags |= WDOGF_ACTIVE; } while (0)
|
||||
#define WDOG_SETALLOCED(w) do { (w)->flags |= WDOGF_ALLOCED; } while (0)
|
||||
|
||||
#define WDOG_CLRACTIVE(w) do { (w)->flags &= ~WDOGF_ACTIVE; } while (0)
|
||||
#define WDOG_CLRALLOCED(w) do { (w)->flags &= ~WDOGF_ALLOCED; } while (0)
|
||||
|
||||
#define WDOG_ISACTIVE(w) (((w)->flags & WDOGF_ACTIVE) != 0)
|
||||
#define WDOG_ISALLOCED(w) (((w)->flags & WDOGF_ALLOCED) != 0)
|
||||
|
||||
/************************************************************************
|
||||
* Public Type Declarations
|
||||
************************************************************************/
|
||||
|
||||
/* This is the watchdog structure. The WDOG_ID is a pointer to a
|
||||
* watchdog structure.
|
||||
*/
|
||||
|
||||
struct wdog_s
|
||||
{
|
||||
FAR struct wdog_s *next; /* Support for singly linked lists. */
|
||||
wdentry_t func; /* Function to execute when delay expires */
|
||||
#ifdef CONFIG_PIC
|
||||
FAR void *picbase; /* PIC base address */
|
||||
#endif
|
||||
int lag; /* Timer associated with the delay */
|
||||
uint8_t flags; /* See WDOGF_* definitions above */
|
||||
uint8_t argc; /* The number of parameters to pass */
|
||||
uint32_t parm[CONFIG_MAX_WDOGPARMS];
|
||||
};
|
||||
typedef struct wdog_s wdog_t;
|
||||
|
||||
/************************************************************************
|
||||
* Public Variables
|
||||
************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user