RTEMS  5.1
clockimpl.h
Go to the documentation of this file.
1 
9 /*
10  * COPYRIGHT (c) 1989-2014.
11  * On-Line Applications Research Corporation (OAR).
12  *
13  * The license and distribution terms for this file may be
14  * found in the file LICENSE in this distribution or at
15  * http://www.rtems.org/license/LICENSE.
16  */
17 
18 #include <stdlib.h>
19 
20 #include <bsp.h>
21 #include <rtems/clockdrv.h>
22 #include <rtems/score/percpu.h>
23 #include <rtems/score/smpimpl.h>
25 #include <rtems/score/thread.h>
27 
28 #ifdef Clock_driver_nanoseconds_since_last_tick
29 #error "Update driver to use the timecounter instead of nanoseconds extension"
30 #endif
31 
40 #if CLOCK_DRIVER_USE_FAST_IDLE && CLOCK_DRIVER_ISRS_PER_TICK
41 #error "Fast Idle PLUS n ISRs per tick is not supported"
42 #endif
43 
47 #ifndef Clock_driver_support_install_isr
48  #define Clock_driver_support_install_isr(isr)
49 #endif
50 
54 #ifndef Clock_driver_support_find_timer
55  #define Clock_driver_support_find_timer()
56 #endif
57 
61 #ifndef Clock_driver_support_at_tick
62  #define Clock_driver_support_at_tick()
63 #endif
64 
68 #ifndef Clock_driver_support_set_interrupt_affinity
69  #define Clock_driver_support_set_interrupt_affinity(online_processors)
70 #endif
71 
72 /*
73  * A specialized clock driver may use for example rtems_timecounter_tick_simple()
74  * instead of the default.
75  */
76 #ifndef Clock_driver_timecounter_tick
77 static void Clock_driver_timecounter_tick( void )
78 {
79 #if defined(CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER)
81 #elif defined(RTEMS_SMP) && defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
82  uint32_t cpu_max;
83  uint32_t cpu_index;
84 
85  cpu_max = _SMP_Get_processor_maximum();
86 
87  for ( cpu_index = 0 ; cpu_index < cpu_max ; ++cpu_index ) {
88  Per_CPU_Control *cpu;
89 
90  cpu = _Per_CPU_Get_by_index( cpu_index );
91 
92  if ( _Per_CPU_Is_boot_processor( cpu ) ) {
94  } else if ( _Processor_mask_Is_set( _SMP_Get_online_processors(), cpu_index ) ) {
95  _Watchdog_Tick( cpu );
96  }
97  }
98 #else
100 #endif
101 }
102 #endif
103 
107 #if CLOCK_DRIVER_ISRS_PER_TICK
108  volatile uint32_t Clock_driver_isrs;
109 #endif
110 
114 volatile uint32_t Clock_driver_ticks;
115 
116 #ifdef Clock_driver_support_shutdown_hardware
117 #error "Clock_driver_support_shutdown_hardware() is no longer supported"
118 #endif
119 
127 #if defined(BSP_FEATURE_IRQ_EXTENSION) || \
128  (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)
129 void Clock_isr(void *arg);
130 void Clock_isr(void *arg)
131 {
132 #else
135  rtems_vector_number vector
136 )
137 {
138 #endif
139  /*
140  * Accurate count of ISRs
141  */
142  Clock_driver_ticks += 1;
143 
144  #if CLOCK_DRIVER_USE_FAST_IDLE
145  {
146  struct timecounter *tc = _Timecounter;
147  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
148  uint32_t interval = (uint32_t)
149  ((tc->tc_frequency * us_per_tick) / 1000000);
150 
151  Clock_driver_timecounter_tick();
152 
153  if (_SMP_Get_processor_maximum() == 1) {
154  while (
155  _Thread_Heir == _Thread_Executing && _Thread_Executing->is_idle
156  ) {
157  ISR_lock_Context lock_context;
158 
159  _Timecounter_Acquire(&lock_context);
161  interval,
162  (*tc->tc_get_timecount)(tc),
163  &lock_context
164  );
165  }
166  }
167 
169  }
170  #else
171  /*
172  * Do the hardware specific per-tick action.
173  *
174  * The counter/timer may or may not be set to automatically reload.
175  */
177 
178  #if CLOCK_DRIVER_ISRS_PER_TICK
179  /*
180  * The driver is multiple ISRs per clock tick.
181  */
182  if ( !Clock_driver_isrs ) {
183  Clock_driver_timecounter_tick();
184 
185  Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE;
186  }
187  Clock_driver_isrs--;
188  #else
189  /*
190  * The driver is one ISR per clock tick.
191  */
192  Clock_driver_timecounter_tick();
193  #endif
194  #endif
195 }
196 
197 void _Clock_Initialize( void )
198 {
199  Clock_driver_ticks = 0;
200 
201  /*
202  * Find timer -- some BSPs search buses for hardware timer
203  */
205 
206  /*
207  * Install vector
208  */
210 
211  #ifdef RTEMS_SMP
214  );
215  #endif
216 
217  /*
218  * Now initialize the hardware that is the source of the tick ISR.
219  */
220  Clock_driver_support_initialize_hardware();
221 
222  /*
223  * If we are counting ISRs per tick, then initialize the counter.
224  */
225  #if CLOCK_DRIVER_ISRS_PER_TICK
226  Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE;
227  #endif
228 }
#define Clock_driver_support_install_isr(isr)
Do nothing by default.
Definition: clockimpl.h:48
volatile uint32_t Clock_driver_ticks
ISRs until next clock tick.
Definition: clockimpl.h:114
RTEMS_INLINE_ROUTINE const Processor_mask * _SMP_Get_online_processors(void)
Gets all online processors.
Definition: smpimpl.h:318
#define Clock_driver_support_find_timer()
This method is rarely used so default it.
Definition: clockimpl.h:55
void _Timecounter_Tick_simple(uint32_t delta, uint32_t offset, ISR_lock_Context *lock_context)
Performs a simple timecounter tick.
struct timecounter * _Timecounter
The current timecounter.
Inlined Routines in the Watchdog Handler.
ISR_Vector_number rtems_vector_number
Control block type used to manage the vectors.
Definition: intr.h:47
#define _Timecounter_Acquire(lock_context)
Lock to protect the timecounter mechanic.
Definition: timecounter.h:201
RTEMS_INLINE_ROUTINE void rtems_timecounter_tick(void)
Performs a timecounter tick.
Definition: timecounter.h:83
rtems_status_code rtems_clock_tick(void)
Announce a Clock Tick.
Definition: clocktick.c:25
ISR_Handler rtems_isr
Return type for interrupt handler.
Definition: intr.h:52
RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_set(const Processor_mask *mask, uint32_t index)
Checks if the specified index bit of the mask is set.
Definition: processormask.h:139
Definition: timetc.h:46
Per CPU Core Structure.
Definition: percpu.h:347
#define Clock_driver_support_set_interrupt_affinity(online_processors)
Do nothing by default.
Definition: clockimpl.h:69
void _Clock_Initialize(void)
Initialize the clock driver.
Definition: clockimpl.h:197
Clock Driver API.
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
Constants and Structures Related with the Thread Control Block.
rtems_isr Clock_isr(rtems_vector_number vector)
Clock_isr.
Definition: clockimpl.h:134
Timecounter API.
#define Clock_driver_support_at_tick()
Do nothing by default.
Definition: clockimpl.h:62
SuperCore SMP Implementation.
void _Watchdog_Tick(struct Per_CPU_Control *cpu)
Performs a watchdog tick.
Definition: watchdogtick.c:54