source: rtems/cpukit/include/rtems/timecounter.h @ 2afb22b

5
Last change on this file since 2afb22b was 2afb22b, checked in by Chris Johns <chrisj@…>, on 12/23/17 at 07:18:56

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

  • Property mode set to 100644
File size: 8.4 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup SAPITimecounter
5 *
6 * @brief Timecounter API
7 */
8
9/*
10 * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#ifndef _RTEMS_TIMECOUNTER_H
24#define _RTEMS_TIMECOUNTER_H
25
26#include <rtems/score/timecounter.h>
27#include <rtems/score/basedefs.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif /* __cplusplus */
32
33/**
34 * @defgroup SAPITimecounter Timecounter Support
35 *
36 * @{
37 */
38
39/**
40 * @brief Timecounter quality for the clock drivers.
41 *
42 * Timecounter with higher quality value are used in favour of those with lower
43 * quality value.
44 */
45#define RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER 100
46
47/**
48 * @copydoc _Timecounter_Install()
49 *
50 * Below is an exemplary code snippet that shows the adjustable parameters and
51 * the following call of the install routine.
52 *
53 * @code
54 * struct timecounter tc;
55 *
56 * uint32_t get_timecount( struct timecounter *tc )
57 * {
58 *   return some_free_running_counter;
59 * }
60 *
61 * void install( void )
62 * {
63 *   tc.tc_get_timecount = get_timecount;
64 *   tc.tc_counter_mask = 0xffffffff;
65 *   tc.tc_frequency = 123456;
66 *   tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
67 *   rtems_timecounter_install( &tc );
68 * }
69 * @endcode
70 */
71RTEMS_INLINE_ROUTINE void rtems_timecounter_install(
72  struct timecounter *tc
73)
74{
75  _Timecounter_Install( tc );
76}
77
78/**
79 * @copydoc _Timecounter_Tick()
80 */
81RTEMS_INLINE_ROUTINE void rtems_timecounter_tick(void)
82{
83  _Timecounter_Tick();
84}
85
86/**
87 * @brief Simple timecounter to support legacy clock drivers.
88 */
89typedef struct {
90  struct timecounter tc;
91  uint64_t scaler;
92  uint32_t real_interval;
93  uint32_t binary_interval;
94} rtems_timecounter_simple;
95
96/**
97 * @brief At tick handling done under protection of the timecounter lock.
98 */
99typedef void rtems_timecounter_simple_at_tick(
100  rtems_timecounter_simple *tc
101);
102
103/**
104 * @brief Returns the current value of a simple timecounter.
105 */
106typedef uint32_t rtems_timecounter_simple_get(
107  rtems_timecounter_simple *tc
108);
109
110/**
111 * @brief Returns true if the interrupt of a simple timecounter is pending, and
112 * false otherwise.
113 */
114typedef bool rtems_timecounter_simple_is_pending(
115  rtems_timecounter_simple *tc
116);
117
118/**
119 * @brief Initializes and installs a simple timecounter.
120 *
121 * A simple timecounter can be used if the hardware provides no free running
122 * counter.  A periodic hardware counter must be provided.  The counter period
123 * must be synchronous to the clock tick.  The counter ticks per clock tick is
124 * scaled up to the next power of two.
125 *
126 * @param[in] tc Zero initialized simple timecounter.
127 * @param[in] counter_frequency_in_hz The hardware counter frequency in Hz.
128 * @param[in] counter_ticks_per_clock_tick The hardware counter ticks per clock
129 *   tick.
130 * @param[in] get_timecount The method to get the current time count.
131 *
132 * @code
133 * #include <rtems/timecounter.h>
134 *
135 * static rtems_timecounter_simple some_tc;
136 *
137 * static uint32_t some_tc_get( rtems_timecounter_simple *tc )
138 * {
139 *   return some.value;
140 * }
141 *
142 * static bool some_tc_is_pending( rtems_timecounter_simple *tc )
143 * {
144 *   return some.is_pending;
145 * }
146 *
147 * static uint32_t some_tc_get_timecount( struct timecounter *tc )
148 * {
149 *   return rtems_timecounter_simple_downcounter_get(
150 *     tc,
151 *     some_tc_get,
152 *     some_tc_is_pending
153 *   );
154 * }
155 *
156 * static void some_tc_tick( void )
157 * {
158 *   rtems_timecounter_simple_downcounter_tick( &some_tc, some_tc_get );
159 * }
160 *
161 * void some_tc_init( void )
162 * {
163 *   uint64_t us_per_tick;
164 *   uint32_t counter_frequency_in_hz;
165 *   uint32_t counter_ticks_per_clock_tick;
166 *
167 *   us_per_tick = rtems_configuration_get_microseconds_per_tick();
168 *   counter_frequency_in_hz = some_tc_get_frequency();
169 *   counter_ticks_per_clock_tick =
170 *     (uint32_t) ( counter_frequency_in_hz * us_per_tick ) / 1000000;
171 *
172 *   some_tc_init_hardware( counter_ticks_per_clock_tick );
173 *   some_tc_init_clock_tick_interrupt( some_tc_tick );
174 *
175 *   rtems_timecounter_simple_install(
176 *     &some_tc,
177 *     counter_frequency_in_hz,
178 *     counter_ticks_per_clock_tick,
179 *     some_tc_get_timecount
180 *   );
181 * }
182 * @endcode
183 *
184 * @see rtems_timecounter_simple_downcounter_get(),
185 * rtems_timecounter_simple_downcounter_tick(),
186 * rtems_timecounter_simple_upcounter_get() and
187 * rtems_timecounter_simple_upcounter_tick().
188 */
189void rtems_timecounter_simple_install(
190  rtems_timecounter_simple *tc,
191  uint32_t                  counter_frequency_in_hz,
192  uint32_t                  counter_ticks_per_clock_tick,
193  timecounter_get_t        *get_timecount
194);
195
196/**
197 * @brief Maps a simple timecounter value into its binary frequency domain.
198 *
199 * @param[in] tc The simple timecounter.
200 * @param[in] value The value of the simple timecounter.
201 *
202 * @return The scaled value.
203 */
204RTEMS_INLINE_ROUTINE uint32_t rtems_timecounter_simple_scale(
205  const rtems_timecounter_simple *tc,
206  uint32_t value
207)
208{
209  return (uint32_t) ( ( value * tc->scaler ) >> 32 );
210}
211
212/**
213 * @brief Performs a simple timecounter tick for downcounters.
214 *
215 * @param[in] tc The simple timecounter.
216 * @param[in] get The method to get the value of the simple timecounter.
217 * @param[in] at_tick The method to perform work under timecounter lock
218 * protection at this tick, e.g. clear a pending flag.
219 */
220RTEMS_INLINE_ROUTINE void rtems_timecounter_simple_downcounter_tick(
221  rtems_timecounter_simple         *tc,
222  rtems_timecounter_simple_get      get,
223  rtems_timecounter_simple_at_tick  at_tick
224)
225{
226  ISR_lock_Context lock_context;
227  uint32_t current;
228
229  _Timecounter_Acquire( &lock_context );
230
231  ( *at_tick )( tc );
232
233  current = rtems_timecounter_simple_scale(
234    tc,
235    tc->real_interval - ( *get )( tc )
236  );
237
238  _Timecounter_Tick_simple( tc->binary_interval, current, &lock_context );
239}
240
241/**
242 * @brief Performs a simple timecounter tick for upcounters.
243 *
244 * @param[in] tc The simple timecounter.
245 * @param[in] get The method to get the value of the simple timecounter.
246 * @param[in] at_tick The method to perform work under timecounter lock
247 * protection at this tick, e.g. clear a pending flag.
248 */
249RTEMS_INLINE_ROUTINE void rtems_timecounter_simple_upcounter_tick(
250  rtems_timecounter_simple         *tc,
251  rtems_timecounter_simple_get      get,
252  rtems_timecounter_simple_at_tick  at_tick
253)
254{
255  ISR_lock_Context lock_context;
256  uint32_t current;
257
258  _Timecounter_Acquire( &lock_context );
259
260  ( *at_tick )( tc );
261
262  current = rtems_timecounter_simple_scale( tc, ( *get )( tc ) );
263
264  _Timecounter_Tick_simple( tc->binary_interval, current, &lock_context );
265}
266
267/**
268 * @brief Gets the simple timecounter value mapped to its binary frequency
269 * domain for downcounters.
270 *
271 * @param[in] tc The simple timecounter.
272 * @param[in] get The method to get the value of the simple timecounter.
273 * @param[in] is_pending The method which indicates if the interrupt of the
274 * simple timecounter is pending.
275 */
276RTEMS_INLINE_ROUTINE uint32_t rtems_timecounter_simple_downcounter_get(
277  struct timecounter                  *tc_base,
278  rtems_timecounter_simple_get         get,
279  rtems_timecounter_simple_is_pending  is_pending
280)
281{
282  rtems_timecounter_simple *tc;
283  uint32_t counter;
284  uint32_t interval;
285
286  tc = (rtems_timecounter_simple *) tc_base;
287  counter = ( *get )( tc );
288  interval = tc->real_interval;
289
290  if ( ( *is_pending )( tc ) ) {
291    counter = ( *get )( tc );
292    interval *= 2;
293  }
294
295  return rtems_timecounter_simple_scale( tc, interval - counter );
296}
297
298/**
299 * @brief Gets the simple timecounter value mapped to its binary frequency
300 * domain for upcounters.
301 *
302 * @param[in] tc The simple timecounter.
303 * @param[in] get The method to get the value of the simple timecounter.
304 * @param[in] is_pending The method which indicates if the interrupt of the
305 * simple timecounter is pending.
306 */
307RTEMS_INLINE_ROUTINE uint32_t rtems_timecounter_simple_upcounter_get(
308  struct timecounter                  *tc_base,
309  rtems_timecounter_simple_get         get,
310  rtems_timecounter_simple_is_pending  is_pending
311)
312{
313  rtems_timecounter_simple *tc;
314  uint32_t counter;
315  uint32_t interval;
316
317  tc = (rtems_timecounter_simple *) tc_base;
318  counter = ( *get )( tc );
319  interval = 0;
320
321  if ( ( *is_pending )( tc ) ) {
322    counter = ( *get )( tc );
323    interval = tc->real_interval;
324  }
325
326  return rtems_timecounter_simple_scale( tc, interval + counter );
327}
328
329/** @} */
330
331#ifdef __cplusplus
332}
333#endif /* __cplusplus */
334
335#endif /* _RTEMS_TIMECOUNTER_H */
Note: See TracBrowser for help on using the repository browser.