summaryrefslogtreecommitdiff
path: root/include/rtems/score/watchdogimpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/rtems/score/watchdogimpl.h')
-rw-r--r--include/rtems/score/watchdogimpl.h513
1 files changed, 513 insertions, 0 deletions
diff --git a/include/rtems/score/watchdogimpl.h b/include/rtems/score/watchdogimpl.h
new file mode 100644
index 0000000000..0e04f64d7b
--- /dev/null
+++ b/include/rtems/score/watchdogimpl.h
@@ -0,0 +1,513 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines in the Watchdog Handler
+ *
+ * This file contains the static inline implementation of all inlined
+ * routines in the Watchdog Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_WATCHDOGIMPL_H
+#define _RTEMS_SCORE_WATCHDOGIMPL_H
+
+#include <rtems/score/watchdog.h>
+#include <rtems/score/assert.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/isrlock.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreWatchdog
+ * @{
+ */
+
+/**
+ * @brief Watchdog initializer for static initialization.
+ *
+ * @see _Watchdog_Initialize().
+ */
+#define WATCHDOG_INITIALIZER( routine, id, user_data ) \
+ { \
+ { NULL, NULL }, \
+ WATCHDOG_INACTIVE, \
+ 0, 0, 0, 0, \
+ ( routine ), ( id ), ( user_data ) \
+ }
+
+/**
+ * @brief Iterator item to synchronize concurrent insert, remove and tickle
+ * operations.
+ */
+typedef struct {
+ /**
+ * @brief A node for a Watchdog_Header::Iterators chain.
+ */
+ Chain_Node Node;
+
+ /**
+ * @brief The current delta interval of the new watchdog to insert.
+ */
+ Watchdog_Interval delta_interval;
+
+ /**
+ * @brief The current watchdog of the chain on the way to insert the new
+ * watchdog.
+ */
+ Chain_Node *current;
+} Watchdog_Iterator;
+
+/**
+ * @brief Watchdog header.
+ */
+typedef struct {
+ /**
+ * @brief ISR lock to protect this watchdog chain.
+ */
+ ISR_LOCK_MEMBER( Lock )
+
+ /**
+ * @brief The chain of active or transient watchdogs.
+ */
+ Chain_Control Watchdogs;
+
+ /**
+ * @brief Currently active iterators.
+ *
+ * The iterators are registered in _Watchdog_Insert() and updated in case the
+ * watchdog chain changes.
+ */
+ Chain_Control Iterators;
+} Watchdog_Header;
+
+/**
+ * @brief Watchdog chain which is managed at ticks.
+ *
+ * This is the watchdog chain which is managed at ticks.
+ */
+SCORE_EXTERN Watchdog_Header _Watchdog_Ticks_header;
+
+/**
+ * @brief Watchdog chain which is managed at second boundaries.
+ *
+ * This is the watchdog chain which is managed at second boundaries.
+ */
+SCORE_EXTERN Watchdog_Header _Watchdog_Seconds_header;
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Acquire(
+ Watchdog_Header *header,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_ISR_disable_and_acquire( &header->Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Release(
+ Watchdog_Header *header,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release_and_ISR_enable( &header->Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Flash(
+ Watchdog_Header *header,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Flash( &header->Lock, lock_context );
+}
+
+/**
+ * @brief Initialize the watchdog handler.
+ *
+ * This routine initializes the watchdog handler. The watchdog
+ * synchronization flag is initialized and the watchdog chains are
+ * initialized and emptied.
+ */
+void _Watchdog_Handler_initialization( void );
+
+/**
+ * @brief Triggers a watchdog tick.
+ *
+ * This routine executes TOD, watchdog and scheduler ticks.
+ */
+void _Watchdog_Tick( void );
+
+/**
+ * @brief Removes @a the_watchdog from the watchdog chain.
+ *
+ * This routine removes @a the_watchdog from the watchdog chain on which
+ * it resides and returns the state @a the_watchdog timer was in.
+ *
+ * @param[in] header The watchdog chain.
+ * @param[in] the_watchdog will be removed
+ * @retval the state in which @a the_watchdog was in when removed
+ */
+Watchdog_States _Watchdog_Remove (
+ Watchdog_Header *header,
+ Watchdog_Control *the_watchdog
+);
+
+/**
+ * @brief Adjusts the header watchdog chain in the backward direction for
+ * units ticks.
+ *
+ * @param[in] header The watchdog chain.
+ * @param[in] units The units of ticks to adjust.
+ */
+void _Watchdog_Adjust_backward(
+ Watchdog_Header *header,
+ Watchdog_Interval units
+);
+
+/**
+ * @brief Adjusts the watchdogs in backward direction in a locked context.
+ *
+ * The caller must be the owner of the watchdog lock and will be the owner
+ * after the call.
+ *
+ * @param[in] header The watchdog header.
+ * @param[in] units The units of ticks to adjust.
+ *
+ * @see _Watchdog_Adjust_forward().
+ */
+void _Watchdog_Adjust_backward_locked(
+ Watchdog_Header *header,
+ Watchdog_Interval units
+);
+
+/**
+ * @brief Adjusts the header watchdog chain in the forward direction for units
+ * ticks.
+ *
+ * This may lead to several _Watchdog_Tickle() invocations.
+ *
+ * @param[in] header The watchdog chain.
+ * @param[in] units The units of ticks to adjust.
+ */
+void _Watchdog_Adjust_forward(
+ Watchdog_Header *header,
+ Watchdog_Interval units
+);
+
+/**
+ * @brief Adjusts the watchdogs in forward direction in a locked context.
+ *
+ * The caller must be the owner of the watchdog lock and will be the owner
+ * after the call. This function may release and acquire the watchdog lock
+ * internally.
+ *
+ * @param[in] header The watchdog header.
+ * @param[in] units The units of ticks to adjust.
+ * @param[in] lock_context The lock context.
+ *
+ * @see _Watchdog_Adjust_forward().
+ */
+void _Watchdog_Adjust_forward_locked(
+ Watchdog_Header *header,
+ Watchdog_Interval units,
+ ISR_lock_Context *lock_context
+);
+
+/**
+ * @brief Inserts @a the_watchdog into the @a header watchdog chain
+ * for a time of @a units.
+ *
+ * This routine inserts @a the_watchdog into the @a header watchdog chain
+ * for a time of @a units.
+ * Update the delta interval counters.
+ *
+ * @param[in] header is @a the_watchdog list to insert @a the_watchdog on
+ * @param[in] the_watchdog is the watchdog to insert
+ */
+void _Watchdog_Insert (
+ Watchdog_Header *header,
+ Watchdog_Control *the_watchdog
+);
+
+/**
+ * @brief Inserts the watchdog in a locked context.
+ *
+ * The caller must be the owner of the watchdog lock and will be the owner
+ * after the call. This function may release and acquire the watchdog lock
+ * internally.
+ *
+ * @param[in] header The watchdog header.
+ * @param[in] the_watchdog The watchdog.
+ * @param[in] lock_context The lock context.
+ *
+ * @see _Watchdog_Insert().
+ */
+void _Watchdog_Insert_locked(
+ Watchdog_Header *header,
+ Watchdog_Control *the_watchdog,
+ ISR_lock_Context *lock_context
+);
+
+/**
+ * @brief This routine is invoked at appropriate intervals to update
+ * the @a header watchdog chain.
+ *
+ * This routine is invoked at appropriate intervals to update
+ * the @a header watchdog chain.
+ * This routine decrements the delta counter in response to a tick.
+ *
+ * @param[in] header is the watchdog chain to tickle
+ */
+void _Watchdog_Tickle (
+ Watchdog_Header *header
+);
+
+/**
+ * @brief Pre-initializes a watchdog.
+ *
+ * This routine must be called before a watchdog is used in any way. The
+ * exception are statically initialized watchdogs via WATCHDOG_INITIALIZER().
+ *
+ * @param[in] the_watchdog The uninitialized watchdog.
+ */
+RTEMS_INLINE_ROUTINE void _Watchdog_Preinitialize(
+ Watchdog_Control *the_watchdog
+)
+{
+ the_watchdog->state = WATCHDOG_INACTIVE;
+#if defined(RTEMS_DEBUG)
+ the_watchdog->routine = NULL;
+ the_watchdog->id = 0;
+ the_watchdog->user_data = NULL;
+#endif
+}
+
+/**
+ * This routine initializes the specified watchdog. The watchdog is
+ * made inactive, the watchdog id and handler routine are set to the
+ * specified values.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Initialize(
+ Watchdog_Control *the_watchdog,
+ Watchdog_Service_routine_entry routine,
+ Objects_Id id,
+ void *user_data
+)
+{
+ _Assert( the_watchdog->state == WATCHDOG_INACTIVE );
+ the_watchdog->routine = routine;
+ the_watchdog->id = id;
+ the_watchdog->user_data = user_data;
+}
+
+/**
+ * This routine returns true if the watchdog timer is in the ACTIVE
+ * state, and false otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE bool _Watchdog_Is_active(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ return ( the_watchdog->state == WATCHDOG_ACTIVE );
+
+}
+
+/**
+ * This routine activates THE_WATCHDOG timer which is already
+ * on a watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Activate(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ the_watchdog->state = WATCHDOG_ACTIVE;
+
+}
+
+/**
+ * This routine is invoked at each clock tick to update the ticks
+ * watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_ticks( void )
+{
+
+ _Watchdog_Tickle( &_Watchdog_Ticks_header );
+
+}
+
+/**
+ * This routine is invoked at each clock tick to update the seconds
+ * watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_seconds( void )
+{
+
+ _Watchdog_Tickle( &_Watchdog_Seconds_header );
+
+}
+
+/**
+ * This routine inserts THE_WATCHDOG into the ticks watchdog chain
+ * for a time of UNITS ticks. The INSERT_MODE indicates whether
+ * THE_WATCHDOG is to be activated automatically or later, explicitly
+ * by the caller.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Insert_ticks(
+ Watchdog_Control *the_watchdog,
+ Watchdog_Interval units
+)
+{
+
+ the_watchdog->initial = units;
+
+ _Watchdog_Insert( &_Watchdog_Ticks_header, the_watchdog );
+
+}
+
+/**
+ * This routine inserts THE_WATCHDOG into the seconds watchdog chain
+ * for a time of UNITS seconds. The INSERT_MODE indicates whether
+ * THE_WATCHDOG is to be activated automatically or later, explicitly
+ * by the caller.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Insert_seconds(
+ Watchdog_Control *the_watchdog,
+ Watchdog_Interval units
+)
+{
+
+ the_watchdog->initial = units;
+
+ _Watchdog_Insert( &_Watchdog_Seconds_header, the_watchdog );
+
+}
+
+RTEMS_INLINE_ROUTINE Watchdog_States _Watchdog_Remove_ticks(
+ Watchdog_Control *the_watchdog
+)
+{
+ return _Watchdog_Remove( &_Watchdog_Ticks_header, the_watchdog );
+}
+
+RTEMS_INLINE_ROUTINE Watchdog_States _Watchdog_Remove_seconds(
+ Watchdog_Control *the_watchdog
+)
+{
+ return _Watchdog_Remove( &_Watchdog_Seconds_header, the_watchdog );
+}
+
+/**
+ * This routine resets THE_WATCHDOG timer to its state at INSERT
+ * time. This routine is valid only on interval watchdog timers
+ * and is used to make an interval watchdog timer fire "every" so
+ * many ticks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Reset_ticks(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ _Watchdog_Remove_ticks( the_watchdog );
+
+ _Watchdog_Insert( &_Watchdog_Ticks_header, the_watchdog );
+
+}
+
+/**
+ * This routine returns a pointer to the watchdog timer following
+ * THE_WATCHDOG on the watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Next(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ return ( (Watchdog_Control *) the_watchdog->Node.next );
+
+}
+
+/**
+ * This routine returns a pointer to the watchdog timer preceding
+ * THE_WATCHDOG on the watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Previous(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ return ( (Watchdog_Control *) the_watchdog->Node.previous );
+
+}
+
+/**
+ * This routine returns a pointer to the first watchdog timer
+ * on the watchdog chain HEADER.
+ */
+
+RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_First(
+ Watchdog_Header *header
+)
+{
+
+ return ( (Watchdog_Control *) _Chain_First( &header->Watchdogs ) );
+
+}
+
+/**
+ * This routine returns a pointer to the last watchdog timer
+ * on the watchdog chain HEADER.
+ */
+
+RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Last(
+ Watchdog_Header *header
+)
+{
+
+ return ( (Watchdog_Control *) _Chain_Last( &header->Watchdogs ) );
+
+}
+
+RTEMS_INLINE_ROUTINE bool _Watchdog_Is_empty(
+ const Watchdog_Header *header
+)
+{
+ return _Chain_Is_empty( &header->Watchdogs );
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Header_initialize(
+ Watchdog_Header *header
+)
+{
+ _ISR_lock_Initialize( &header->Lock, "Watchdog" );
+ _Chain_Initialize_empty( &header->Watchdogs );
+ _Chain_Initialize_empty( &header->Iterators );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */