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

Last change on this file since 7ee59313 was 7ee59313, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 1, 2018 at 5:11:12 AM

Remove Clock_driver_support_shutdown_hardware()

The aim of this clock driver hook was to stop clock tick interrupts at
some late point in the exit() procedure.

The use of atexit() pulls in malloc() which pulls in errno. It is
incompatible with the intention of the
CONFIGURE_DISABLE_NEWLIB_REENTRANCY configuration option.

The exit() function must be called from thread context, so accompanied
clock tick interrupts should cause no harm. On the contrary, someone
may assume a normal operating system operation, e.g. working timeouts.

Remove the Clock_driver_support_shutdown_hardware() clock driver hook.

Close #3436.

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