mirror of
https://github.com/t-crest/rtems.git
synced 2025-11-16 12:34:47 +00:00
Use new timer API and use usec timer instead of cycles timer
This commit is contained in:
@@ -22,6 +22,10 @@
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
|
||||
#include <machine/patmos.h>
|
||||
#include <machine/exceptions.h>
|
||||
#include <machine/rtc.h>
|
||||
|
||||
void Clock_exit( void );
|
||||
rtems_isr Clock_isr( rtems_vector_number vector )__attribute__((naked));
|
||||
|
||||
@@ -52,6 +56,8 @@ rtems_device_minor_number rtems_clock_minor;
|
||||
uint64_t cycles_offset;
|
||||
/* CPU frequency in MHZ */
|
||||
uint32_t freq;
|
||||
/* timestamp of the last tick in usec */
|
||||
uint64_t usec_offset;
|
||||
|
||||
/*
|
||||
* The previous ISR on this clock tick interrupt vector.
|
||||
@@ -61,41 +67,15 @@ rtems_isr_entry Old_ticker;
|
||||
|
||||
void Clock_exit( void );
|
||||
|
||||
void set_cpu_cycles (uint64_t time_warp)
|
||||
void set_usec_timer (uint64_t time_warp)
|
||||
{
|
||||
|
||||
__PATMOS_RTC_WR_CYCLE_LOW((unsigned int)time_warp);
|
||||
__PATMOS_RTC_WR_CYCLE_UP((unsigned int)(time_warp >> 32));
|
||||
// __PATMOS_RTC_WR_CYCLE_LOW((unsigned int)time_warp);
|
||||
// __PATMOS_RTC_WR_CYCLE_UP((unsigned int)(time_warp >> 32));
|
||||
|
||||
}
|
||||
usec_offset += time_warp;
|
||||
|
||||
uint64_t get_cpu_cycles(void)
|
||||
{
|
||||
uint32_t u;
|
||||
uint32_t l;
|
||||
|
||||
__PATMOS_RTC_RD_CYCLE_LOW(l);
|
||||
__PATMOS_RTC_RD_CYCLE_UP(u);
|
||||
|
||||
return (((uint64_t)u) << 32) | l;
|
||||
}
|
||||
|
||||
uint64_t get_cpu_time(void)
|
||||
{
|
||||
uint32_t u;
|
||||
uint32_t l;
|
||||
|
||||
__PATMOS_RTC_RD_TIME_LOW(l);
|
||||
__PATMOS_RTC_RD_TIME_UP(u);
|
||||
|
||||
return (((uint64_t)u) << 32) | l;
|
||||
}
|
||||
|
||||
uint32_t get_cpu_freq(void)
|
||||
{
|
||||
uint32_t freq;
|
||||
__PATMOS_CPU_RD_FREQ(freq);
|
||||
return freq;
|
||||
arm_usec_timer(usec_offset);
|
||||
}
|
||||
|
||||
uint32_t get_cpu_freq_mhz(void)
|
||||
@@ -232,7 +212,7 @@ rtems_isr Clock_isr(
|
||||
"i" (s6_OFFSET), "i" (s7_OFFSET), "i" (s8_OFFSET), "i" (s9_OFFSET), "i" (s10_OFFSET),
|
||||
"i" (s11_OFFSET), "i" (s12_OFFSET), "i" (s13_OFFSET), "i" (s14_OFFSET), "i" (s15_OFFSET));
|
||||
|
||||
__PATMOS_RTC_WR_INTERVAL(rtems_configuration_get_microseconds_per_tick() * freq);
|
||||
set_usec_timer(rtems_configuration_get_microseconds_per_tick());
|
||||
|
||||
/*
|
||||
* Accurate count of ISRs
|
||||
@@ -344,7 +324,13 @@ void Install_clock(
|
||||
Clock_driver_ticks = 0;
|
||||
Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000;
|
||||
|
||||
__PATMOS_RTC_WR_ISR((uint32_t)clock_isr);
|
||||
exc_register(EXC_INTR_USEC, (uint32_t)clock_isr);
|
||||
// clear pending flags
|
||||
intr_clear_all_pending();
|
||||
// unmask interrupt
|
||||
intr_unmask(EXC_INTR_USEC);
|
||||
// enable interrupts
|
||||
intr_enable();
|
||||
|
||||
#if defined(Clock_driver_nanoseconds_since_last_tick)
|
||||
rtems_clock_set_nanoseconds_extension(
|
||||
@@ -359,7 +345,11 @@ void Install_clock(
|
||||
*/
|
||||
cycles_offset = get_cpu_cycles();
|
||||
|
||||
__PATMOS_RTC_WR_INTERVAL(rtems_configuration_get_microseconds_per_tick() * freq);
|
||||
usec_offset = get_cpu_usecs();
|
||||
|
||||
set_usec_timer(rtems_configuration_get_microseconds_per_tick());
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Schedule the clock cleanup routine to execute if the application exits.
|
||||
|
||||
@@ -42,8 +42,6 @@ typedef _IODEV unsigned int volatile * const _iodev_ptr_t;
|
||||
|
||||
extern char _cpuinfo_base; /* linker symbol giving the address of the CPU info */
|
||||
|
||||
extern uint32_t get_cpu_freq(void);
|
||||
|
||||
extern uint32_t get_cpu_freq_mhz(void);
|
||||
|
||||
#define __PATMOS_INF 0xFFFFFFFF /* maximum cycles the clock can run without interrupts */
|
||||
@@ -120,11 +118,7 @@ extern char _uart_base; /* linker symbol giving the address of the UART */
|
||||
|
||||
extern char _timer_base; /* linker symbol giving the address of the RTC */
|
||||
|
||||
extern void set_cpu_cycles (uint64_t time_warp);
|
||||
|
||||
extern uint64_t get_cpu_cycles(void);
|
||||
|
||||
extern uint64_t get_cpu_time(void);
|
||||
extern void set_usec_timer (uint64_t time_warp);
|
||||
|
||||
/* Address to access the cycle counter low register of the RTC */
|
||||
#define __PATMOS_RTC_CYCLE_LOW_ADDR (&_timer_base + 0x04)
|
||||
@@ -138,11 +132,8 @@ extern uint64_t get_cpu_time(void);
|
||||
/* Address to access the time in microseconds up register of the RTC */
|
||||
#define __PATMOS_RTC_TIME_UP_ADDR (&_timer_base + 0x08)
|
||||
|
||||
/* Address to access the interrupt interval register of the RTC */
|
||||
#define __PATMOS_RTC_INTERVAL_ADDR (&_timer_base + 0x10)
|
||||
|
||||
/* Address to access the ISR address register of the RTC */
|
||||
#define __PATMOS_RTC_ISR_ADDR (&_timer_base + 0x14)
|
||||
/* Address to access the ISR address register of the RTC cycle timer */
|
||||
#define __PATMOS_RTC_ISR_ADDR (&_excunit_base + 0xc0)
|
||||
|
||||
/* Macro to read the RTC's cycle counter low register of the RTC */
|
||||
#define __PATMOS_RTC_RD_CYCLE_LOW(res) res = *((_iodev_ptr_t)__PATMOS_RTC_CYCLE_LOW_ADDR);
|
||||
@@ -156,18 +147,12 @@ extern uint64_t get_cpu_time(void);
|
||||
/* Macro to read the RTC's time in microseconds up register of the RTC */
|
||||
#define __PATMOS_RTC_RD_TIME_UP(res) res = *((_iodev_ptr_t)__PATMOS_RTC_TIME_UP_ADDR);
|
||||
|
||||
/* Macro to read the RTC's interrupt interval register */
|
||||
#define __PATMOS_RTC_RD_INTERVAL(interval) interval = *((_iodev_ptr_t)__PATMOS_RTC_INTERVAL_ADDR);
|
||||
|
||||
/* Macro to write the RTC's cycle counter low register */
|
||||
#define __PATMOS_RTC_WR_CYCLE_LOW(val) *((_iodev_ptr_t)__PATMOS_RTC_CYCLE_LOW_ADDR) = val;
|
||||
|
||||
/* Macro to write the RTC's cycle counter up register */
|
||||
#define __PATMOS_RTC_WR_CYCLE_UP(val) *((_iodev_ptr_t)__PATMOS_RTC_CYCLE_UP_ADDR) = val;
|
||||
|
||||
/* Macro to write the RTC's interrupt interval register */
|
||||
#define __PATMOS_RTC_WR_INTERVAL(interval) *((_iodev_ptr_t)__PATMOS_RTC_INTERVAL_ADDR) = interval;
|
||||
|
||||
/* Macro to write the RTC's ISR address register */
|
||||
#define __PATMOS_RTC_WR_ISR(address) *((_iodev_ptr_t)__PATMOS_RTC_ISR_ADDR) = address;
|
||||
|
||||
|
||||
@@ -18,31 +18,33 @@
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
#include <machine/rtc.h>
|
||||
|
||||
bool benchmark_timer_find_average_overhead;
|
||||
|
||||
#define AVG_OVERHEAD 0 /* It typically takes 0 microseconds */
|
||||
/* to start/stop the timer. */
|
||||
#define LEAST_VALID 1 /* Don't trust a value lower than this */
|
||||
|
||||
uint64_t timer_offset;
|
||||
|
||||
void benchmark_timer_initialize(void)
|
||||
{
|
||||
/*
|
||||
* Timer runs long and accurate enough not to require an interrupt.
|
||||
*/
|
||||
__PATMOS_RTC_WR_INTERVAL(__PATMOS_INF);
|
||||
timer_offset = get_cpu_cycles();
|
||||
}
|
||||
|
||||
int benchmark_timer_read(void)
|
||||
{
|
||||
uint32_t total;
|
||||
uint64_t total;
|
||||
|
||||
/*
|
||||
* Read the timer and see how many clicks it has been since we started.
|
||||
*/
|
||||
|
||||
__PATMOS_RTC_RD_INTERVAL(total);
|
||||
|
||||
total = (__PATMOS_INF - total)/get_cpu_freq_mhz();
|
||||
total = (get_cpu_cycles() - timer_offset)/get_cpu_freq_mhz();
|
||||
|
||||
if ( benchmark_timer_find_average_overhead == true )
|
||||
return total; /* in one microsecond units */
|
||||
|
||||
Reference in New Issue
Block a user