source: rtems/c/src/lib/libbsp/lm32/shared/timer/timer.c @ 44d7753

4.11
Last change on this file since 44d7753 was 44d7753, checked in by Ralf Corsepius <ralf.corsepius@…>, on Feb 9, 2011 at 8:19:30 AM

2011-02-09 Ralf Corsépius <ralf.corsepius@…>

  • shared/milkymist_timer/timer.c, shared/timer/timer.c: Include <rtems/btimer.h>. Fix benchmark_timer_read() definition.
  • Property mode set to 100644
File size: 3.2 KB
Line 
1/*  timer.c
2 *
3 *  This file manages the benchmark timer used by the RTEMS Timing
4 *  Test Suite.  Each measured time period is demarcated by calls to
5 *  benchmark_timer_initialize() and benchmark_timer_read().
6 *  benchmark_timer_read() usually returns the number of microseconds
7 *  since benchmark_timer_initialize() exitted.
8 *
9 *  NOTE: It is important that the timer start/stop overhead be
10 *        determined when porting or modifying this code.
11 *
12 *  COPYRIGHT (c) 1989-1999.
13 *  On-Line Applications Research Corporation (OAR).
14 *
15 *  The license and distribution terms for this file may be
16 *  found in the file LICENSE in this distribution or at
17 *  http://www.rtems.com/license/LICENSE.
18 *
19 *  $Id$
20 *
21 *  Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
22 *  Micro-Research Finland Oy
23 */
24
25#include <rtems.h>
26#include <bsp.h>
27#include <rtems/btimer.h>
28#include "../include/system_conf.h"
29#include "../../shared/clock/clock.h"
30
31static inline int timerread(unsigned int reg)
32{
33#if ON_SIMULATOR && defined(TIMER0_BASE_ADDRESS)
34  return *((int*)(TIMER0_BASE_ADDRESS + reg));
35#elif defined(TIMER1_BASE_ADDRESS)
36  return *((int*)(TIMER1_BASE_ADDRESS + reg));
37#else
38#warning "Benchmarking timer not available!"
39  return 0;
40#endif
41}
42
43static inline void timerwrite(unsigned int reg, int value)
44{
45#if ON_SIMULATOR && defined(TIMER0_BASE_ADDRESS)
46  *((int*)(TIMER0_BASE_ADDRESS + reg)) = value;
47#elif defined(TIMER1_BASE_ADDRESS)
48  *((int*)(TIMER1_BASE_ADDRESS + reg)) = value;
49#endif
50}
51
52bool benchmark_timer_find_average_overhead;
53
54void benchmark_timer_initialize( void )
55{
56  /* Set timer period */
57  timerwrite(LM32_CLOCK_PERIOD, 0xffffffff);
58  /* Stop timer */
59  timerwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_STOP);
60  /* Clear status register */
61  timerwrite(LM32_CLOCK_SR, 0);
62  /* Start timer */
63  timerwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_START);
64}
65
66/*
67 *  The following controls the behavior of benchmark_timer_read().
68 *
69 *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
70 *  is usually deducted from the number returned.
71 *
72 *  LEAST_VALID is the lowest number this routine should trust.  Numbers
73 *  below this are "noise" and zero is returned.
74 */
75
76#define AVG_OVERHEAD      4  /* It typically takes X.X microseconds */
77                             /* (Y countdowns) to start/stop the timer. */
78                             /* This value is in microseconds. */
79#define LEAST_VALID       4  /* Don't trust a clicks value lower than this */
80
81uint32_t benchmark_timer_read( void )
82{
83  uint32_t ticks;
84  uint32_t total;
85  uint32_t status;
86
87  ticks = 0xffffffff - timerread(LM32_CLOCK_SNAPSHOT);
88  status = timerread(LM32_CLOCK_SR);
89  if (status & LM32_CLOCK_SR_TO)
90    printk("Timer overflow!\n");
91
92  total = ticks / (CPU_FREQUENCY / 1000000);
93
94  if ( benchmark_timer_find_average_overhead == true )
95    return total;          /* in XXX microsecond units */
96  else
97    {
98      if ( total < LEAST_VALID )
99        return 0;            /* below timer resolution */
100      /*
101       *  Somehow convert total into microseconds
102       */
103      return (total - AVG_OVERHEAD);
104    }
105}
106
107void benchmark_timer_disable_subtracting_average_overhead(
108  bool find_flag
109)
110{
111  benchmark_timer_find_average_overhead = find_flag;
112}
Note: See TracBrowser for help on using the repository browser.