mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
@@ -23,7 +23,12 @@
|
||||
/* This is defined in clockdrv_shell.h */
|
||||
static void Clock_isr(void *arg);
|
||||
|
||||
static rtems_timecounter_simple _ARMV7M_TC;
|
||||
typedef struct {
|
||||
rtems_timecounter_simple base;
|
||||
bool countflag;
|
||||
} ARMV7M_Timecounter;
|
||||
|
||||
static ARMV7M_Timecounter _ARMV7M_TC;
|
||||
|
||||
static uint32_t _ARMV7M_TC_get(rtems_timecounter_simple *tc)
|
||||
{
|
||||
@@ -32,11 +37,25 @@ static uint32_t _ARMV7M_TC_get(rtems_timecounter_simple *tc)
|
||||
return systick->cvr;
|
||||
}
|
||||
|
||||
static bool _ARMV7M_TC_is_pending(rtems_timecounter_simple *tc)
|
||||
static bool _ARMV7M_TC_is_pending(rtems_timecounter_simple *base)
|
||||
{
|
||||
volatile ARMV7M_SCB *scb = _ARMV7M_SCB;
|
||||
ARMV7M_Timecounter *tc = (ARMV7M_Timecounter *) base;
|
||||
rtems_interrupt_level level;
|
||||
bool countflag;
|
||||
|
||||
return ((scb->icsr & ARMV7M_SCB_ICSR_PENDSTSET) != 0);
|
||||
rtems_interrupt_disable(level);
|
||||
|
||||
countflag = tc->countflag;
|
||||
if (!countflag) {
|
||||
volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
|
||||
|
||||
countflag = ((systick->csr & ARMV7M_SYSTICK_CSR_COUNTFLAG) != 0);
|
||||
tc->countflag = countflag;
|
||||
}
|
||||
|
||||
rtems_interrupt_enable(level);
|
||||
|
||||
return countflag;
|
||||
}
|
||||
|
||||
static uint32_t _ARMV7M_TC_get_timecount(struct timecounter *tc)
|
||||
@@ -48,19 +67,26 @@ static uint32_t _ARMV7M_TC_get_timecount(struct timecounter *tc)
|
||||
);
|
||||
}
|
||||
|
||||
static void _ARMV7M_TC_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(&_ARMV7M_TC, _ARMV7M_TC_get);
|
||||
}
|
||||
|
||||
static void _ARMV7M_Systick_at_tick(void)
|
||||
static void _ARMV7M_TC_at_tick(rtems_timecounter_simple *base)
|
||||
{
|
||||
ARMV7M_Timecounter *tc = (ARMV7M_Timecounter *) base;
|
||||
volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
|
||||
|
||||
tc->countflag = false;
|
||||
|
||||
/* Clear COUNTFLAG */
|
||||
systick->csr;
|
||||
}
|
||||
|
||||
static void _ARMV7M_TC_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&_ARMV7M_TC.base,
|
||||
_ARMV7M_TC_get,
|
||||
_ARMV7M_TC_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
static void _ARMV7M_Systick_handler(void)
|
||||
{
|
||||
_ARMV7M_Interrupt_service_enter();
|
||||
@@ -95,7 +121,7 @@ static void _ARMV7M_Systick_initialize(void)
|
||||
| ARMV7M_SYSTICK_CSR_CLKSOURCE;
|
||||
|
||||
rtems_timecounter_simple_install(
|
||||
&_ARMV7M_TC,
|
||||
&_ARMV7M_TC.base,
|
||||
freq,
|
||||
interval,
|
||||
_ARMV7M_TC_get_timecount
|
||||
@@ -111,9 +137,6 @@ static void _ARMV7M_Systick_cleanup(void)
|
||||
|
||||
#define Clock_driver_timecounter_tick() _ARMV7M_TC_tick()
|
||||
|
||||
#define Clock_driver_support_at_tick() \
|
||||
_ARMV7M_Systick_at_tick()
|
||||
|
||||
#define Clock_driver_support_initialize_hardware() \
|
||||
_ARMV7M_Systick_initialize()
|
||||
|
||||
|
||||
@@ -32,18 +32,19 @@ static uint32_t mcf52235_tc_get_timecount(struct timecounter *tc)
|
||||
);
|
||||
}
|
||||
|
||||
static void mcf52235_tc_tick(void)
|
||||
static void mcf52235_tc_at_tick(rtems_timecounter_simple *tc)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(&mcf52235_tc, mcf52235_tc_get);
|
||||
MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Periodic interval timer interrupt handler
|
||||
*/
|
||||
#define Clock_driver_support_at_tick() \
|
||||
do { \
|
||||
MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF; \
|
||||
} while (0) \
|
||||
static void mcf52235_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&mcf52235_tc,
|
||||
mcf52235_tc_get,
|
||||
mcf52235_tc_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach clock interrupt handler
|
||||
|
||||
@@ -32,18 +32,19 @@ static uint32_t mcf5225x_tc_get_timecount(struct timecounter *tc)
|
||||
);
|
||||
}
|
||||
|
||||
static void mcf5225x_tc_tick(void)
|
||||
static void mcf5225x_tc_at_tick(rtems_timecounter_simple *tc)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(&mcf5225x_tc, mcf5225x_tc_get);
|
||||
MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Periodic interval timer interrupt handler
|
||||
*/
|
||||
#define Clock_driver_support_at_tick() \
|
||||
do { \
|
||||
MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF; \
|
||||
} while (0) \
|
||||
static void mcf5225x_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&mcf5225x_tc,
|
||||
mcf5225x_tc_get,
|
||||
mcf5225x_tc_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach clock interrupt handler
|
||||
|
||||
@@ -32,18 +32,19 @@ static uint32_t mcf5329_tc_get_timecount(struct timecounter *tc)
|
||||
);
|
||||
}
|
||||
|
||||
static void mcf5329_tc_tick(void)
|
||||
static void mcf5329_tc_at_tick(rtems_timecounter_simple *tc)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(&mcf5329_tc, mcf5329_tc_get);
|
||||
MCF_PIT3_PCSR |= MCF_PIT_PCSR_PIF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Periodic interval timer interrupt handler
|
||||
*/
|
||||
#define Clock_driver_support_at_tick() \
|
||||
do { \
|
||||
MCF_PIT3_PCSR |= MCF_PIT_PCSR_PIF; \
|
||||
} while (0) \
|
||||
static void mcf5329_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&mcf5329_tc,
|
||||
mcf5329_tc_get,
|
||||
mcf5329_tc_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach clock interrupt handler
|
||||
|
||||
@@ -16,6 +16,17 @@
|
||||
#include <bsp.h>
|
||||
#include <mcf5282/mcf5282.h>
|
||||
|
||||
/*
|
||||
* CPU load counters
|
||||
* Place in static RAM so updates don't hit the SDRAM
|
||||
*/
|
||||
#define IDLE_COUNTER __SRAMBASE.idle_counter
|
||||
#define FILTERED_IDLE __SRAMBASE.filtered_idle
|
||||
#define MAX_IDLE_COUNT __SRAMBASE.max_idle_count
|
||||
#define PITC_PER_TICK __SRAMBASE.pitc_per_tick
|
||||
#define NSEC_PER_PITC __SRAMBASE.nsec_per_pitc
|
||||
#define FILTER_SHIFT 6
|
||||
|
||||
/*
|
||||
* Use INTC0 base
|
||||
*/
|
||||
@@ -42,34 +53,24 @@ static uint32_t uC5282_tc_get_timecount(struct timecounter *tc)
|
||||
);
|
||||
}
|
||||
|
||||
static void uC5282_tc_tick(void)
|
||||
static void uC5282_tc_at_tick(rtems_timecounter_simple *tc)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(&uC5282_tc, uC5282_tc_get);
|
||||
unsigned idle = IDLE_COUNTER;
|
||||
IDLE_COUNTER = 0;
|
||||
if (idle > MAX_IDLE_COUNT)
|
||||
MAX_IDLE_COUNT = idle;
|
||||
FILTERED_IDLE = idle + FILTERED_IDLE - (FILTERED_IDLE>>FILTER_SHIFT);
|
||||
MCF5282_PIT3_PCSR |= MCF5282_PIT_PCSR_PIF;
|
||||
}
|
||||
|
||||
/*
|
||||
* CPU load counters
|
||||
* Place in static RAM so updates don't hit the SDRAM
|
||||
*/
|
||||
#define IDLE_COUNTER __SRAMBASE.idle_counter
|
||||
#define FILTERED_IDLE __SRAMBASE.filtered_idle
|
||||
#define MAX_IDLE_COUNT __SRAMBASE.max_idle_count
|
||||
#define PITC_PER_TICK __SRAMBASE.pitc_per_tick
|
||||
#define NSEC_PER_PITC __SRAMBASE.nsec_per_pitc
|
||||
#define FILTER_SHIFT 6
|
||||
|
||||
/*
|
||||
* Periodic interval timer interrupt handler
|
||||
*/
|
||||
#define Clock_driver_support_at_tick() \
|
||||
do { \
|
||||
unsigned idle = IDLE_COUNTER; \
|
||||
IDLE_COUNTER = 0; \
|
||||
if (idle > MAX_IDLE_COUNT) \
|
||||
MAX_IDLE_COUNT = idle; \
|
||||
FILTERED_IDLE = idle + FILTERED_IDLE - (FILTERED_IDLE>>FILTER_SHIFT);\
|
||||
MCF5282_PIT3_PCSR |= MCF5282_PIT_PCSR_PIF; \
|
||||
} while (0)
|
||||
static void uC5282_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&uC5282_tc,
|
||||
uC5282_tc_get,
|
||||
uC5282_tc_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach clock interrupt handler
|
||||
|
||||
@@ -55,18 +55,22 @@ static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc)
|
||||
);
|
||||
}
|
||||
|
||||
static void mpc55xx_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_upcounter_tick(&mpc55xx_tc, mpc55xx_tc_get);
|
||||
}
|
||||
|
||||
static void mpc55xx_clock_at_tick(void)
|
||||
static void mpc55xx_tc_at_tick(rtems_timecounter_simple *tc)
|
||||
{
|
||||
union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
|
||||
csr.B.FLAG = 1;
|
||||
EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.R = csr.R;
|
||||
}
|
||||
|
||||
static void mpc55xx_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_upcounter_tick(
|
||||
&mpc55xx_tc,
|
||||
mpc55xx_tc_get,
|
||||
mpc55xx_tc_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
@@ -174,12 +178,7 @@ static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc)
|
||||
);
|
||||
}
|
||||
|
||||
static void mpc55xx_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(&mpc55xx_tc, mpc55xx_tc_get);
|
||||
}
|
||||
|
||||
static void mpc55xx_clock_at_tick(void)
|
||||
static void mpc55xx_tc_at_tick(rtems_timecounter_simple *tc)
|
||||
{
|
||||
volatile PIT_RTI_CHANNEL_tag *channel =
|
||||
&PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
|
||||
@@ -188,6 +187,15 @@ static void mpc55xx_clock_at_tick(void)
|
||||
channel->TFLG.R = tflg.R;
|
||||
}
|
||||
|
||||
static void mpc55xx_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&mpc55xx_tc,
|
||||
mpc55xx_tc_get,
|
||||
mpc55xx_tc_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
@@ -238,8 +246,6 @@ static void mpc55xx_clock_cleanup(void)
|
||||
#endif
|
||||
|
||||
#define Clock_driver_timecounter_tick() mpc55xx_tc_tick()
|
||||
#define Clock_driver_support_at_tick() \
|
||||
mpc55xx_clock_at_tick()
|
||||
#define Clock_driver_support_initialize_hardware() \
|
||||
mpc55xx_clock_initialize()
|
||||
#define Clock_driver_support_install_isr(isr, old_isr) \
|
||||
|
||||
@@ -44,6 +44,13 @@
|
||||
#define Clock_driver_support_find_timer()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Do nothing by default.
|
||||
*/
|
||||
#ifndef Clock_driver_support_at_tick
|
||||
#define Clock_driver_support_at_tick()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A specialized clock driver may use for example rtems_timecounter_tick_simple()
|
||||
* instead of the default.
|
||||
@@ -108,7 +115,14 @@ rtems_isr Clock_isr(
|
||||
&& _Thread_Executing->Start.entry_point
|
||||
== (Thread_Entry) rtems_configuration_get_idle_task()
|
||||
) {
|
||||
_Timecounter_Tick_simple(interval, (*tc->tc_get_timecount)(tc));
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_Timecounter_Acquire(&lock_context);
|
||||
_Timecounter_Tick_simple(
|
||||
interval,
|
||||
(*tc->tc_get_timecount)(tc),
|
||||
&lock_context
|
||||
);
|
||||
}
|
||||
|
||||
Clock_driver_support_at_tick();
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
*/
|
||||
#define CLOCK_VECTOR ERC32_TRAP_TYPE( ERC32_INTERRUPT_REAL_TIME_CLOCK )
|
||||
|
||||
#define Clock_driver_support_at_tick()
|
||||
|
||||
#define Clock_driver_support_install_isr( _new, _old ) \
|
||||
do { \
|
||||
_old = set_vector( _new, CLOCK_VECTOR, 1 ); \
|
||||
@@ -66,11 +64,17 @@ static uint32_t erc32_tc_get_timecount( struct timecounter *tc )
|
||||
);
|
||||
}
|
||||
|
||||
static void erc32_tc_at_tick( rtems_timecounter_simple *tc )
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
static void erc32_tc_tick( void )
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&erc32_tc,
|
||||
erc32_tc_get
|
||||
erc32_tc_get,
|
||||
erc32_tc_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,9 +51,18 @@ static uint32_t leon2_tc_get_timecount( struct timecounter *tc )
|
||||
);
|
||||
}
|
||||
|
||||
static void leon2_tc_at_tick( rtems_timecounter_simple *tc )
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
static void leon2_tc_tick( void )
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick( &leon2_tc, leon2_tc_get );
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&leon2_tc,
|
||||
leon2_tc_get,
|
||||
leon2_tc_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -62,8 +71,6 @@ static void leon2_tc_tick( void )
|
||||
|
||||
#define CLOCK_VECTOR LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER1 )
|
||||
|
||||
#define Clock_driver_support_at_tick()
|
||||
|
||||
#define Clock_driver_support_install_isr( _new, _old ) \
|
||||
do { \
|
||||
_old = set_vector( _new, CLOCK_VECTOR, 1 ); \
|
||||
|
||||
@@ -69,15 +69,6 @@ static uint32_t leon3_tc_get_timecount_irqmp(struct timecounter *tc)
|
||||
return LEON3_IrqCtrl_Regs->timestamp[0].counter;
|
||||
}
|
||||
|
||||
static void leon3_tc_tick(void)
|
||||
{
|
||||
if (leon3_tc_use_irqmp) {
|
||||
rtems_timecounter_tick();
|
||||
} else {
|
||||
rtems_timecounter_simple_downcounter_tick(&leon3_tc, leon3_tc_get);
|
||||
}
|
||||
}
|
||||
|
||||
static void leon3_clock_profiling_interrupt_delay(void)
|
||||
{
|
||||
#ifdef RTEMS_PROFILING
|
||||
@@ -111,10 +102,24 @@ static void leon3_clock_profiling_interrupt_delay(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#define Clock_driver_support_at_tick() \
|
||||
do { \
|
||||
leon3_clock_profiling_interrupt_delay(); \
|
||||
} while (0)
|
||||
static void leon3_tc_at_tick( rtems_timecounter_simple *tc )
|
||||
{
|
||||
leon3_clock_profiling_interrupt_delay();
|
||||
}
|
||||
|
||||
static void leon3_tc_tick(void)
|
||||
{
|
||||
if (leon3_tc_use_irqmp) {
|
||||
leon3_clock_profiling_interrupt_delay();
|
||||
rtems_timecounter_tick();
|
||||
} else {
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&leon3_tc,
|
||||
leon3_tc_get,
|
||||
leon3_tc_at_tick
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#define Adjust_clkirq_for_node() do { clkirq += LEON3_CLOCK_INDEX; } while(0)
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#undef CLOCK_DRIVER_ISRS_PER_TICK
|
||||
#undef CLOCK_DRIVER_USE_FAST_IDLE
|
||||
*/
|
||||
#define Clock_driver_support_at_tick()
|
||||
|
||||
/*
|
||||
* Number of Clock ticks since initialization
|
||||
@@ -87,11 +86,17 @@ static uint32_t tlib_tc_get_timecount(struct timecounter *tc)
|
||||
);
|
||||
}
|
||||
|
||||
static void tlib_tc_at_tick(rtems_timecounter_simple *tc)
|
||||
{
|
||||
/* Nothing to do? */
|
||||
}
|
||||
|
||||
static void tlib_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&tlib_tc,
|
||||
tlib_tc_get
|
||||
tlib_tc_get,
|
||||
tlib_tc_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
@@ -130,16 +135,10 @@ void Clock_isr(void *arg_unused)
|
||||
} while ( _Thread_Executing == _Thread_Idle &&
|
||||
_Thread_Heir == _Thread_Executing);
|
||||
|
||||
Clock_driver_support_at_tick();
|
||||
return;
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Add custom handling at every tick from bsp.h
|
||||
*/
|
||||
Clock_driver_support_at_tick();
|
||||
|
||||
#ifdef CLOCK_DRIVER_ISRS_PER_TICK
|
||||
/*
|
||||
* The driver is multiple ISRs per clock tick.
|
||||
|
||||
@@ -45,9 +45,26 @@ static uint32_t lpc22xx_tc_get_timecount(struct timecounter *tc)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* When we get the clock interrupt
|
||||
* - clear the interrupt bit?
|
||||
* - restart the timer?
|
||||
*/
|
||||
static void lpc22xx_tc_at_tick(rtems_timecounter_simple *tc)
|
||||
{
|
||||
if (!(T0IR & 0x01))
|
||||
return;
|
||||
T0IR = 0x01;
|
||||
VICVectAddr = 0x00;
|
||||
}
|
||||
|
||||
static void lpc22xx_tc_tick(void)
|
||||
{
|
||||
rtems_timecounter_simple_upcounter_tick(&lpc22xx_tc, lpc22xx_tc_get);
|
||||
rtems_timecounter_simple_upcounter_tick(
|
||||
&lpc22xx_tc,
|
||||
lpc22xx_tc_get,
|
||||
lpc22xx_tc_at_tick
|
||||
);
|
||||
}
|
||||
|
||||
/* Replace the first value with the clock's interrupt name. */
|
||||
@@ -62,19 +79,6 @@ rtems_irq_connect_data clock_isr_data = {
|
||||
|
||||
/* use the /shared/clockdrv_shell.h code template */
|
||||
|
||||
/**
|
||||
* When we get the clock interrupt
|
||||
* - clear the interrupt bit?
|
||||
* - restart the timer?
|
||||
*/
|
||||
#define Clock_driver_support_at_tick() \
|
||||
do { \
|
||||
if (!(T0IR & 0x01)) \
|
||||
return; \
|
||||
T0IR = 0x01; \
|
||||
VICVectAddr = 0x00; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Installs the clock ISR. You shouldn't need to change this.
|
||||
*/
|
||||
|
||||
@@ -23,9 +23,13 @@
|
||||
|
||||
rtems_status_code rtems_clock_tick( void )
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_Timecounter_Acquire( &lock_context );
|
||||
_Timecounter_Tick_simple(
|
||||
rtems_configuration_get_microseconds_per_tick(),
|
||||
0
|
||||
0,
|
||||
&lock_context
|
||||
);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
@@ -93,6 +93,13 @@ typedef struct {
|
||||
uint32_t binary_interval;
|
||||
} rtems_timecounter_simple;
|
||||
|
||||
/**
|
||||
* @brief At tick handling done under protection of the timecounter lock.
|
||||
*/
|
||||
typedef void rtems_timecounter_simple_at_tick(
|
||||
rtems_timecounter_simple *tc
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Returns the current value of a simple timecounter.
|
||||
*/
|
||||
@@ -199,20 +206,28 @@ RTEMS_INLINE_ROUTINE uint32_t rtems_timecounter_simple_scale(
|
||||
*
|
||||
* @param[in] tc The simple timecounter.
|
||||
* @param[in] get The method to get the value of the simple timecounter.
|
||||
* @param[in] at_tick The method to perform work under timecounter lock
|
||||
* protection at this tick, e.g. clear a pending flag.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void rtems_timecounter_simple_downcounter_tick(
|
||||
rtems_timecounter_simple *tc,
|
||||
rtems_timecounter_simple_get get
|
||||
rtems_timecounter_simple *tc,
|
||||
rtems_timecounter_simple_get get,
|
||||
rtems_timecounter_simple_at_tick at_tick
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
uint32_t current;
|
||||
|
||||
_Timecounter_Acquire( &lock_context );
|
||||
|
||||
( *at_tick )( tc );
|
||||
|
||||
current = rtems_timecounter_simple_scale(
|
||||
tc,
|
||||
tc->real_interval - ( *get )( tc )
|
||||
);
|
||||
|
||||
_Timecounter_Tick_simple( tc->binary_interval, current );
|
||||
_Timecounter_Tick_simple( tc->binary_interval, current, &lock_context );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,17 +235,25 @@ RTEMS_INLINE_ROUTINE void rtems_timecounter_simple_downcounter_tick(
|
||||
*
|
||||
* @param[in] tc The simple timecounter.
|
||||
* @param[in] get The method to get the value of the simple timecounter.
|
||||
* @param[in] at_tick The method to perform work under timecounter lock
|
||||
* protection at this tick, e.g. clear a pending flag.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void rtems_timecounter_simple_upcounter_tick(
|
||||
rtems_timecounter_simple *tc,
|
||||
rtems_timecounter_simple_get get
|
||||
rtems_timecounter_simple *tc,
|
||||
rtems_timecounter_simple_get get,
|
||||
rtems_timecounter_simple_at_tick at_tick
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
uint32_t current;
|
||||
|
||||
_Timecounter_Acquire( &lock_context );
|
||||
|
||||
( *at_tick )( tc );
|
||||
|
||||
current = rtems_timecounter_simple_scale( tc, ( *get )( tc ) );
|
||||
|
||||
_Timecounter_Tick_simple( tc->binary_interval, current );
|
||||
_Timecounter_Tick_simple( tc->binary_interval, current, &lock_context );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/timetc.h>
|
||||
|
||||
#include <rtems/score/isrlock.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
@@ -160,6 +162,21 @@ void _Timecounter_Install( struct timecounter *tc );
|
||||
*/
|
||||
void _Timecounter_Tick( void );
|
||||
|
||||
/**
|
||||
* @brief Lock to protect the timecounter mechanic.
|
||||
*/
|
||||
ISR_LOCK_DECLARE( extern, _Timecounter_Lock )
|
||||
|
||||
/**
|
||||
* @brief Acquires the timecounter lock.
|
||||
*
|
||||
* @param[in] lock_context The lock context.
|
||||
*
|
||||
* See _Timecounter_Tick_simple().
|
||||
*/
|
||||
#define _Timecounter_Acquire( lock_context ) \
|
||||
_ISR_lock_ISR_disable_and_acquire( &_Timecounter_Lock, lock_context )
|
||||
|
||||
/**
|
||||
* @brief Performs a simple timecounter tick.
|
||||
*
|
||||
@@ -169,8 +186,14 @@ void _Timecounter_Tick( void );
|
||||
* @param[in] delta The time in timecounter ticks elapsed since the last call
|
||||
* to _Timecounter_Tick_simple().
|
||||
* @param[in] offset The current value of the timecounter.
|
||||
* @param[in] lock_context The lock context of the corresponding
|
||||
* _Timecounter_Acquire().
|
||||
*/
|
||||
void _Timecounter_Tick_simple( uint32_t delta, uint32_t offset );
|
||||
void _Timecounter_Tick_simple(
|
||||
uint32_t delta,
|
||||
uint32_t offset,
|
||||
ISR_lock_Context *lock_context
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief The wall clock time in seconds.
|
||||
|
||||
@@ -64,7 +64,9 @@ __FBSDID("$FreeBSD r284178 2015-06-09T11:49:56Z$");
|
||||
#ifdef __rtems__
|
||||
#include <limits.h>
|
||||
#include <rtems.h>
|
||||
ISR_LOCK_DEFINE(static, _Timecounter_Lock, "Timecounter");
|
||||
ISR_LOCK_DEFINE(, _Timecounter_Lock, "Timecounter")
|
||||
#define _Timecounter_Release(lock_context) \
|
||||
_ISR_lock_Release_and_ISR_enable(&_Timecounter_Lock, lock_context)
|
||||
#define hz rtems_clock_get_ticks_per_second()
|
||||
#define printf(...)
|
||||
#define log(...)
|
||||
@@ -1383,7 +1385,7 @@ tc_windup(void)
|
||||
#ifdef __rtems__
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_ISR_lock_ISR_disable_and_acquire(&_Timecounter_Lock, &lock_context);
|
||||
_Timecounter_Acquire(&lock_context);
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/*
|
||||
@@ -1538,7 +1540,7 @@ tc_windup(void)
|
||||
timekeep_push_vdso();
|
||||
#endif /* __rtems__ */
|
||||
#ifdef __rtems__
|
||||
_ISR_lock_Release_and_ISR_enable(&_Timecounter_Lock, &lock_context);
|
||||
_Timecounter_Release(&lock_context);
|
||||
#endif /* __rtems__ */
|
||||
}
|
||||
|
||||
@@ -1963,14 +1965,12 @@ _Timecounter_Tick(void)
|
||||
}
|
||||
#ifdef __rtems__
|
||||
void
|
||||
_Timecounter_Tick_simple(uint32_t delta, uint32_t offset)
|
||||
_Timecounter_Tick_simple(uint32_t delta, uint32_t offset,
|
||||
ISR_lock_Context *lock_context)
|
||||
{
|
||||
struct bintime bt;
|
||||
struct timehands *th;
|
||||
uint32_t ogen;
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_ISR_lock_ISR_disable_and_acquire(&_Timecounter_Lock, &lock_context);
|
||||
|
||||
th = timehands;
|
||||
ogen = th->th_generation;
|
||||
@@ -1997,7 +1997,7 @@ _Timecounter_Tick_simple(uint32_t delta, uint32_t offset)
|
||||
time_second = th->th_microtime.tv_sec;
|
||||
time_uptime = th->th_offset.sec;
|
||||
|
||||
_ISR_lock_Release_and_ISR_enable(&_Timecounter_Lock, &lock_context);
|
||||
_Timecounter_Release(lock_context);
|
||||
|
||||
_Watchdog_Tick();
|
||||
}
|
||||
|
||||
@@ -89,6 +89,13 @@ static uint32_t some_tc_get( rtems_timecounter_simple *tc )
|
||||
return some.counter;
|
||||
@}
|
||||
|
||||
static void some_tc_at_tick( rtems_timecounter_simple *tc )
|
||||
@{
|
||||
/*
|
||||
* Do work necessary at the clock tick interrupt, e.g. clear a pending flag.
|
||||
*/
|
||||
@}
|
||||
|
||||
static bool some_tc_is_pending( rtems_timecounter_simple *tc )
|
||||
@{
|
||||
return some.is_pending;
|
||||
@@ -105,7 +112,11 @@ static uint32_t some_tc_get_timecount( struct timecounter *tc )
|
||||
|
||||
static void some_tc_tick( void )
|
||||
@{
|
||||
rtems_timecounter_simple_downcounter_tick( &some_tc, some_tc_get );
|
||||
rtems_timecounter_simple_downcounter_tick(
|
||||
&some_tc,
|
||||
some_tc_get,
|
||||
some_tc_at_tick
|
||||
);
|
||||
@}
|
||||
|
||||
static void some_support_initialize_hardware( void )
|
||||
|
||||
Reference in New Issue
Block a user