source: rtems/c/src/lib/libbsp/shared/clockdrv_shell.h @ 48fed9a

4.115
Last change on this file since 48fed9a was 48fed9a, checked in by Sebastian Huber <sebastian.huber@…>, on 06/25/15 at 12:11:53

score: Simplify <rtems/system.h>

Drop the <rtems/score/percpu.h> include since this file exposes a lot of
implementation details.

  • Property mode set to 100644
File size: 4.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
24#ifdef Clock_driver_nanoseconds_since_last_tick
25#error "Update driver to use the timecounter instead of nanoseconds extension"
26#endif
27
28/**
29 * @defgroup bsp_clock Clock Support
30 *
31 * @ingroup bsp_shared
32 *
33 * @brief Clock support
34 *
35 */
36#if CLOCK_DRIVER_USE_FAST_IDLE && CLOCK_DRIVER_ISRS_PER_TICK
37#error "clockdrv_shell.h: Fast Idle PLUS n ISRs per tick is not supported"
38#endif
39
40/**
41 * @brief This method is rarely used so default it.
42 */
43#ifndef Clock_driver_support_find_timer
44  #define Clock_driver_support_find_timer()
45#endif
46
47/*
48 * A specialized clock driver may use for example rtems_timecounter_tick_simple()
49 * instead of the default.
50 */
51#ifndef Clock_driver_timecounter_tick
52  #ifdef CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
53    #define Clock_driver_timecounter_tick() rtems_clock_tick()
54  #else
55    #define Clock_driver_timecounter_tick() rtems_timecounter_tick()
56  #endif
57#endif
58
59/**
60 * @brief ISRs until next clock tick
61 */
62#if CLOCK_DRIVER_ISRS_PER_TICK
63  volatile uint32_t  Clock_driver_isrs;
64#endif
65
66/**
67 * @brief Clock ticks since initialization
68 */
69volatile uint32_t    Clock_driver_ticks;
70
71void Clock_exit( void );
72
73/**
74 *  @brief Clock_isr
75 *
76 *  This is the clock tick interrupt handler.
77 *
78 *  @param vector Vector number.
79 */
80#if defined(BSP_FEATURE_IRQ_EXTENSION) || \
81    (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)
82void Clock_isr(void *arg);
83void Clock_isr(void *arg)
84{
85#else
86rtems_isr Clock_isr(rtems_vector_number vector);
87rtems_isr Clock_isr(
88  rtems_vector_number vector
89)
90{
91#endif
92  /*
93   *  Accurate count of ISRs
94   */
95  Clock_driver_ticks += 1;
96
97  #if CLOCK_DRIVER_USE_FAST_IDLE
98    {
99      struct timecounter *tc = _Timecounter;
100      uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
101      uint32_t interval = (uint32_t)
102        ((tc->tc_frequency * us_per_tick) / 1000000);
103
104      Clock_driver_timecounter_tick();
105
106      while (
107        _Thread_Heir == _Thread_Executing
108          && _Thread_Executing->Start.entry_point
109            == (Thread_Entry) rtems_configuration_get_idle_task()
110      ) {
111        _Timecounter_Tick_simple(interval, (*tc->tc_get_timecount)(tc));
112      }
113
114      Clock_driver_support_at_tick();
115    }
116  #else
117    /*
118     *  Do the hardware specific per-tick action.
119     *
120     *  The counter/timer may or may not be set to automatically reload.
121     */
122    Clock_driver_support_at_tick();
123
124    #if CLOCK_DRIVER_ISRS_PER_TICK
125      /*
126       *  The driver is multiple ISRs per clock tick.
127       */
128      if ( !Clock_driver_isrs ) {
129        Clock_driver_timecounter_tick();
130
131        Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK;
132      }
133      Clock_driver_isrs--;
134    #else
135      /*
136       *  The driver is one ISR per clock tick.
137       */
138      Clock_driver_timecounter_tick();
139    #endif
140  #endif
141}
142
143/**
144 *  @brief Clock_exit
145 *
146 *  This routine allows the clock driver to exit by masking the interrupt and
147 *  disabling the clock's counter.
148 */
149void Clock_exit( void )
150{
151  Clock_driver_support_shutdown_hardware();
152
153  /* do not restore old vector */
154}
155
156/**
157 * @brief Clock_initialize
158 *
159 * This routine initializes the clock driver.
160 *
161 * @param[in] major Clock device major number.
162 * @param[in] minor Clock device minor number.
163 * @param[in] parg  Pointer to optional device driver arguments
164 *
165 * @retval rtems_device_driver status code
166 */
167rtems_device_driver Clock_initialize(
168  rtems_device_major_number major,
169  rtems_device_minor_number minor,
170  void *pargp
171)
172{
173  rtems_isr_entry  Old_ticker;
174
175  Clock_driver_ticks = 0;
176
177  /*
178   *  Find timer -- some BSPs search buses for hardware timer
179   */
180  Clock_driver_support_find_timer();
181
182  /*
183   *  Install vector
184   */
185  (void) Old_ticker;
186  Clock_driver_support_install_isr( Clock_isr, Old_ticker );
187
188  /*
189   *  Now initialize the hardware that is the source of the tick ISR.
190   */
191  Clock_driver_support_initialize_hardware();
192
193  atexit( Clock_exit );
194
195  /*
196   *  If we are counting ISRs per tick, then initialize the counter.
197   */
198  #if CLOCK_DRIVER_ISRS_PER_TICK
199    Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE;
200  #endif
201
202  return RTEMS_SUCCESSFUL;
203}
Note: See TracBrowser for help on using the repository browser.