[PATCH 2/4] timecounter: Port to RTEMS New test: timecounter01
Gedare Bloom
gedare at rtems.org
Wed Apr 1 14:55:30 UTC 2015
On Wed, Apr 1, 2015 at 10:37 AM, Alexander Krutwig
<alexander.krutwig at embedded-brains.de> wrote:
> ---
> cpukit/score/Makefile.am | 10 ++
> cpukit/score/include/rtems/score/timecounter.h | 23 +++
> cpukit/score/include/sys/timeffc.h | 2 +
> cpukit/score/include/sys/timetc.h | 2 +
Adding a new subdirectory here should be considered carefully. It
certainly needs justification.
> cpukit/score/preinstall.am | 25 +++
> cpukit/score/src/kern_tc.c | 171 ++++++++++++++++++++-
> testsuites/sptests/sptimecounter01/Makefile.am | 19 +++
> testsuites/sptests/sptimecounter01/init.c | 130 ++++++++++++++++
> .../sptests/sptimecounter01/sptimecounter01.doc | 11 ++
> .../sptests/sptimecounter01/sptimecounter01.scn | 0
> 10 files changed, 390 insertions(+), 3 deletions(-)
> create mode 100644 cpukit/score/include/rtems/score/timecounter.h
> create mode 100644 testsuites/sptests/sptimecounter01/Makefile.am
> create mode 100644 testsuites/sptests/sptimecounter01/init.c
> create mode 100644 testsuites/sptests/sptimecounter01/sptimecounter01.doc
> create mode 100644 testsuites/sptests/sptimecounter01/sptimecounter01.scn
>
> diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
> index 090f7f6..55fdc99 100644
> --- a/cpukit/score/Makefile.am
> +++ b/cpukit/score/Makefile.am
> @@ -5,6 +5,15 @@ SUBDIRS = cpu
>
> ## include
>
> +include_sysdir = $(includedir)/sys
> +
> +include_sys_HEADERS =
> +include_sys_HEADERS += include/sys/_ffcounter.h
> +include_sys_HEADERS += include/sys/timeffc.h
> +include_sys_HEADERS += include/sys/timepps.h
> +include_sys_HEADERS += include/sys/timetc.h
> +include_sys_HEADERS += include/sys/timex.h
> +
> include_rtemsdir = $(includedir)/rtems
>
> include_rtems_HEADERS = include/rtems/debug.h
> @@ -343,6 +352,7 @@ libscore_a_SOURCES += src/profilingisrentryexit.c
> libscore_a_SOURCES += src/once.c
> libscore_a_SOURCES += src/resourceiterate.c
> libscore_a_SOURCES += src/smpbarrierwait.c
> +libscore_a_SOURCES += src/kern_tc.c
>
> EXTRA_DIST = src/Unlimited.txt
>
> diff --git a/cpukit/score/include/rtems/score/timecounter.h b/cpukit/score/include/rtems/score/timecounter.h
> new file mode 100644
> index 0000000..3744a76
> --- /dev/null
> +++ b/cpukit/score/include/rtems/score/timecounter.h
This file needs doxygen.
> @@ -0,0 +1,23 @@
> +
> +#include <sys/time.h>
> +
> +void _Timecounter_Initialize(void);
> +
> +void _Timecounter_Set_clock(const struct timespec *ts);
> +
> +void _Timecounter_Ticktock(int cnt);
> +
> +void rtems_bintime(struct bintime *bt);
> +void rtems_nanotime(struct timespec *tsp);
> +void rtems_microtime(struct timeval *tvp);
> +void rtems_binuptime(struct bintime *bt);
> +void rtems_nanouptime(struct timespec *tsp);
> +void rtems_microuptime(struct timeval *tvp);
> +void rtems_getbintime(struct bintime *bt);
> +void rtems_getnanotime(struct timespec *tsp);
> +void rtems_getmicrotime(struct timeval *tvp);
> +void rtems_getbinuptime(struct bintime *bt);
> +void rtems_getnanouptime(struct timespec *tsp);
> +void rtems_getmicrouptime(struct timeval *tvp);
If these are "public-facing" they should be declared somewhere other
than score header file, maybe add timecounter API to the classic
"rtems" api. then this should be more like rtems_timecounter_bintime;
> +
> +
> diff --git a/cpukit/score/include/sys/timeffc.h b/cpukit/score/include/sys/timeffc.h
> index 3bda5d4..c3aed67 100644
> --- a/cpukit/score/include/sys/timeffc.h
> +++ b/cpukit/score/include/sys/timeffc.h
> @@ -55,11 +55,13 @@ struct ffclock_estimate {
> #if __BSD_VISIBLE
> #ifdef _KERNEL
>
> +#ifndef __rtems__
> /* Define the kern.sysclock sysctl tree. */
> SYSCTL_DECL(_kern_sysclock);
>
> /* Define the kern.sysclock.ffclock sysctl tree. */
> SYSCTL_DECL(_kern_sysclock_ffclock);
> +#endif /* __rtems__ */
>
> /*
> * Index into the sysclocks array for obtaining the ASCII name of a particular
> diff --git a/cpukit/score/include/sys/timetc.h b/cpukit/score/include/sys/timetc.h
> index e68e327..1fed542 100644
> --- a/cpukit/score/include/sys/timetc.h
> +++ b/cpukit/score/include/sys/timetc.h
> @@ -12,9 +12,11 @@
> #ifndef _SYS_TIMETC_H_
> #define _SYS_TIMETC_H_
>
> +#ifndef __rtems__
> #ifndef _KERNEL
> #error "no user-serviceable parts inside"
> #endif
> +#endif /* __rtems__ */
>
> /*-
> * `struct timecounter' is the interface between the hardware which implements
> diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
> index 920c0d9..75c8be6 100644
> --- a/cpukit/score/preinstall.am
> +++ b/cpukit/score/preinstall.am
> @@ -13,6 +13,31 @@ all-am: $(PREINSTALL_FILES)
> PREINSTALL_FILES =
> CLEANFILES = $(PREINSTALL_FILES)
>
> +$(PROJECT_INCLUDE)/sys/$(dirstamp):
> + @$(MKDIR_P) $(PROJECT_INCLUDE)/sys
> + @: > $(PROJECT_INCLUDE)/sys/$(dirstamp)
> +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/sys/$(dirstamp)
> +
> +$(PROJECT_INCLUDE)/sys/_ffcounter.h: include/sys/_ffcounter.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
> + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/_ffcounter.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/_ffcounter.h
> +
> +$(PROJECT_INCLUDE)/sys/timeffc.h: include/sys/timeffc.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
> + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timeffc.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timeffc.h
> +
> +$(PROJECT_INCLUDE)/sys/timepps.h: include/sys/timepps.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
> + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timepps.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timepps.h
> +
> +$(PROJECT_INCLUDE)/sys/timetc.h: include/sys/timetc.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
> + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timetc.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timetc.h
> +
> +$(PROJECT_INCLUDE)/sys/timex.h: include/sys/timex.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
> + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timex.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timex.h
> +
Not sure where all these headers come from.
> $(PROJECT_INCLUDE)/rtems/$(dirstamp):
> @$(MKDIR_P) $(PROJECT_INCLUDE)/rtems
> @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
> diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c
> index 1c29041..ba4396e 100644
> --- a/cpukit/score/src/kern_tc.c
> +++ b/cpukit/score/src/kern_tc.c
> @@ -13,6 +13,23 @@
> * of Melbourne under sponsorship from the FreeBSD Foundation.
> */
>
> +#ifdef __rtems__
> +#define _KERNEL
> +#define tc_init _Timecounter_Install
> +#define bintime _Timecounter_Bintime
> +#define nanotime _Timecounter_Nanotime
> +#define microtime _Timecounter_Microtime
> +#define binuptime _Timecounter_Binuptime
> +#define nanouptime _Timecounter_Nanouptime
> +#define microuptime _Timecounter_Microuptime
> +#define getbintime _Timecounter_Getbintime
> +#define getnanouptime _Timecounter_Getnanouptime
> +#define getmicrouptime _Timecounter_Getmicrouptime
> +#define getbinuptime _Timecounter_Getbinuptime
> +#define getnanouptime _Timecounter_Getnanouptime
> +#define getmicrouptime _Timecounter_Getmicrouptime
> +#include <rtems/score/timecounterimpl.h>
Where is this header?
> +#endif /* __rtems__ */
> #include <sys/cdefs.h>
> __FBSDID("$FreeBSD$");
>
> @@ -21,20 +38,50 @@ __FBSDID("$FreeBSD$");
> #include "opt_ffclock.h"
>
> #include <sys/param.h>
> +#ifndef __rtems__
> #include <sys/kernel.h>
> #include <sys/limits.h>
> +#else /* __rtems__ */
> +#include <limits.h>
> +#endif /* __rtems__ */
> #ifdef FFCLOCK
> #include <sys/lock.h>
> #include <sys/mutex.h>
> #endif
> +#ifndef __rtems__
> #include <sys/sysctl.h>
> #include <sys/syslog.h>
> #include <sys/systm.h>
> +#endif /* __rtems__ */
> #include <sys/timeffc.h>
> #include <sys/timepps.h>
> #include <sys/timetc.h>
> #include <sys/timex.h>
> +#ifndef __rtems__
> #include <sys/vdso.h>
> +#endif /* __rtems__ */
> +#ifdef __rtems__
> +#include <rtems.h>
> +ISR_LOCK_DEFINE(static, _Timecounter_Lock, "Timecounter");
> +#define hz rtems_clock_get_ticks_per_second()
> +#define bootverbose 0
> +#define printf(...)
> +#define log(...)
> +/* FIXME */
> +static inline int
> +fls(int x)
> +{
> + return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
> +}
> +/* FIXME */
> +static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); }
> +/* FIXME */
> +struct bintime tick_bt; /* bintime per tick (1s / hz) */
> +/* FIXME */
> +sbintime_t tick_sbt;
> +/* FIXME */
> +#define ntp_update_second(a, b) do { (void) a; (void) b; } while (0)
> +#endif /* __rtems__ */
>
> /*
> * A large step happens on boot. This constant detects such steps.
> @@ -76,6 +123,7 @@ struct timehands {
> struct timehands *th_next;
> };
>
> +#if defined(RTEMS_SMP)
> static struct timehands th0;
> static struct timehands th9 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th0};
> static struct timehands th8 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th9};
> @@ -86,6 +134,7 @@ static struct timehands th4 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th5};
> static struct timehands th3 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th4};
> static struct timehands th2 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th3};
> static struct timehands th1 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th2};
> +#endif
> static struct timehands th0 = {
> &dummy_timecounter,
> 0,
> @@ -95,7 +144,11 @@ static struct timehands th0 = {
> {0, 0},
> {0, 0},
> 1,
> +#if defined(RTEMS_SMP)
> &th1
> +#else
> + &th0
> +#endif
> };
>
> static struct timehands *volatile timehands = &th0;
> @@ -108,6 +161,7 @@ volatile time_t time_second = 1;
> volatile time_t time_uptime = 1;
>
> struct bintime boottimebin;
> +#ifndef __rtems__
> struct timeval boottime;
> static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS);
> SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, CTLTYPE_STRUCT|CTLFLAG_RD,
> @@ -119,6 +173,7 @@ static SYSCTL_NODE(_kern_timecounter, OID_AUTO, tc, CTLFLAG_RW, 0, "");
> static int timestepwarnings;
> SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW,
> ×tepwarnings, 0, "Log time steps");
> +#endif /* __rtems__ */
>
> struct bintime bt_timethreshold;
> struct bintime bt_tickthreshold;
> @@ -128,17 +183,22 @@ struct bintime tc_tick_bt;
> sbintime_t tc_tick_sbt;
> int tc_precexp;
> int tc_timepercentage = TC_DEFAULTPERC;
> +#ifndef __rtems__
> static int sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS);
> SYSCTL_PROC(_kern_timecounter, OID_AUTO, alloweddeviation,
> CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 0, 0,
> sysctl_kern_timecounter_adjprecision, "I",
> "Allowed time interval deviation in percents");
> +#endif /* __rtems__ */
>
> static void tc_windup(void);
> +#ifndef __rtems__
> static void cpu_tick_calibrate(int);
> +#endif /* __rtems__ */
>
> void dtrace_getnanotime(struct timespec *tsp);
>
> +#ifndef __rtems__
> static int
> sysctl_kern_boottime(SYSCTL_HANDLER_ARGS)
> {
> @@ -175,6 +235,7 @@ sysctl_kern_timecounter_freq(SYSCTL_HANDLER_ARGS)
> freq = tc->tc_frequency;
> return sysctl_handle_64(oidp, &freq, 0, req);
> }
> +#endif /* __rtems__ */
>
> /*
> * Return the difference between the timehands' counter value now and what
> @@ -994,16 +1055,19 @@ dtrace_getnanotime(struct timespec *tsp)
> } while (gen == 0 || gen != th->th_generation);
> }
>
> +#ifdef FFCLOCK
> /*
> * System clock currently providing time to the system. Modifiable via sysctl
> * when the FFCLOCK option is defined.
> */
> int sysclock_active = SYSCLOCK_FBCK;
> +#endif
>
> /* Internal NTP status and error estimates. */
> extern int time_status;
> extern long time_esterror;
>
> +#ifndef __rtems__
> /*
> * Take a snapshot of sysclock data which can be used to compare system clocks
> * and generate timestamps after the fact.
> @@ -1046,7 +1110,9 @@ sysclock_getsnapshot(struct sysclock_snap *clock_snap, int fast)
> } while (gen == 0 || gen != th->th_generation);
>
> clock_snap->delta = delta;
> +#ifdef FFCLOCK
> clock_snap->sysclock_active = sysclock_active;
> +#endif
>
> /* Record feedback clock status and error. */
> clock_snap->fb_info.status = time_status;
> @@ -1133,6 +1199,7 @@ sysclock_snap2bintime(struct sysclock_snap *cs, struct bintime *bt,
>
> return (0);
> }
> +#endif /* __rtems__ */
>
> /*
> * Initialize a new timecounter and possibly use it.
> @@ -1140,9 +1207,11 @@ sysclock_snap2bintime(struct sysclock_snap *cs, struct bintime *bt,
> void
> tc_init(struct timecounter *tc)
> {
> - u_int u;
> +// u_int u;
> +#ifndef __rtems__
> struct sysctl_oid *tc_root;
> -
> +#endif /* __rtems__ */
> +#if 0
> u = tc->tc_frequency / tc->tc_counter_mask;
> /* XXX: We need some margin here, 10% is a guess */
> u *= 11;
> @@ -1159,9 +1228,10 @@ tc_init(struct timecounter *tc)
> tc->tc_name, (uintmax_t)tc->tc_frequency,
> tc->tc_quality);
> }
> -
> +#endif
> tc->tc_next = timecounters;
> timecounters = tc;
> +#ifndef __rtems__
> /*
> * Set up sysctl tree for this counter.
> */
> @@ -1180,11 +1250,13 @@ tc_init(struct timecounter *tc)
> SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO,
> "quality", CTLFLAG_RD, &(tc->tc_quality), 0,
> "goodness of time counter");
> +#endif /* __rtems__ */
> /*
> * Never automatically use a timecounter with negative quality.
> * Even though we run on the dummy counter, switching here may be
> * worse since this timecounter may not be monotonous.
> */
> +#if 0
> if (tc->tc_quality < 0)
> return;
> if (tc->tc_quality < timecounter->tc_quality)
> @@ -1192,9 +1264,13 @@ tc_init(struct timecounter *tc)
> if (tc->tc_quality == timecounter->tc_quality &&
> tc->tc_frequency < timecounter->tc_frequency)
> return;
> +#endif
> (void)tc->tc_get_timecount(tc);
> (void)tc->tc_get_timecount(tc);
> timecounter = tc;
> +#ifdef __rtems__
> + tc_windup();
> +#endif /* __rtems__ */
> }
>
> /* Report the frequency of the current timecounter. */
> @@ -1210,23 +1286,36 @@ tc_getfrequency(void)
> * when we booted.
> * XXX: not locked.
> */
> +
> +#ifndef __rtems__
> void
> tc_setclock(struct timespec *ts)
> +#else /* __rtems__ */
> +void
> +_Timecounter_Set_clock(const struct timespec *ts)
> +#endif /* __rtems__ */
> {
> +#ifndef __rtems__
> struct timespec tbef, taft;
> +#endif /* __rtems__ */
> struct bintime bt, bt2;
>
> +#ifndef __rtems__
> cpu_tick_calibrate(1);
> nanotime(&tbef);
> +#endif /* __rtems__ */
> timespec2bintime(ts, &bt);
> binuptime(&bt2);
> bintime_sub(&bt, &bt2);
> bintime_add(&bt2, &boottimebin);
> boottimebin = bt;
> +#ifndef __rtems__
> bintime2timeval(&bt, &boottime);
> +#endif /* __rtems__ */
>
> /* XXX fiddle all the little crinkly bits around the fiords... */
> tc_windup();
> +#ifndef __rtems__
> nanotime(&taft);
> if (timestepwarnings) {
> log(LOG_INFO,
> @@ -1236,6 +1325,7 @@ tc_setclock(struct timespec *ts)
> (intmax_t)ts->tv_sec, ts->tv_nsec);
> }
> cpu_tick_calibrate(1);
> +#endif /* __rtems__ */
> }
>
> /*
> @@ -1243,6 +1333,7 @@ tc_setclock(struct timespec *ts)
> * it the active timehands. Along the way we might switch to a different
> * timecounter and/or do seconds processing in NTP. Slightly magic.
> */
> +
> static void
> tc_windup(void)
> {
> @@ -1252,6 +1343,11 @@ tc_windup(void)
> u_int delta, ncount, ogen;
> int i;
> time_t t;
> +#ifdef __rtems__
> + ISR_lock_Context lock_context;
> +
> + _ISR_lock_ISR_disable_and_acquire(_Timecounter_Lock, &lock_context);
> +#endif /* __rtems__ */
>
> /*
> * Make the next timehands a copy of the current one, but do not
> @@ -1329,12 +1425,14 @@ tc_windup(void)
>
> /* Now is a good time to change timecounters. */
> if (th->th_counter != timecounter) {
> +#ifndef __rtems__
> #ifndef __arm__
> if ((timecounter->tc_flags & TC_FLAGS_C2STOP) != 0)
> cpu_disable_c2_sleep++;
> if ((th->th_counter->tc_flags & TC_FLAGS_C2STOP) != 0)
> cpu_disable_c2_sleep--;
> #endif
> +#endif /* __rtems__ */
> th->th_counter = timecounter;
> th->th_offset_count = ncount;
> tc_min_ticktock_freq = max(1, timecounter->tc_frequency /
> @@ -1397,9 +1495,17 @@ tc_windup(void)
> #endif
>
> timehands = th;
> +#ifndef __rtems__
> timekeep_push_vdso();
> +#endif /* __rtems__ */
> +#ifdef __rtems__
> + _ISR_lock_Release_and_ISR_enable(_Timecounter_Lock, &lock_context);
> +#endif /* __rtems__ */
> }
>
> +
> +
> +#ifndef __rtems__
> /* Report or change the active timecounter hardware. */
> static int
> sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS)
> @@ -1464,7 +1570,9 @@ sysctl_kern_timecounter_choice(SYSCTL_HANDLER_ARGS)
>
> SYSCTL_PROC(_kern_timecounter, OID_AUTO, choice, CTLTYPE_STRING | CTLFLAG_RD,
> 0, 0, sysctl_kern_timecounter_choice, "A", "Timecounter hardware detected");
> +#endif /* __rtems__ */
>
> +#ifndef __rtems__
> /*
> * RFC 2783 PPS-API implementation.
> */
> @@ -1745,6 +1853,7 @@ pps_event(struct pps_state *pps, int event)
> /* Wakeup anyone sleeping in pps_fetch(). */
> wakeup(pps);
> }
> +#endif /* __rtems__ */
>
> /*
> * Timecounters need to be updated every so often to prevent the hardware
> @@ -1754,12 +1863,21 @@ pps_event(struct pps_state *pps, int event)
> */
>
> static int tc_tick;
> +#ifndef __rtems__
> SYSCTL_INT(_kern_timecounter, OID_AUTO, tick, CTLFLAG_RD, &tc_tick, 0,
> "Approximate number of hardclock ticks in a millisecond");
> +#endif /* __rtems__ */
>
> +#ifndef __rtems__
> void
> tc_ticktock(int cnt)
> {
> +#else /* __rtems__ */
> +void
> +_Timecounter_Tick(void)
> +{
> + int cnt = 1;
> +#endif /* __rtems__ */
> static int count;
>
> count += cnt;
> @@ -1768,6 +1886,37 @@ tc_ticktock(int cnt)
> count = 0;
> tc_windup();
> }
> +#ifdef __rtems__
> +void
> +_Timecounter_Tick_simple(u_int delta, u_int offset)
> +{
> + struct timehands *th;
> + u_int ogen;
> + ISR_lock_Context lock_context;
> +
> + _ISR_lock_ISR_disable_and_acquire(_Timecounter_Lock, &lock_context);
> +
> + th = timehands;
> + ogen = th->th_generation;
> + th->th_offset_count = offset;
> + bintime_addx(&th->th_offset, th->th_scale * delta);
> +
> + /* Update the UTC timestamps used by the get*() functions. */
> + /* XXX shouldn't do this here. Should force non-`get' versions. */
> + bintime2timeval(&th->th_offset, &th->th_microtime);
> + bintime2timespec(&th->th_offset, &th->th_nanotime);
> +
> + /*
> + * Now that the struct timehands is again consistent, set the new
> + * generation number, making sure to not make it zero.
> + */
> + if (++ogen == 0)
> + ogen = 1;
> + th->th_generation = ogen;
> +
> + _ISR_lock_Release_and_ISR_enable(_Timecounter_Lock, &lock_context);
> +}
> +#endif /* __rtems__ */
>
> static void __inline
> tc_adjprecision(void)
> @@ -1791,6 +1940,7 @@ tc_adjprecision(void)
> sbt_tickthreshold = bttosbt(bt_tickthreshold);
> }
>
> +#ifndef __rtems__
> static int
> sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS)
> {
> @@ -1807,9 +1957,15 @@ sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS)
> done:
> return (0);
> }
> +#endif /* __rtems__ */
>
> +#ifndef __rtems__
> static void
> inittimecounter(void *dummy)
> +#else /* __rtems__ */
> +void
> +_Timecounter_Initialize(void)
> +#endif /* __rtems__ */
> {
> u_int p;
> int tick_rate;
> @@ -1834,6 +1990,9 @@ inittimecounter(void *dummy)
> tc_tick_sbt = bttosbt(tc_tick_bt);
> p = (tc_tick * 1000000) / hz;
> printf("Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000);
> +#ifdef __rtems__
> + (void) p;
> +#endif /* __rtems__ */
>
> #ifdef FFCLOCK
> ffclock_init();
> @@ -1844,8 +2003,11 @@ inittimecounter(void *dummy)
> tc_windup();
> }
>
> +#ifndef __rtems__
> SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_SECOND, inittimecounter, NULL);
> +#endif /* __rtems__ */
>
> +#ifndef __rtems__
> /* Cpu tick handling -------------------------------------------------*/
>
> static int cpu_tick_variable;
> @@ -1978,7 +2140,9 @@ cputick2usec(uint64_t tick)
> }
>
> cpu_tick_f *cpu_ticks = tc_cpu_ticks;
> +#endif /* __rtems__ */
>
> +#ifndef __rtems__
> static int vdso_th_enable = 1;
> static int
> sysctl_fast_gettime(SYSCTL_HANDLER_ARGS)
> @@ -2014,6 +2178,7 @@ tc_fill_vdso_timehands(struct vdso_timehands *vdso_th)
> enabled = 0;
> return (enabled);
> }
> +#endif /* __rtems__ */
>
> #ifdef COMPAT_FREEBSD32
> uint32_t
> diff --git a/testsuites/sptests/sptimecounter01/Makefile.am b/testsuites/sptests/sptimecounter01/Makefile.am
> new file mode 100644
> index 0000000..b231088
> --- /dev/null
> +++ b/testsuites/sptests/sptimecounter01/Makefile.am
> @@ -0,0 +1,19 @@
> +rtems_tests_PROGRAMS = sptimecounter01
> +sptimecounter01_SOURCES = init.c
> +
> +dist_rtems_tests_DATA = sptimecounter01.scn sptimecounter01.doc
> +
> +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
> +include $(top_srcdir)/../automake/compile.am
> +include $(top_srcdir)/../automake/leaf.am
> +
> +AM_CPPFLAGS += -I$(top_srcdir)/../support/include
> +
> +LINK_OBJS = $(sptimecounter01_OBJECTS)
> +LINK_LIBS = $(sptimecounter01_LDLIBS)
> +
> +sptimecounter01$(EXEEXT): $(sptimecounter01_OBJECTS) $(sptimecounter01_DEPENDENCIES)
> + @rm -f sptimecounter01$(EXEEXT)
> + $(make-exe)
> +
> +include $(top_srcdir)/../automake/local.am
> diff --git a/testsuites/sptests/sptimecounter01/init.c b/testsuites/sptests/sptimecounter01/init.c
> new file mode 100644
> index 0000000..e698761
> --- /dev/null
> +++ b/testsuites/sptests/sptimecounter01/init.c
> @@ -0,0 +1,130 @@
> +/*
> + * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
> + *
> + * embedded brains GmbH
> + * Dornierstr. 4
> + * 82178 Puchheim
> + * Germany
> + * <rtems at embedded-brains.de>
> + *
> + * The license and distribution terms for this file may be
> + * found in the file LICENSE in this distribution or at
> + * http://www.rtems.org/license/LICENSE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> + #include "config.h"
> +#endif
> +
> +#include <assert.h>
> +
> +#include <bsp/bootcard.h>
> +
> +#include <rtems/test.h>
> +
> +#include <rtems/score/timecounterimpl.h>
> +#include <rtems/timecounter.h>
> +
> +const char rtems_test_name[] = "SPTIMECOUNTER_1";
> +
> +typedef struct {
> + struct timecounter tc_soft;
> + u_int tc_soft_counter;
> +} test_context;
> +
> +static test_context test_instance;
> +
> +static u_int test_get_timecount_soft(struct timecounter *tc)
> +{
> + test_context *ctx = tc->tc_priv;
> +
> + ++ctx->tc_soft_counter;
> +
> + return ctx->tc_soft_counter;
> +}
> +
> +void boot_card(const char *cmdline)
> +{
> + test_context *ctx = &test_instance;
> + struct timecounter *tc_soft = &ctx->tc_soft;
> + uint64_t soft_freq = 1000000;
> + struct bintime bt;
> +
> + rtems_test_begink();
> +
> + _Timecounter_Initialize();
> +
> + rtems_binuptime(&bt);
> + assert(bt.sec == 1);
> + assert(bt.frac== 73786976294835);
> +
> + rtems_binuptime(&bt);
> + assert(bt.sec == 1);
> + assert(bt.frac == 92233720368543);
> +
> + _Timecounter_Tick();
> + rtems_binuptime(&bt);
> + assert(bt.sec == 1);
> + assert(bt.frac == 129127208515959);
> +
> + ctx->tc_soft_counter = 0;
> + tc_soft->tc_get_timecount = test_get_timecount_soft;
> + tc_soft->tc_counter_mask = 0x0fffffff;
> + tc_soft->tc_frequency = soft_freq;
> + tc_soft->tc_quality = 1234;
> + tc_soft->tc_priv = ctx;
> + _Timecounter_Install(tc_soft);
> + assert(ctx->tc_soft_counter == 3);
> +
> + rtems_binuptime(&bt);
> + assert(ctx->tc_soft_counter == 4);
> +
> + assert(bt.sec == 1);
> + assert(bt.frac == 166020696663375);
> +
> + ctx->tc_soft_counter = 0xf0000000 | 3;
> + rtems_binuptime(&bt);
> + assert(ctx->tc_soft_counter == (0xf0000000 | 4));
> +
> + assert(bt.sec == 1);
> + assert(bt.frac == 166020696663375);
> +
> + /* Ensure that the fraction overflows and the second remains constant */
> + ctx->tc_soft_counter = (0xf0000000 | 3) + soft_freq;
> + rtems_binuptime(&bt);
> + assert(ctx->tc_soft_counter == (0xf0000000 | 4) + soft_freq);
> + assert(bt.sec == 1);
> + assert(bt.frac == 166020695111759);
> +
> + rtems_test_endk();
> +
> + _Terminate(RTEMS_FATAL_SOURCE_EXIT, false, 0);
> +}
> +
> +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
> +
> +#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
> +
> +#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
> +
> +#define CONFIGURE_SCHEDULER_USER
> +
> +#define CONFIGURE_SCHEDULER_CONTEXT
> +
> +#define CONFIGURE_SCHEDULER_CONTROLS { }
> +
> +#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER 0
> +
> +#define CONFIGURE_TASK_STACK_ALLOCATOR NULL
> +
> +#define CONFIGURE_TASK_STACK_DEALLOCATOR NULL
> +
> +#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
> +
> +#define CONFIGURE_IDLE_TASK_BODY NULL
> +
> +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
> +
> +#define CONFIGURE_INIT
> +
> +#include <rtems/confdefs.h>
> diff --git a/testsuites/sptests/sptimecounter01/sptimecounter01.doc b/testsuites/sptests/sptimecounter01/sptimecounter01.doc
> new file mode 100644
> index 0000000..3568f72
> --- /dev/null
> +++ b/testsuites/sptests/sptimecounter01/sptimecounter01.doc
> @@ -0,0 +1,11 @@
> +This file describes the directives and concepts tested by this test set.
> +
> +test set name: sptimecounter01
> +
> +directives:
> +
> + TBD
> +
> +concepts:
> +
> + TBD
Fix the test doc and scn files
> diff --git a/testsuites/sptests/sptimecounter01/sptimecounter01.scn b/testsuites/sptests/sptimecounter01/sptimecounter01.scn
> new file mode 100644
> index 0000000..e69de29
> --
> 1.8.4.5
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
More information about the devel
mailing list