source: rtems/cpukit/rtems/src/timercreate.c @ 6b5f22dc

Last change on this file since 6b5f22dc was 6b5f22dc, checked in by Sebastian Huber <sebastian.huber@…>, on 11/26/20 at 10:45:47

rtems: Canonicalize Doxygen @file comments

Use common phrases for the file brief descriptions.

Update #3706.

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSImplClassicTimer
5 *
6 * @brief This source file contains the definition of ::_Timer_server and the
7 *   implementation of _Timer_Routine_adaptor(), _Timer_Fire(),
8 *   _Timer_Fire_after(), _Timer_Fire_when(), _Timer_Cancel(), and the Timer
9 *   Manager system initialization.
10 */
11
12/*
13 *  COPYRIGHT (c) 1989-2002.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.org/license/LICENSE.
19 */
20
21#ifdef HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#include <rtems/rtems/timerimpl.h>
26#include <rtems/rtems/clockimpl.h>
27#include <rtems/rtems/status.h>
28#include <rtems/rtems/support.h>
29#include <rtems/score/assert.h>
30#include <rtems/score/chainimpl.h>
31#include <rtems/score/thread.h>
32#include <rtems/score/todimpl.h>
33#include <rtems/score/watchdogimpl.h>
34#include <rtems/sysinit.h>
35
36RTEMS_STATIC_ASSERT(
37  PER_CPU_WATCHDOG_REALTIME == TIMER_CLASS_BIT_TIME_OF_DAY,
38  TIMER_CLASS_BIT_TIME_OF_DAY
39);
40
41Timer_server_Control *volatile _Timer_server;
42
43void _Timer_Routine_adaptor( Watchdog_Control *the_watchdog )
44{
45  Timer_Control   *the_timer;
46  Per_CPU_Control *cpu;
47
48  the_timer = RTEMS_CONTAINER_OF( the_watchdog, Timer_Control, Ticker );
49  cpu = _Watchdog_Get_CPU( &the_timer->Ticker );
50  the_timer->stop_time = _Timer_Get_CPU_ticks( cpu );
51
52  ( *the_timer->routine )( the_timer->Object.id, the_timer->user_data );
53}
54
55rtems_status_code _Timer_Fire(
56  rtems_id                           id,
57  rtems_interval                     interval,
58  rtems_timer_service_routine_entry  routine,
59  void                              *user_data,
60  Timer_Classes                      the_class,
61  Watchdog_Service_routine_entry     adaptor
62)
63{
64  Timer_Control    *the_timer;
65  ISR_lock_Context  lock_context;
66
67  the_timer = _Timer_Get( id, &lock_context );
68  if ( the_timer != NULL ) {
69    Per_CPU_Control *cpu;
70
71    cpu = _Timer_Acquire_critical( the_timer, &lock_context );
72    _Timer_Cancel( cpu, the_timer );
73    _Watchdog_Initialize( &the_timer->Ticker, adaptor );
74    the_timer->the_class = the_class;
75    the_timer->routine = routine;
76    the_timer->user_data = user_data;
77    the_timer->initial = interval;
78    the_timer->start_time = _Timer_Get_CPU_ticks( cpu );
79
80    if ( _Timer_Is_interval_class( the_class ) ) {
81      _Watchdog_Insert(
82        &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
83        &the_timer->Ticker,
84        cpu->Watchdog.ticks + interval
85      );
86    } else {
87      _Watchdog_Insert(
88        &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ],
89        &the_timer->Ticker,
90        _Watchdog_Ticks_from_seconds( interval )
91      );
92    }
93
94    _Timer_Release( cpu, &lock_context );
95    return RTEMS_SUCCESSFUL;
96  }
97
98  return RTEMS_INVALID_ID;
99}
100
101rtems_status_code _Timer_Fire_after(
102  rtems_id                           id,
103  rtems_interval                     ticks,
104  rtems_timer_service_routine_entry  routine,
105  void                              *user_data,
106  Timer_Classes                      the_class,
107  Watchdog_Service_routine_entry     adaptor
108)
109{
110  if ( ticks == 0 )
111    return RTEMS_INVALID_NUMBER;
112
113  if ( !routine )
114    return RTEMS_INVALID_ADDRESS;
115
116  return _Timer_Fire(
117    id,
118    ticks,
119    routine,
120    user_data,
121    the_class,
122    adaptor
123  );
124}
125
126rtems_status_code _Timer_Fire_when(
127  rtems_id                           id,
128  const rtems_time_of_day           *wall_time,
129  rtems_timer_service_routine_entry  routine,
130  void                              *user_data,
131  Timer_Classes                      the_class,
132  Watchdog_Service_routine_entry     adaptor
133)
134{
135  rtems_interval seconds;
136
137  if ( !_TOD_Is_set() )
138    return RTEMS_NOT_DEFINED;
139
140  if ( !routine )
141    return RTEMS_INVALID_ADDRESS;
142
143  if ( !_TOD_Validate( wall_time ) )
144    return RTEMS_INVALID_CLOCK;
145
146  seconds = _TOD_To_seconds( wall_time );
147  if ( seconds <= _TOD_Seconds_since_epoch() )
148    return RTEMS_INVALID_CLOCK;
149
150  return _Timer_Fire(
151    id,
152    seconds,
153    routine,
154    user_data,
155    the_class,
156    adaptor
157  );
158}
159
160void _Timer_Cancel( Per_CPU_Control *cpu, Timer_Control *the_timer )
161{
162  Timer_Classes the_class;
163
164  the_class = the_timer->the_class;
165
166  if ( _Watchdog_Is_scheduled( &the_timer->Ticker ) ) {
167    the_timer->stop_time = _Timer_Get_CPU_ticks( cpu );
168    _Watchdog_Remove(
169      &cpu->Watchdog.Header[ _Timer_Watchdog_header_index( the_class ) ],
170      &the_timer->Ticker
171    );
172  } else if ( _Timer_Is_on_task_class( the_class ) ) {
173    Timer_server_Control *timer_server;
174    ISR_lock_Context      lock_context;
175
176    timer_server = _Timer_server;
177    _Assert( timer_server != NULL );
178    _Timer_server_Acquire_critical( timer_server, &lock_context );
179
180    if ( _Watchdog_Get_state( &the_timer->Ticker ) == WATCHDOG_PENDING ) {
181      _Watchdog_Set_state( &the_timer->Ticker, WATCHDOG_INACTIVE );
182      _Chain_Extract_unprotected( &the_timer->Ticker.Node.Chain );
183    }
184
185    _Timer_server_Release_critical( timer_server, &lock_context );
186  }
187}
188
189rtems_status_code rtems_timer_create(
190  rtems_name  name,
191  rtems_id   *id
192)
193{
194  Timer_Control *the_timer;
195
196  if ( !rtems_is_name_valid( name ) )
197    return RTEMS_INVALID_NAME;
198
199  if ( !id )
200    return RTEMS_INVALID_ADDRESS;
201
202  the_timer = _Timer_Allocate();
203
204  if ( !the_timer ) {
205    _Objects_Allocator_unlock();
206    return RTEMS_TOO_MANY;
207  }
208
209  the_timer->the_class = TIMER_DORMANT;
210  _Watchdog_Preinitialize( &the_timer->Ticker, _Per_CPU_Get_snapshot() );
211
212  _Objects_Open(
213    &_Timer_Information,
214    &the_timer->Object,
215    (Objects_Name) name
216  );
217
218  *id = the_timer->Object.id;
219  _Objects_Allocator_unlock();
220  return RTEMS_SUCCESSFUL;
221}
222
223static void _Timer_Manager_initialization( void )
224{
225  _Objects_Initialize_information( &_Timer_Information );
226}
227
228RTEMS_SYSINIT_ITEM(
229  _Timer_Manager_initialization,
230  RTEMS_SYSINIT_CLASSIC_TIMER,
231  RTEMS_SYSINIT_ORDER_MIDDLE
232);
Note: See TracBrowser for help on using the repository browser.