source: rtems/cpukit/score/include/rtems/score/watchdogimpl.h @ 80fca28

4.115
Last change on this file since 80fca28 was 80fca28, checked in by Sebastian Huber <sebastian.huber@…>, on 06/13/15 at 13:29:04

score: Add _Watchdog_Preinitialize()

Add an assert to ensure that the watchdog is the proper state for a
_Watchdog_Initialize(). This helps to detect invalid initializations
which may lead to a corrupt watchdog chain.

  • Property mode set to 100644
File size: 11.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Inlined Routines in the Watchdog Handler
5 *
6 * This file contains the static inline implementation of all inlined
7 * routines in the Watchdog Handler.
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2004.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_WATCHDOGIMPL_H
20#define _RTEMS_SCORE_WATCHDOGIMPL_H
21
22#include <rtems/score/watchdog.h>
23#include <rtems/score/assert.h>
24#include <rtems/score/chainimpl.h>
25#include <rtems/score/isrlock.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/**
32 *  @addtogroup ScoreWatchdog
33 *  @{
34 */
35
36/**
37 * @brief Watchdog initializer for static initialization.
38 *
39 * @see _Watchdog_Initialize().
40 */
41#define WATCHDOG_INITIALIZER( routine, id, user_data ) \
42  { \
43    { NULL, NULL }, \
44    WATCHDOG_INACTIVE, \
45    0, 0, 0, 0, \
46    ( routine ), ( id ), ( user_data ) \
47  }
48
49/**
50 * @brief Iterator item to synchronize concurrent insert, remove and tickle
51 * operations.
52 */
53typedef struct {
54  /**
55   * @brief A node for a Watchdog_Header::Iterators chain.
56   */
57  Chain_Node Node;
58
59  /**
60   * @brief The current delta interval of the new watchdog to insert.
61   */
62  Watchdog_Interval delta_interval;
63
64  /**
65   * @brief The current watchdog of the chain on the way to insert the new
66   * watchdog.
67   */
68  Chain_Node *current;
69} Watchdog_Iterator;
70
71/**
72 * @brief Watchdog header.
73 */
74typedef struct {
75  /**
76   * @brief ISR lock to protect this watchdog chain.
77   */
78  ISR_LOCK_MEMBER( Lock )
79
80  /**
81   * @brief The chain of active or transient watchdogs.
82   */
83  Chain_Control Watchdogs;
84
85  /**
86   * @brief Currently active iterators.
87   *
88   * The iterators are registered in _Watchdog_Insert() and updated in case the
89   * watchdog chain changes.
90   */
91  Chain_Control Iterators;
92} Watchdog_Header;
93
94/**
95 *  @brief Watchdog chain which is managed at ticks.
96 *
97 *  This is the watchdog chain which is managed at ticks.
98 */
99SCORE_EXTERN Watchdog_Header _Watchdog_Ticks_header;
100
101/**
102 *  @brief Watchdog chain which is managed at second boundaries.
103 *
104 *  This is the watchdog chain which is managed at second boundaries.
105 */
106SCORE_EXTERN Watchdog_Header _Watchdog_Seconds_header;
107
108RTEMS_INLINE_ROUTINE void _Watchdog_Acquire(
109  Watchdog_Header  *header,
110  ISR_lock_Context *lock_context
111)
112{
113  _ISR_lock_ISR_disable_and_acquire( &header->Lock, lock_context );
114}
115
116RTEMS_INLINE_ROUTINE void _Watchdog_Release(
117  Watchdog_Header  *header,
118  ISR_lock_Context *lock_context
119)
120{
121  _ISR_lock_Release_and_ISR_enable( &header->Lock, lock_context );
122}
123
124RTEMS_INLINE_ROUTINE void _Watchdog_Flash(
125  Watchdog_Header  *header,
126  ISR_lock_Context *lock_context
127)
128{
129  _ISR_lock_Flash( &header->Lock, lock_context );
130}
131
132/**
133 *  @brief Initialize the watchdog handler.
134 *
135 *  This routine initializes the watchdog handler.  The watchdog
136 *  synchronization flag is initialized and the watchdog chains are
137 *  initialized and emptied.
138 */
139void _Watchdog_Handler_initialization( void );
140
141/**
142 *  @brief Triggers a watchdog tick.
143 *
144 *  This routine executes TOD, watchdog and scheduler ticks.
145 */
146void _Watchdog_Tick( void );
147
148/**
149 *  @brief Removes @a the_watchdog from the watchdog chain.
150 *
151 *  This routine removes @a the_watchdog from the watchdog chain on which
152 *  it resides and returns the state @a the_watchdog timer was in.
153 *
154 *  @param[in] header The watchdog chain.
155 *  @param[in] the_watchdog will be removed
156 *  @retval the state in which @a the_watchdog was in when removed
157 */
158Watchdog_States _Watchdog_Remove (
159  Watchdog_Header  *header,
160  Watchdog_Control *the_watchdog
161);
162
163/**
164 *  @brief Adjusts the header watchdog chain in the backward direction for
165 *  units ticks.
166 *
167 *  @param[in] header The watchdog chain.
168 *  @param[in] units The units of ticks to adjust.
169 */
170void _Watchdog_Adjust_backward(
171  Watchdog_Header   *header,
172  Watchdog_Interval  units
173);
174
175/**
176 * @brief Adjusts the watchdogs in backward direction in a locked context.
177 *
178 * The caller must be the owner of the watchdog lock and will be the owner
179 * after the call.
180 *
181 * @param[in] header The watchdog header.
182 * @param[in] units The units of ticks to adjust.
183 *
184 * @see _Watchdog_Adjust_forward().
185 */
186void _Watchdog_Adjust_backward_locked(
187  Watchdog_Header   *header,
188  Watchdog_Interval  units
189);
190
191/**
192 *  @brief Adjusts the header watchdog chain in the forward direction for units
193 *  ticks.
194 *
195 *  This may lead to several _Watchdog_Tickle() invocations.
196 *
197 *  @param[in] header The watchdog chain.
198 *  @param[in] units The units of ticks to adjust.
199 */
200void _Watchdog_Adjust_forward(
201  Watchdog_Header   *header,
202  Watchdog_Interval  units
203);
204
205/**
206 * @brief Adjusts the watchdogs in forward direction in a locked context.
207 *
208 * The caller must be the owner of the watchdog lock and will be the owner
209 * after the call.  This function may release and acquire the watchdog lock
210 * internally.
211 *
212 * @param[in] header The watchdog header.
213 * @param[in] units The units of ticks to adjust.
214 * @param[in] lock_context The lock context.
215 *
216 * @see _Watchdog_Adjust_forward().
217 */
218void _Watchdog_Adjust_forward_locked(
219  Watchdog_Header   *header,
220  Watchdog_Interval  units,
221  ISR_lock_Context  *lock_context
222);
223
224/**
225 *  @brief Inserts @a the_watchdog into the @a header watchdog chain
226 *  for a time of @a units.
227 *
228 *  This routine inserts @a the_watchdog into the @a header watchdog chain
229 *  for a time of @a units.
230 *  Update the delta interval counters.
231 *
232 *  @param[in] header is @a the_watchdog list to insert @a the_watchdog on
233 *  @param[in] the_watchdog is the watchdog to insert
234 */
235void _Watchdog_Insert (
236  Watchdog_Header  *header,
237  Watchdog_Control *the_watchdog
238);
239
240/**
241 * @brief Inserts the watchdog in a locked context.
242 *
243 * The caller must be the owner of the watchdog lock and will be the owner
244 * after the call.  This function may release and acquire the watchdog lock
245 * internally.
246 *
247 * @param[in] header The watchdog header.
248 * @param[in] the_watchdog The watchdog.
249 * @param[in] lock_context The lock context.
250 *
251 * @see _Watchdog_Insert().
252 */
253void _Watchdog_Insert_locked(
254  Watchdog_Header  *header,
255  Watchdog_Control *the_watchdog,
256  ISR_lock_Context *lock_context
257);
258
259/**
260 *  @brief This routine is invoked at appropriate intervals to update
261 *  the @a header watchdog chain.
262 *
263 *  This routine is invoked at appropriate intervals to update
264 *  the @a header watchdog chain.
265 *  This routine decrements the delta counter in response to a tick.
266 *
267 *  @param[in] header is the watchdog chain to tickle
268 */
269void _Watchdog_Tickle (
270  Watchdog_Header *header
271);
272
273/**
274 * @brief Pre-initializes a watchdog.
275 *
276 * This routine must be called before a watchdog is used in any way.  The
277 * exception are statically initialized watchdogs via WATCHDOG_INITIALIZER().
278 *
279 * @param[in] the_watchdog The uninitialized watchdog.
280 */
281RTEMS_INLINE_ROUTINE void _Watchdog_Preinitialize(
282  Watchdog_Control *the_watchdog
283)
284{
285  the_watchdog->state = WATCHDOG_INACTIVE;
286#if defined(RTEMS_DEBUG)
287  the_watchdog->routine = NULL;
288  the_watchdog->id = 0;
289  the_watchdog->user_data = NULL;
290#endif
291}
292
293/**
294 * This routine initializes the specified watchdog.  The watchdog is
295 * made inactive, the watchdog id and handler routine are set to the
296 * specified values.
297 */
298
299RTEMS_INLINE_ROUTINE void _Watchdog_Initialize(
300  Watchdog_Control               *the_watchdog,
301  Watchdog_Service_routine_entry  routine,
302  Objects_Id                      id,
303  void                           *user_data
304)
305{
306  _Assert( the_watchdog->state == WATCHDOG_INACTIVE );
307  the_watchdog->routine   = routine;
308  the_watchdog->id        = id;
309  the_watchdog->user_data = user_data;
310}
311
312/**
313 * This routine returns true if the watchdog timer is in the ACTIVE
314 * state, and false otherwise.
315 */
316
317RTEMS_INLINE_ROUTINE bool _Watchdog_Is_active(
318  Watchdog_Control *the_watchdog
319)
320{
321
322  return ( the_watchdog->state == WATCHDOG_ACTIVE );
323
324}
325
326/**
327 * This routine activates THE_WATCHDOG timer which is already
328 * on a watchdog chain.
329 */
330
331RTEMS_INLINE_ROUTINE void _Watchdog_Activate(
332  Watchdog_Control *the_watchdog
333)
334{
335
336  the_watchdog->state = WATCHDOG_ACTIVE;
337
338}
339
340/**
341 * This routine is invoked at each clock tick to update the ticks
342 * watchdog chain.
343 */
344
345RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_ticks( void )
346{
347
348  _Watchdog_Tickle( &_Watchdog_Ticks_header );
349
350}
351
352/**
353 * This routine is invoked at each clock tick to update the seconds
354 * watchdog chain.
355 */
356
357RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_seconds( void )
358{
359
360  _Watchdog_Tickle( &_Watchdog_Seconds_header );
361
362}
363
364/**
365 * This routine inserts THE_WATCHDOG into the ticks watchdog chain
366 * for a time of UNITS ticks.  The INSERT_MODE indicates whether
367 * THE_WATCHDOG is to be activated automatically or later, explicitly
368 * by the caller.
369 */
370
371RTEMS_INLINE_ROUTINE void _Watchdog_Insert_ticks(
372  Watchdog_Control      *the_watchdog,
373  Watchdog_Interval      units
374)
375{
376
377  the_watchdog->initial = units;
378
379  _Watchdog_Insert( &_Watchdog_Ticks_header, the_watchdog );
380
381}
382
383/**
384 * This routine inserts THE_WATCHDOG into the seconds watchdog chain
385 * for a time of UNITS seconds.  The INSERT_MODE indicates whether
386 * THE_WATCHDOG is to be activated automatically or later, explicitly
387 * by the caller.
388 */
389
390RTEMS_INLINE_ROUTINE void _Watchdog_Insert_seconds(
391  Watchdog_Control      *the_watchdog,
392  Watchdog_Interval      units
393)
394{
395
396  the_watchdog->initial = units;
397
398  _Watchdog_Insert( &_Watchdog_Seconds_header, the_watchdog );
399
400}
401
402RTEMS_INLINE_ROUTINE Watchdog_States _Watchdog_Remove_ticks(
403  Watchdog_Control *the_watchdog
404)
405{
406  return _Watchdog_Remove( &_Watchdog_Ticks_header, the_watchdog );
407}
408
409RTEMS_INLINE_ROUTINE Watchdog_States _Watchdog_Remove_seconds(
410  Watchdog_Control *the_watchdog
411)
412{
413  return _Watchdog_Remove( &_Watchdog_Seconds_header, the_watchdog );
414}
415
416/**
417 * This routine resets THE_WATCHDOG timer to its state at INSERT
418 * time.  This routine is valid only on interval watchdog timers
419 * and is used to make an interval watchdog timer fire "every" so
420 * many ticks.
421 */
422
423RTEMS_INLINE_ROUTINE void _Watchdog_Reset_ticks(
424  Watchdog_Control *the_watchdog
425)
426{
427
428  _Watchdog_Remove_ticks( the_watchdog );
429
430  _Watchdog_Insert( &_Watchdog_Ticks_header, the_watchdog );
431
432}
433
434/**
435 * This routine returns a pointer to the watchdog timer following
436 * THE_WATCHDOG on the watchdog chain.
437 */
438
439RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Next(
440  Watchdog_Control *the_watchdog
441)
442{
443
444  return ( (Watchdog_Control *) the_watchdog->Node.next );
445
446}
447
448/**
449 * This routine returns a pointer to the watchdog timer preceding
450 * THE_WATCHDOG on the watchdog chain.
451 */
452
453RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Previous(
454  Watchdog_Control *the_watchdog
455)
456{
457
458  return ( (Watchdog_Control *) the_watchdog->Node.previous );
459
460}
461
462/**
463 * This routine returns a pointer to the first watchdog timer
464 * on the watchdog chain HEADER.
465 */
466
467RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_First(
468  Watchdog_Header *header
469)
470{
471
472  return ( (Watchdog_Control *) _Chain_First( &header->Watchdogs ) );
473
474}
475
476/**
477 * This routine returns a pointer to the last watchdog timer
478 * on the watchdog chain HEADER.
479 */
480
481RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Last(
482  Watchdog_Header *header
483)
484{
485
486  return ( (Watchdog_Control *) _Chain_Last( &header->Watchdogs ) );
487
488}
489
490RTEMS_INLINE_ROUTINE bool _Watchdog_Is_empty(
491  const Watchdog_Header *header
492)
493{
494  return _Chain_Is_empty( &header->Watchdogs );
495}
496
497RTEMS_INLINE_ROUTINE void _Watchdog_Header_initialize(
498  Watchdog_Header *header
499)
500{
501  _ISR_lock_Initialize( &header->Lock, "Watchdog" );
502  _Chain_Initialize_empty( &header->Watchdogs );
503  _Chain_Initialize_empty( &header->Iterators );
504}
505
506/** @} */
507
508#ifdef __cplusplus
509}
510#endif
511
512#endif
513/* end of include file */
Note: See TracBrowser for help on using the repository browser.