RTEMS: bsps/shared/dev/clock/clockimpl.h Source File

| RTEMS 5.4-rc2

Loading...
Searching...
No Matches
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>
24#include <rtems/score/timecounter.h>
25#include <rtems/score/thread.h>
26#include <rtems/score/watchdogimpl.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
77static void Clock_driver_timecounter_tick( void )
78{
79#if defined(CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER)
80 rtems_clock_tick();
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 ) ) {
93 rtems_timecounter_tick();
94 } else if ( _Processor_mask_Is_set( _SMP_Get_online_processors(), cpu_index ) ) {
95 _Watchdog_Tick( cpu );
96 }
97 }
98#else
99 rtems_timecounter_tick();
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)
129void Clock_isr(void *arg);
130void Clock_isr(void *arg)
131{
132#else
133 rtems_isr Clock_isr(rtems_vector_number vector);
134 rtems_isr Clock_isr(
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);
160 _Timecounter_Tick_simple(
161 interval,
162 (*tc->tc_get_timecount)(tc),
163 &lock_context
164 );
165 }
166 }
167
168 Clock_driver_support_at_tick();
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 */
176 Clock_driver_support_at_tick();
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 */
204 Clock_driver_support_find_timer();
205
206 /*
207 * Install vector
208 */
209 Clock_driver_support_install_isr( Clock_isr );
210
211 #ifdef RTEMS_SMP
212 Clock_driver_support_set_interrupt_affinity(
213 _SMP_Get_online_processors()
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}
clockdrv.h
Clock Driver API.
Clock_driver_support_find_timer
#define Clock_driver_support_find_timer()
This method is rarely used so default it.
Definition: clockimpl.h:55
Clock_driver_support_set_interrupt_affinity
#define Clock_driver_support_set_interrupt_affinity(online_processors)
Do nothing by default.
Definition: clockimpl.h:69
Clock_driver_support_install_isr
#define Clock_driver_support_install_isr(isr)
Do nothing by default.
Definition: clockimpl.h:48
Clock_driver_support_at_tick
#define Clock_driver_support_at_tick()
Do nothing by default.
Definition: clockimpl.h:62
rtems_clock_tick
rtems_status_code rtems_clock_tick(void)
Announce a Clock Tick.
Definition: clocktick.c:25
rtems_isr
ISR_Handler rtems_isr
Return type for interrupt handler.
Definition: intr.h:52
rtems_vector_number
ISR_Vector_number rtems_vector_number
Control block type used to manage the vectors.
Definition: intr.h:47
Clock_driver_ticks
volatile uint32_t Clock_driver_ticks
ISRs until next clock tick.
Definition: clockimpl.h:114
_Clock_Initialize
void _Clock_Initialize(void)
Initialize the clock driver.
Definition: clockimpl.h:197
_Processor_mask_Is_set
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
_SMP_Get_online_processors
RTEMS_INLINE_ROUTINE const Processor_mask * _SMP_Get_online_processors(void)
Gets all online processors.
Definition: smpimpl.h:318
_Timecounter_Tick_simple
void _Timecounter_Tick_simple(uint32_t delta, uint32_t offset, ISR_lock_Context *lock_context)
Performs a simple timecounter tick.
_Timecounter_Acquire
#define _Timecounter_Acquire(lock_context)
Lock to protect the timecounter mechanic.
Definition: timecounter.h:201
_Timecounter
struct timecounter * _Timecounter
The current timecounter.
_Watchdog_Tick
void _Watchdog_Tick(struct Per_CPU_Control *cpu)
Performs a watchdog tick.
Definition: watchdogtick.c:54
rtems_timecounter_tick
RTEMS_INLINE_ROUTINE void rtems_timecounter_tick(void)
Performs a timecounter tick.
Definition: timecounter.h:83
percpu.h
thread.h
Constants and Structures Related with the Thread Control Block.
timecounter.h
Timecounter API.
smpimpl.h
SuperCore SMP Implementation.
ISR_lock_Context
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
Per_CPU_Control
Per CPU Core Structure.
Definition: percpu.h:347
timecounter
Definition: timetc.h:46
watchdogimpl.h
Inlined Routines in the Watchdog Handler.