Changeset 0a1f5df9 in rtems for bsps/sparc/erc32


Ignore:
Timestamp:
May 3, 2018, 11:03:27 AM (22 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
7ee6437
Parents:
ef23838
git-author:
Sebastian Huber <sebastian.huber@…> (05/03/18 11:03:27)
git-committer:
Sebastian Huber <sebastian.huber@…> (12/07/18 13:22:01)
Message:

Simplify _CPU_Counter_difference()

In order to simplify the use of CPU counter values it is beneficial to
have monotonic increasing values within the range of the CPU counter
ticks data type, e.g. 32-bit unsigned integer. This eases the use of
CPU counter timestamps in external tools which do not know the details
of the CPU counter hardware. The CPU counter is the fastest way to get
a time on an RTEMS system.

Such a CPU counter may be also used as the timecounter. Use it on SPARC
for this purpose to simplify the clock drivers.

Update #3456.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • bsps/sparc/erc32/clock/ckinit.c

    ref23838 r0a1f5df9  
    2525#include <bsp.h>
    2626#include <bspopts.h>
    27 #include <rtems/counter.h>
     27#include <rtems/sysinit.h>
    2828#include <rtems/timecounter.h>
    2929#include <rtems/score/sparcimpl.h>
    3030
     31extern int CLOCK_SPEED;
     32
    3133#define ERC32_REAL_TIME_CLOCK_FREQUENCY 1000000
     34
     35static struct timecounter erc32_tc;
     36
     37static void erc32_clock_init( void )
     38{
     39  struct timecounter *tc;
     40
     41  tc = &erc32_tc;
     42  tc->tc_get_timecount = _SPARC_Get_timecount_clock;
     43  tc->tc_counter_mask = 0xffffffff;
     44  tc->tc_frequency = ERC32_REAL_TIME_CLOCK_FREQUENCY;
     45  tc->tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
     46  rtems_timecounter_install(tc);
     47}
     48
     49uint32_t _CPU_Counter_frequency(void)
     50{
     51  return ERC32_REAL_TIME_CLOCK_FREQUENCY;
     52}
     53
     54static void erc32_clock_at_tick( void )
     55{
     56  SPARC_Counter *counter;
     57  rtems_interrupt_level level;
     58
     59  counter = &_SPARC_Counter_mutable;
     60  rtems_interrupt_local_disable(level);
     61
     62  ERC32_Clear_interrupt( ERC32_INTERRUPT_REAL_TIME_CLOCK );
     63  counter->accumulated += counter->interval;
     64
     65  rtems_interrupt_local_enable(level);
     66}
     67
     68static void erc32_clock_initialize_early( void )
     69{
     70  SPARC_Counter *counter;
     71
     72  /* approximately 1 us per countdown */
     73  ERC32_MEC.Real_Time_Clock_Scalar = CLOCK_SPEED - 1;
     74  ERC32_MEC.Real_Time_Clock_Counter =
     75    rtems_configuration_get_microseconds_per_tick();
     76  ERC32_MEC_Set_Real_Time_Clock_Timer_Control(
     77      ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING |
     78      ERC32_MEC_TIMER_COUNTER_LOAD_SCALER |
     79      ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER
     80  );
     81  ERC32_MEC_Set_Real_Time_Clock_Timer_Control(
     82    ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING |
     83    ERC32_MEC_TIMER_COUNTER_RELOAD_AT_ZERO
     84  );
     85
     86  counter = &_SPARC_Counter_mutable;
     87  counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled;
     88  counter->read = _SPARC_Counter_read_clock;
     89  counter->counter_register = &ERC32_MEC.Real_Time_Clock_Counter,
     90  counter->pending_register = &ERC32_MEC.Interrupt_Pending;
     91  counter->pending_mask = UINT32_C(1) << ERC32_INTERRUPT_REAL_TIME_CLOCK;
     92  counter->accumulated = rtems_configuration_get_microseconds_per_tick();
     93  counter->interval = rtems_configuration_get_microseconds_per_tick();
     94}
     95
     96RTEMS_SYSINIT_ITEM(
     97  erc32_clock_initialize_early,
     98  RTEMS_SYSINIT_CPU_COUNTER,
     99  RTEMS_SYSINIT_ORDER_FIRST
     100);
    32101
    33102/*
     
    44113  } while (0)
    45114
    46 extern int CLOCK_SPEED;
     115#define Clock_driver_support_at_tick() erc32_clock_at_tick()
    47116
    48 static rtems_timecounter_simple erc32_tc;
    49 
    50 static uint32_t erc32_tc_get( rtems_timecounter_simple *tc )
    51 {
    52   return ERC32_MEC.Real_Time_Clock_Counter;
    53 }
    54 
    55 static bool erc32_tc_is_pending( rtems_timecounter_simple *tc )
    56 {
    57   return ERC32_Is_interrupt_pending( ERC32_INTERRUPT_REAL_TIME_CLOCK );
    58 }
    59 
    60 static uint32_t erc32_tc_get_timecount( struct timecounter *tc )
    61 {
    62   return rtems_timecounter_simple_downcounter_get(
    63     tc,
    64     erc32_tc_get,
    65     erc32_tc_is_pending
    66   );
    67 }
    68 
    69 static void erc32_tc_at_tick( rtems_timecounter_simple *tc )
    70 {
    71   /* Nothing to do */
    72 }
    73 
    74 static void erc32_tc_tick( void )
    75 {
    76   rtems_timecounter_simple_downcounter_tick(
    77     &erc32_tc,
    78     erc32_tc_get,
    79     erc32_tc_at_tick
    80   );
    81 }
    82 
    83 static void erc32_counter_initialize( void )
    84 {
    85   _SPARC_Counter_initialize(
    86     _SPARC_Counter_read_address,
    87     _SPARC_Counter_difference_clock_period,
    88     &ERC32_MEC.Real_Time_Clock_Counter
    89   );
    90 }
    91 
    92 uint32_t _CPU_Counter_frequency(void)
    93 {
    94   return ERC32_REAL_TIME_CLOCK_FREQUENCY;
    95 }
    96 
    97 #define Clock_driver_support_initialize_hardware() \
    98   do { \
    99     /* approximately 1 us per countdown */ \
    100     ERC32_MEC.Real_Time_Clock_Scalar  = CLOCK_SPEED - 1; \
    101     ERC32_MEC.Real_Time_Clock_Counter = \
    102       rtems_configuration_get_microseconds_per_tick(); \
    103     \
    104     ERC32_MEC_Set_Real_Time_Clock_Timer_Control( \
    105         ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING | \
    106         ERC32_MEC_TIMER_COUNTER_LOAD_SCALER | \
    107         ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER \
    108     ); \
    109     \
    110     ERC32_MEC_Set_Real_Time_Clock_Timer_Control( \
    111         ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING | \
    112         ERC32_MEC_TIMER_COUNTER_RELOAD_AT_ZERO \
    113     );  \
    114     rtems_timecounter_simple_install( \
    115         &erc32_tc, \
    116         ERC32_REAL_TIME_CLOCK_FREQUENCY, \
    117         rtems_configuration_get_microseconds_per_tick(), \
    118         erc32_tc_get_timecount \
    119     ); \
    120     erc32_counter_initialize(); \
    121   } while (0)
    122 
    123 #define Clock_driver_timecounter_tick() erc32_tc_tick()
     117#define Clock_driver_support_initialize_hardware() erc32_clock_init()
    124118
    125119#include "../../../shared/dev/clock/clockimpl.h"
Note: See TracChangeset for help on using the changeset viewer.