Use new timer API and use usec timer instead of cycles timer

This commit is contained in:
Stefan Hepp
2014-03-18 14:05:41 +01:00
parent 4626a8b696
commit 1c1b68be2f
3 changed files with 34 additions and 57 deletions

View File

@@ -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.

View File

@@ -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;

View File

@@ -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 */