Changeset 762fa62 in rtems for bsps/arm


Ignore:
Timestamp:
May 22, 2018, 6:52:13 AM (18 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
b0c3ba2f
Parents:
65f868c
git-author:
Sebastian Huber <sebastian.huber@…> (05/22/18 06:52:13)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/15/18 11:12:05)
Message:

arm: Simplify CPU counter support

Use the standard ARMv7-M systick module for the ARMv7-M CPU counter
instead of DWT counter since the DWT counter is affected by power saving
states.

Use an inline function for _CPU_Counter_difference() for all ARM BSPs.

Update #3456.

Location:
bsps/arm
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • bsps/arm/lpc176x/start/system-clocks.c

    r65f868c r762fa62  
    119119  return lpc176x_get_timer1();
    120120}
    121 
    122 inline CPU_Counter_ticks _CPU_Counter_difference(
    123   CPU_Counter_ticks second,
    124   CPU_Counter_ticks first
    125 )
    126 {
    127   return second - first;
    128 }
    129 
  • bsps/arm/shared/clock/clock-armv7m.c

    r65f868c r762fa62  
    11/*
    2  * Copyright (c) 2011-2012 Sebastian Huber.  All rights reserved.
     2 * Copyright (c) 2011, 2018 Sebastian Huber.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
    5  *  Obere Lagerstr. 30
     5 *  Dornierstr. 4
    66 *  82178 Puchheim
    77 *  Germany
     
    1313 */
    1414
     15#include <bsp/clock-armv7m.h>
     16
    1517#include <rtems.h>
    16 #include <rtems/timecounter.h>
    17 #include <rtems/score/armv7m.h>
    18 
    19 #include <bsp.h>
     18#include <rtems/sysinit.h>
    2019
    2120#ifdef ARM_MULTILIB_ARCH_V7M
     
    2423static void Clock_isr(void *arg);
    2524
    26 typedef struct {
    27   rtems_timecounter_simple base;
    28   void (*tick)(void);
    29   bool countflag;
    30 } ARMV7M_Timecounter;
     25ARMV7M_Timecounter _ARMV7M_TC;
    3126
    32 static ARMV7M_Timecounter _ARMV7M_TC;
    33 
    34 static uint32_t _ARMV7M_TC_systick_get(rtems_timecounter_simple *tc)
     27static uint32_t _ARMV7M_TC_get_timecount(struct timecounter *base)
    3528{
    36   volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
    37 
    38   return systick->cvr;
     29  return _ARMV7M_Clock_counter((ARMV7M_Timecounter *) base);
    3930}
    4031
    41 static bool _ARMV7M_TC_systick_is_pending(rtems_timecounter_simple *base)
    42 {
    43   ARMV7M_Timecounter *tc = (ARMV7M_Timecounter *) base;
    44   rtems_interrupt_level level;
    45   bool countflag;
    46 
    47   rtems_interrupt_disable(level);
    48 
    49   countflag = tc->countflag;
    50   if (!countflag) {
    51     volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
    52 
    53     countflag = ((systick->csr & ARMV7M_SYSTICK_CSR_COUNTFLAG) != 0);
    54     tc->countflag = countflag;
    55   }
    56 
    57   rtems_interrupt_enable(level);
    58 
    59   return countflag;
    60 }
    61 
    62 static uint32_t _ARMV7M_TC_systick_get_timecount(struct timecounter *tc)
    63 {
    64   return rtems_timecounter_simple_downcounter_get(
    65     tc,
    66     _ARMV7M_TC_systick_get,
    67     _ARMV7M_TC_systick_is_pending
    68   );
    69 }
    70 
    71 static void _ARMV7M_TC_systick_at_tick(rtems_timecounter_simple *base)
    72 {
    73   ARMV7M_Timecounter *tc = (ARMV7M_Timecounter *) base;
    74   volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
    75 
    76   tc->countflag = false;
    77 
    78   /* Clear COUNTFLAG */
    79   systick->csr;
    80 }
    81 
    82 static void _ARMV7M_TC_systick_tick(void)
    83 {
    84   rtems_timecounter_simple_downcounter_tick(
    85     &_ARMV7M_TC.base,
    86     _ARMV7M_TC_systick_get,
    87     _ARMV7M_TC_systick_at_tick
    88   );
    89 }
    90 
    91 static void _ARMV7M_TC_tick(void)
    92 {
    93   (*_ARMV7M_TC.tick)();
    94 }
    95 
    96 static void _ARMV7M_Systick_handler(void)
     32static void _ARMV7M_Clock_handler(void)
    9733{
    9834  _ARMV7M_Interrupt_service_enter();
     
    10137}
    10238
    103 static void _ARMV7M_Systick_handler_install(void)
     39static void _ARMV7M_Clock_handler_install(void)
    10440{
    10541  _ARMV7M_Set_exception_priority_and_handler(
    10642    ARMV7M_VECTOR_SYSTICK,
    10743    BSP_ARMV7M_SYSTICK_PRIORITY,
    108     _ARMV7M_Systick_handler
     44    _ARMV7M_Clock_handler
    10945  );
    11046}
    11147
    112 static void _ARMV7M_Systick_initialize(void)
     48static void _ARMV7M_Clock_initialize(void)
    11349{
    114   volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
    115   #ifdef BSP_ARMV7M_SYSTICK_FREQUENCY
    116     uint64_t freq = BSP_ARMV7M_SYSTICK_FREQUENCY;
    117   #else
    118     uint64_t freq = ARMV7M_SYSTICK_CALIB_TENMS_GET(systick->calib) * 100ULL;
    119   #endif
    120   uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
    121   uint64_t interval = (freq * us_per_tick) / 1000000ULL;
     50  volatile ARMV7M_Systick *systick;
     51  ARMV7M_Timecounter *tc;
    12252
    123   systick->rvr = (uint32_t) interval;
    124   systick->cvr = 0;
     53  systick = _ARMV7M_Systick;
     54  tc = &_ARMV7M_TC;
     55
    12556  systick->csr = ARMV7M_SYSTICK_CSR_ENABLE
    12657    | ARMV7M_SYSTICK_CSR_TICKINT
    12758    | ARMV7M_SYSTICK_CSR_CLKSOURCE;
    12859
    129   _ARMV7M_TC.tick = _ARMV7M_TC_systick_tick;
    130   rtems_timecounter_simple_install(
    131     &_ARMV7M_TC.base,
    132     freq,
    133     interval,
    134     _ARMV7M_TC_systick_get_timecount
    135   );
     60  tc->base.tc_get_timecount = _ARMV7M_TC_get_timecount;
     61  tc->base.tc_counter_mask = 0xffffffff;
     62  tc->base.tc_frequency = _ARMV7M_Clock_frequency();
     63  tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
     64  rtems_timecounter_install(&tc->base);
    13665}
    13766
    138 static void _ARMV7M_Systick_cleanup(void)
     67static void _ARMV7M_Clock_initialize_early(void)
     68{
     69  volatile ARMV7M_Systick *systick;
     70  uint32_t us_per_tick;
     71  uint64_t freq;
     72  uint32_t interval;
     73
     74  systick = _ARMV7M_Systick;
     75  us_per_tick = rtems_configuration_get_microseconds_per_tick();
     76  freq = _ARMV7M_Clock_frequency();
     77
     78  interval = (uint32_t) ((freq * us_per_tick) / 1000000);
     79
     80  systick->rvr = interval;
     81  systick->cvr = 0;
     82  systick->csr = ARMV7M_SYSTICK_CSR_ENABLE | ARMV7M_SYSTICK_CSR_CLKSOURCE;
     83}
     84
     85RTEMS_SYSINIT_ITEM(
     86  _ARMV7M_Clock_initialize_early,
     87  RTEMS_SYSINIT_CPU_COUNTER,
     88  RTEMS_SYSINIT_ORDER_FIRST
     89);
     90
     91static void _ARMV7M_Clock_cleanup(void)
    13992{
    14093  volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
     
    14396}
    14497
    145 #define Clock_driver_timecounter_tick() _ARMV7M_TC_tick()
    146 
    14798#define Clock_driver_support_initialize_hardware() \
    148   _ARMV7M_Systick_initialize()
     99  _ARMV7M_Clock_initialize()
    149100
    150101#define Clock_driver_support_install_isr(isr) \
    151   _ARMV7M_Systick_handler_install()
     102  _ARMV7M_Clock_handler_install()
    152103
    153104#define Clock_driver_support_shutdown_hardware() \
    154   _ARMV7M_Systick_cleanup()
     105  _ARMV7M_Clock_cleanup()
    155106
    156107/* Include shared source clock driver code */
  • bsps/arm/shared/cpucounter/cpucounter-armv7m.c

    r65f868c r762fa62  
    11/*
    2  * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2016, 2018 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    1313 */
    1414
    15 #include <rtems/score/armv7m.h>
    16 #include <rtems/counter.h>
    17 #include <rtems/sysinit.h>
    18 
    19 #include <bsp.h>
    20 #include <bsp/fatal.h>
     15#include <bsp/clock-armv7m.h>
    2116
    2217uint32_t _CPU_Counter_frequency(void)
    2318{
    24 #ifdef BSP_ARMV7M_SYSTICK_FREQUENCY
    25   return = BSP_ARMV7M_SYSTICK_FREQUENCY;
    26 #else
    27   volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
    28   return ARMV7M_SYSTICK_CALIB_TENMS_GET(systick->calib) * 100;
    29 #endif
     19  return _ARMV7M_Clock_frequency();
    3020}
    3121
    3222CPU_Counter_ticks _CPU_Counter_read(void)
    3323{
    34   volatile ARMV7M_DWT *dwt = _ARMV7M_DWT;
    35 
    36   return dwt->cyccnt;
     24  return _ARMV7M_Clock_counter(&_ARMV7M_TC);
    3725}
    38 
    39 static void armv7m_cpu_counter_initialize(void)
    40 {
    41   bool cyccnt_enabled;
    42 
    43   cyccnt_enabled = _ARMV7M_DWT_Enable_CYCCNT();
    44 
    45   if (!cyccnt_enabled) {
    46     bsp_fatal(BSP_ARM_ARMV7M_CPU_COUNTER_INIT);
    47   }
    48 }
    49 
    50 RTEMS_SYSINIT_ITEM(
    51   armv7m_cpu_counter_initialize,
    52   RTEMS_SYSINIT_CPU_COUNTER,
    53   RTEMS_SYSINIT_ORDER_FIRST
    54 );
Note: See TracChangeset for help on using the changeset viewer.