source: rtems/bsps/shared/dev/clock/clockimpl.h @ 0288536

Last change on this file since 0288536 was 0288536, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 9, 2018 at 8:40:45 AM

bsps: Include missing header files

Update #3598.

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup bsp_clock
5 *
6 * @brief Clock Tick Device Driver Shell
7 */
8
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
32/**
33 * @defgroup bsp_clock Clock Support
34 *
35 * @ingroup bsp_shared
36 *
37 * @brief Clock support
38 *
39 */
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
44/**
45 * @brief Do nothing by default.
46 */
47#ifndef Clock_driver_support_install_isr
48  #define Clock_driver_support_install_isr(isr)
49#endif
50
51/**
52 * @brief This method is rarely used so default it.
53 */
54#ifndef Clock_driver_support_find_timer
55  #define Clock_driver_support_find_timer()
56#endif
57
58/**
59 * @brief Do nothing by default.
60 */
61#ifndef Clock_driver_support_at_tick
62  #define Clock_driver_support_at_tick()
63#endif
64
65/**
66 * @brief Do nothing by default.
67 */
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_count = _SMP_Get_processor_count();
83  uint32_t cpu_index;
84
85  for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
86    Per_CPU_Control *cpu;
87
88    cpu = _Per_CPU_Get_by_index( cpu_index );
89
90    if ( _Per_CPU_Is_boot_processor( cpu ) ) {
91      rtems_timecounter_tick();
92    } else if ( _Processor_mask_Is_set( _SMP_Get_online_processors(), cpu_index ) ) {
93      _Watchdog_Tick( cpu );
94    }
95  }
96#else
97  rtems_timecounter_tick();
98#endif
99}
100#endif
101
102/**
103 * @brief ISRs until next clock tick
104 */
105#if CLOCK_DRIVER_ISRS_PER_TICK
106  volatile uint32_t  Clock_driver_isrs;
107#endif
108
109/**
110 * @brief Clock ticks since initialization
111 */
112volatile uint32_t    Clock_driver_ticks;
113
114#ifdef Clock_driver_support_shutdown_hardware
115#error "Clock_driver_support_shutdown_hardware() is no longer supported"
116#endif
117
118/**
119 *  @brief Clock_isr
120 *
121 *  This is the clock tick interrupt handler.
122 *
123 *  @param vector Vector number.
124 */
125#if defined(BSP_FEATURE_IRQ_EXTENSION) || \
126    (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)
127void Clock_isr(void *arg);
128void Clock_isr(void *arg)
129{
130#else
131rtems_isr Clock_isr(rtems_vector_number vector);
132rtems_isr Clock_isr(
133  rtems_vector_number vector
134)
135{
136#endif
137  /*
138   *  Accurate count of ISRs
139   */
140  Clock_driver_ticks += 1;
141
142  #if CLOCK_DRIVER_USE_FAST_IDLE
143    {
144      struct timecounter *tc = _Timecounter;
145      uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
146      uint32_t interval = (uint32_t)
147        ((tc->tc_frequency * us_per_tick) / 1000000);
148
149      Clock_driver_timecounter_tick();
150
151      if (!rtems_configuration_is_smp_enabled()) {
152        while (
153          _Thread_Heir == _Thread_Executing && _Thread_Executing->is_idle
154        ) {
155          ISR_lock_Context lock_context;
156
157          _Timecounter_Acquire(&lock_context);
158          _Timecounter_Tick_simple(
159            interval,
160            (*tc->tc_get_timecount)(tc),
161            &lock_context
162          );
163        }
164      }
165
166      Clock_driver_support_at_tick();
167    }
168  #else
169    /*
170     *  Do the hardware specific per-tick action.
171     *
172     *  The counter/timer may or may not be set to automatically reload.
173     */
174    Clock_driver_support_at_tick();
175
176    #if CLOCK_DRIVER_ISRS_PER_TICK
177      /*
178       *  The driver is multiple ISRs per clock tick.
179       */
180      if ( !Clock_driver_isrs ) {
181        Clock_driver_timecounter_tick();
182
183        Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK;
184      }
185      Clock_driver_isrs--;
186    #else
187      /*
188       *  The driver is one ISR per clock tick.
189       */
190      Clock_driver_timecounter_tick();
191    #endif
192  #endif
193}
194
195/**
196 * @brief Clock_initialize
197 *
198 * This routine initializes the clock driver.
199 *
200 * @param[in] major Clock device major number.
201 * @param[in] minor Clock device minor number.
202 * @param[in] parg  Pointer to optional device driver arguments
203 *
204 * @retval rtems_device_driver status code
205 */
206rtems_device_driver Clock_initialize(
207  rtems_device_major_number major,
208  rtems_device_minor_number minor,
209  void *pargp
210)
211{
212  Clock_driver_ticks = 0;
213
214  /*
215   *  Find timer -- some BSPs search buses for hardware timer
216   */
217  Clock_driver_support_find_timer();
218
219  /*
220   *  Install vector
221   */
222  Clock_driver_support_install_isr( Clock_isr );
223
224  #ifdef RTEMS_SMP
225    Clock_driver_support_set_interrupt_affinity(
226      _SMP_Get_online_processors()
227    );
228  #endif
229
230  /*
231   *  Now initialize the hardware that is the source of the tick ISR.
232   */
233  Clock_driver_support_initialize_hardware();
234
235  /*
236   *  If we are counting ISRs per tick, then initialize the counter.
237   */
238  #if CLOCK_DRIVER_ISRS_PER_TICK
239    Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE;
240  #endif
241
242  return RTEMS_SUCCESSFUL;
243}
Note: See TracBrowser for help on using the repository browser.