[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,
>      &timestepwarnings, 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