source: rtems/c/src/lib/libbsp/nios2/nios2_iss/timer/timer.c @ 8fbe2e6

4.11
Last change on this file since 8fbe2e6 was 8fbe2e6, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 4, 2014 at 1:59:49 PM

Use correct prototype of benchmark_timer_read()

This change starts with removing the effectively empty file
timerdrv.h. The prototypes for benchmark_timer_XXX() were in
btimer.h which was not universally used. Thus every use of
timerdrv.h had to be changed to btimer.h. Then the prototypes
for benchmark_timer_read() had to be adjusted to return
benchmark_timer_t rather than int or uint32_t.

I took this opportunity to also correct the file headers to
separate the copyright from the file description comments which
is needed to ensure the copyright isn't propagated into Doxygen
output.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*  timer.c
2 *
3 *  This file manages the benchmark timer used by the RTEMS Timing Test
4 *  Suite.  Each measured time period is demarcated by calls to
5 *  benchmark_timer_initialize() and benchmark_timer_read().  benchmark_timer_read() usually returns
6 *  the number of microseconds since benchmark_timer_initialize() exitted.
7 *
8 *  NOTE: It is important that the timer start/stop overhead be
9 *        determined when porting or modifying this code.
10 *
11 *  COPYRIGHT (c) 2005-2006 Kolja Waschk rtemsdev/ixo.de
12 *  Derived from no_cpu/no_bsp/timer/timer.c 1.9,
13 *  COPYRIGHT (c) 1989-1999.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.org/license/LICENSE.
19 */
20
21#define TIMER_WRAPS_AFTER_1MS 0
22
23#include <rtems.h>
24#include <rtems/btimer.h>
25#include <rtems/score/cpu.h>
26#include <bsp.h>
27
28volatile uint32_t Timer_interrupts;
29bool benchmark_timer_find_average_overhead;
30
31#define TIMER_REGS ((altera_avalon_timer_regs*)NIOS2_IO_BASE(TIMER_BASE))
32
33void timerisr( void )
34{
35  TIMER_REGS->status = 0;
36  Timer_interrupts++;
37}
38
39void benchmark_timer_initialize( void )
40{
41  /* Disable timer interrupt, stop timer */
42
43  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_STOP_MSK;
44
45  set_vector((nios2_isr_entry *)timerisr, TIMER_VECTOR, 1);
46
47  /* Enable interrupt processing */
48
49  NIOS2_IENABLE(1 << TIMER_VECTOR);
50
51#if TIMER_WRAPS_AFTER_1MS
52  /* Writing to periodl/h resets the counter and eventually
53     stops it. If the timer hasn't been configured with fixed
54     period, set it to 1 ms now */
55
56  TIMER_REGS->period_hi = (TIMER_FREQ/1000)>>16;
57  TIMER_REGS->period_lo = (TIMER_FREQ/1000)&0xFFFF;
58#else
59  /* Writing to periodl/h resets the counter and eventually
60     stops it. Set max period */
61
62  TIMER_REGS->period_hi = 0xFFFF;
63  TIMER_REGS->period_lo = 0xFFFF;
64#endif
65
66  /* For timers that can be stopped, writing to periodl/h
67     also stopped the timer and we have to manually start it. */
68
69  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_ITO_MSK |
70                        ALTERA_AVALON_TIMER_CONTROL_CONT_MSK |
71                        ALTERA_AVALON_TIMER_CONTROL_START_MSK;
72
73  /* This is the most safe place for resetting the overflow
74     counter - just _after_ we reset the timer. Depending
75     on the SOPC configuration, the counter may not be
76     stoppable and it doesn't make sense to assume that
77     there is any "safe" period before resetting. */
78
79  Timer_interrupts = 0;
80}
81
82/*
83 *  The following controls the behavior of benchmark_timer_read().
84 *
85 *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
86 *  is usually deducted from the number returned.
87 *
88 *  LEAST_VALID is the lowest number this routine should trust.  Numbers
89 *  below this are "noise" and zero is returned.
90 */
91
92#define AVG_OVERHEAD      2      /* It typically takes 2 microseconds */
93                                 /* to start/stop the timer. */
94
95#define LEAST_VALID AVG_OVERHEAD /* Don't trust a value lower than this */
96
97benchmark_timer_t benchmark_timer_read( void )
98{
99  uint32_t timer_wraps;
100  uint32_t timer_snap;
101  uint32_t timer_ticks;
102  uint32_t total;
103
104  /* Hold timer */
105  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_STOP_MSK;
106
107  /* Write to request snapshot of timer value */
108  TIMER_REGS->snap_lo = 0;
109  /* Get snapshot */
110  timer_snap = ((TIMER_REGS->snap_hi)<<16) | TIMER_REGS->snap_lo;
111  timer_wraps = Timer_interrupts;
112
113  /* Restart timer */
114  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_START_MSK;
115
116#if TIMER_WRAPS_AFTER_1MS
117  timer_ticks = (TIMER_FREQ / 1000) - 1 - timer_snap;
118  total = timer_wraps * 1000;
119#else
120  timer_ticks = 0xFFFFFFFF - timer_snap;
121  total = timer_wraps * 0x80000000 / (TIMER_FREQ / 2000000L);
122#endif
123  total += timer_ticks / (TIMER_FREQ / 1000000L);
124
125  if(total < LEAST_VALID) return 0;
126
127  if(benchmark_timer_find_average_overhead != TRUE) total-= AVG_OVERHEAD;
128
129  return total;
130}
131
132void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
133{
134  benchmark_timer_find_average_overhead = find_flag;
135}
Note: See TracBrowser for help on using the repository browser.