You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/02/15 13:07:42 UTC

[incubator-nuttx] branch pr274 updated (db4e2db -> 3332ec3)

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a change to branch pr274
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from db4e2db  Update NuttxPortingGuide.html
     new aa71d52  Make compare_timespec public so timer driver could reuse it
     new 8fd53e4  Reimplement arch alarm timer on top of oneshot driver framework
     new 3332ec3  arch/sim: Implement arch rtc interface on top of rtc driver

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/Kconfig                                       |   3 +
 arch/sim/src/Makefile                              |  14 +-
 arch/sim/src/nuttx-names.dat                       |   1 +
 arch/sim/src/sim/up_critmon.c                      | 114 -------
 .../src/kl_led.c => arch/sim/src/sim/up_hosttime.c |  66 ++--
 arch/sim/src/sim/up_hostusleep.c                   |  53 ---
 arch/sim/src/sim/up_idle.c                         |  48 +--
 arch/sim/src/sim/up_initialize.c                   |  13 -
 arch/sim/src/sim/up_internal.h                     |  10 +-
 arch/sim/src/sim/up_oneshot.c                      | 159 ++++++---
 arch/sim/src/sim/up_rtc.c                          | 127 ++++++++
 arch/sim/src/sim/up_tickless.c                     | 355 ---------------------
 drivers/timers/arch_alarm.c                        |  15 +-
 include/nuttx/clock.h                              |  13 +
 sched/clock/clock_abstime2ticks.c                  |  16 +-
 15 files changed, 326 insertions(+), 681 deletions(-)
 delete mode 100644 arch/sim/src/sim/up_critmon.c
 copy boards/arm/kl/teensy-lc/src/kl_led.c => arch/sim/src/sim/up_hosttime.c (76%)
 delete mode 100644 arch/sim/src/sim/up_hostusleep.c
 create mode 100644 arch/sim/src/sim/up_rtc.c
 delete mode 100644 arch/sim/src/sim/up_tickless.c


[incubator-nuttx] 02/03: Reimplement arch alarm timer on top of oneshot driver framework

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch pr274
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 8fd53e454a66e6e0bab8cf97e9de5363578c637f
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Thu Feb 6 22:45:05 2020 +0800

    Reimplement arch alarm timer on top of oneshot driver framework
    
    The benefit include:
    1.Simplify the implementation
    2.Support both tick and tickless automatically
    3.No time drift in tickless mode
    4.Support critmon arch API automatically
    
    Change-Id: Ie387319f99d5c5b863093ac540e86e4f6f41932e
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 arch/Kconfig                                       |   2 +
 arch/sim/src/Makefile                              |  10 +-
 arch/sim/src/sim/up_critmon.c                      | 114 -------
 .../sim/src/sim/{up_hostusleep.c => up_hosttime.c} |  49 ++-
 arch/sim/src/sim/up_idle.c                         |  48 +--
 arch/sim/src/sim/up_initialize.c                   |  13 -
 arch/sim/src/sim/up_internal.h                     |  10 +-
 arch/sim/src/sim/up_oneshot.c                      | 159 ++++++---
 arch/sim/src/sim/up_tickless.c                     | 355 ---------------------
 9 files changed, 187 insertions(+), 573 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 92a7d29..ce5bac9 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -72,6 +72,8 @@ config ARCH_SIM
 	select ARCH_HAVE_POWEROFF
 	select ARCH_HAVE_TESTSET
 	select ARCH_NOINTC
+	select ALARM_ARCH
+	select ONESHOT
 	select SERIAL_CONSOLE
 	---help---
 		Linux/Cywgin user-mode simulation.
diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile
index 96a7078..5204949 100644
--- a/arch/sim/src/Makefile
+++ b/arch/sim/src/Makefile
@@ -74,16 +74,12 @@ CSRCS += up_allocateheap.c
 VPATH = sim
 DEPPATH = $(patsubst %,--dep-path %,$(subst :, ,$(VPATH)))
 
-HOSTSRCS = up_hostusleep.c
+HOSTSRCS = up_hosttime.c
 
 ifeq ($(CONFIG_STACK_COLORATION),y)
   CSRCS += up_checkstack.c
 endif
 
-ifeq ($(CONFIG_SCHED_TICKLESS),y)
-  CSRCS += up_tickless.c
-endif
-
 ifeq ($(CONFIG_SPINLOCK),y)
   HOSTSRCS += up_testset.c
 endif
@@ -113,10 +109,6 @@ ifeq ($(CONFIG_ONESHOT),y)
   CSRCS += up_oneshot.c
 endif
 
-ifeq ($(CONFIG_SCHED_CRITMONITOR),y)
-  HOSTSRCS += up_critmon.c
-endif
-
 ifeq ($(CONFIG_NX_LCDDRIVER),y)
   CSRCS += up_lcd.c
 else
diff --git a/arch/sim/src/sim/up_critmon.c b/arch/sim/src/sim/up_critmon.c
deleted file mode 100644
index 15671f2..0000000
--- a/arch/sim/src/sim/up_critmon.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/************************************************************************************
- * arch/sim/src/sim/up_critmon.c
- *
- *   Copyright (C) 2018 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ************************************************************************************/
-
-/************************************************************************************
- * Included Files
- ************************************************************************************/
-
-#include <stdint.h>
-#include <time.h>
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-#undef USE_CLOCK                                   /* Too slow */
-#define USE_CLOCK_GETTIME 1                        /* Better */
-
-/* From nuttx/clock.h */
-
-#define NSEC_PER_SEC  1000000000
-
-/* From fixedmath.h */
-
-#define b32ONE        0x0000000100000000           /* 1 */
-#define b32toi(a)     ((a) >> 32)                  /* Conversion to integer */
-#define itob32(i)     (((b32_t)(i)) << 32)         /* Conversion from integer */
-#define b32frac(a)    ((a) & 0x00000000ffffffff)   /* Take fractional part */
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-/* From fixedmath.h */
-
-typedef int64_t b32_t;
-
-/************************************************************************************
- * Private Data
- ************************************************************************************/
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: up_critmon_gettime
- ************************************************************************************/
-
-#if defined(USE_CLOCK)
-uint32_t up_critmon_gettime(void)
-{
-  return (uint32_t)clock() + 1;  /* Avoid returning zero which means clock-not-ready */
-}
-#else /* USE_CLOCK_GETTIME */
-uint32_t up_critmon_gettime(void)
-{
-  struct timespec ts;
-  clock_gettime(CLOCK_MONOTONIC, &ts);
-  return (uint32_t)ts.tv_nsec;
-}
-#endif
-
-/************************************************************************************
- * Name: up_critmon_gettime
- ************************************************************************************/
-
-#if defined(USE_CLOCK)
-void up_critmon_convert(uint32_t elapsed, struct timespec *ts)
-{
-  b32_t b32elapsed;
-
-  b32elapsed  = itob32(elapsed) / CLOCKS_PER_SEC;
-  ts->tv_sec  = b32toi(b32elapsed);
-  ts->tv_nsec = NSEC_PER_SEC * b32frac(b32elapsed) / b32ONE;
-}
-#else /* USE_CLOCK_GETTIME */
-void up_critmon_convert(uint32_t elapsed, struct timespec *ts)
-{
-  ts->tv_sec  = 0;
-  ts->tv_nsec = elapsed;
-}
-#endif
diff --git a/arch/sim/src/sim/up_hostusleep.c b/arch/sim/src/sim/up_hosttime.c
similarity index 67%
rename from arch/sim/src/sim/up_hostusleep.c
rename to arch/sim/src/sim/up_hosttime.c
index a36e83e..cf2be0b 100644
--- a/arch/sim/src/sim/up_hostusleep.c
+++ b/arch/sim/src/sim/up_hosttime.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/sim/src/sim/up_hostusleep.c
+ * arch/sim/src/sim/up_hosttime.c
  *
  *   Copyright (C) 2008 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
@@ -37,6 +37,9 @@
  * Included Files
  ****************************************************************************/
 
+#include <stdbool.h>
+#include <stdint.h>
+#include <time.h>
 #include <unistd.h>
 
 /****************************************************************************
@@ -44,10 +47,48 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_hostusleep
+ * Name: host_gettime
  ****************************************************************************/
 
-int up_hostusleep(unsigned int usec)
+uint64_t host_gettime(bool rtc)
 {
-  return usleep(usec);
+  struct timespec tp;
+
+  clock_gettime(rtc ? CLOCK_REALTIME : CLOCK_MONOTONIC, &tp);
+  return 1000000000ull * tp.tv_sec + tp.tv_nsec;
+}
+
+/****************************************************************************
+ * Name: host_settime
+ ****************************************************************************/
+
+void host_settime(bool rtc, uint64_t nsec)
+{
+  struct timespec tp;
+
+  tp.tv_sec  = nsec / 1000000000;
+  tp.tv_nsec = nsec - 1000000000 * tp.tv_sec;
+  clock_settime(rtc ? CLOCK_REALTIME : CLOCK_MONOTONIC, &tp);
+}
+
+/****************************************************************************
+ * Name: host_sleepuntil
+ ****************************************************************************/
+
+void host_sleepuntil(uint64_t nsec)
+{
+  static uint64_t base;
+  uint64_t now;
+
+  now = host_gettime(false);
+  if (base == 0)
+    {
+      base = now;
+    }
+  now -= base;
+
+  if (nsec > now + 1000)
+    {
+      usleep((nsec - now) / 1000);
+    }
 }
diff --git a/arch/sim/src/sim/up_idle.c b/arch/sim/src/sim/up_idle.c
index 27bfa7e..64cf774 100644
--- a/arch/sim/src/sim/up_idle.c
+++ b/arch/sim/src/sim/up_idle.c
@@ -72,16 +72,21 @@
 
 void up_idle(void)
 {
-#ifdef CONFIG_SCHED_TICKLESS
-  /* Driver the simulated interval timer */
+#ifdef CONFIG_PM
+  static enum pm_state_e state = PM_NORMAL;
+  enum pm_state_e newstate;
 
-  up_timer_update();
-#else
-  /* If the system is idle, then process "fake" timer interrupts.
-   * Hopefully, something will wake up.
-   */
+  /* Fake some power management stuff for testing purposes */
 
-  nxsched_process_timer();
+  newstate = pm_checkstate(PM_IDLE_DOMAIN);
+  if (newstate != state)
+    {
+      if (pm_changestate(PM_IDLE_DOMAIN, newstate) == OK)
+        {
+          state = newstate;
+          pwrinfo("IDLE: switching to new state %i\n", state);
+        }
+    }
 #endif
 
 #ifdef USE_DEVCONSOLE
@@ -106,30 +111,9 @@ void up_idle(void)
   up_rptun_loop();
 #endif
 
-#ifdef CONFIG_PM
-  /* Fake some power management stuff for testing purposes */
-
-  {
-    static enum pm_state_e state = PM_NORMAL;
-    enum pm_state_e newstate;
-
-    newstate = pm_checkstate(PM_IDLE_DOMAIN);
-    if (newstate != state)
-      {
-        if (pm_changestate(PM_IDLE_DOMAIN, newstate) == OK)
-          {
-            state = newstate;
-            pwrinfo("IDLE: switching to new state %i\n", state);
-          }
-      }
-  }
-#endif
-
-#ifdef CONFIG_SIM_WALLTIME
-  /* Wait a bit so that the nxsched_process_timer() is called close to the
-   * correct rate.
-   */
+#ifdef CONFIG_ONESHOT
+  /* Driver the simulated interval timer */
 
-  up_hostusleep(1000000 / CLK_TCK);
+  up_timer_update();
 #endif
 }
diff --git a/arch/sim/src/sim/up_initialize.c b/arch/sim/src/sim/up_initialize.c
index a967e71..bbd1122 100644
--- a/arch/sim/src/sim/up_initialize.c
+++ b/arch/sim/src/sim/up_initialize.c
@@ -296,16 +296,3 @@ void up_initialize(void)
   up_init_smartfs();
 #endif
 }
-
-/****************************************************************************
- * Function:  up_timer_initialize
- *
- * Description:
- *   This function is called during start-up to initialize
- *   the timer hardware.
- *
- ****************************************************************************/
-
-void up_timer_initialize(void)
-{
-}
diff --git a/arch/sim/src/sim/up_internal.h b/arch/sim/src/sim/up_internal.h
index a7fd589..660d80f 100644
--- a/arch/sim/src/sim/up_internal.h
+++ b/arch/sim/src/sim/up_internal.h
@@ -225,9 +225,11 @@ volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS] SP_SECTION;
 int  up_setjmp(xcpt_reg_t *jb);
 void up_longjmp(xcpt_reg_t *jb, int val) noreturn_function;
 
-/* up_hostusleep.c **********************************************************/
+/* up_hosttime.c ************************************************************/
 
-int up_hostusleep(unsigned int usec);
+uint64_t host_gettime(bool rtc);
+void host_settime(bool rtc, uint64_t nsec);
+void host_sleepuntil(uint64_t nsec);
 
 /* up_simsmp.c **************************************************************/
 
@@ -241,9 +243,9 @@ void sim_cpu0_start(void);
 void up_cpu_started(void);
 #endif
 
-/* up_tickless.c ************************************************************/
+/* up_oneshot.c *************************************************************/
 
-#ifdef CONFIG_SCHED_TICKLESS
+#ifdef CONFIG_ONESHOT
 void up_timer_update(void);
 #endif
 
diff --git a/arch/sim/src/sim/up_oneshot.c b/arch/sim/src/sim/up_oneshot.c
index 9beef16..1c31ea1 100644
--- a/arch/sim/src/sim/up_oneshot.c
+++ b/arch/sim/src/sim/up_oneshot.c
@@ -39,16 +39,20 @@
 
 #include <nuttx/config.h>
 
-#include <stdint.h>
-#include <time.h>
 #include <limits.h>
 #include <assert.h>
 #include <errno.h>
 #include <debug.h>
+#include <queue.h>
 
-#include <nuttx/wdog.h>
+#include <nuttx/nuttx.h>
+#include <nuttx/arch.h>
+#include <nuttx/clock.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/timers/oneshot.h>
+#include <nuttx/timers/arch_alarm.h>
+
+#include "up_internal.h"
 
 /****************************************************************************
  * Private Types
@@ -68,7 +72,9 @@ struct sim_oneshot_lowerhalf_s
 
   /* Private lower half data follows */
 
-  WDOG_ID wdog;                   /* Simulates oneshot timer */
+  sq_entry_t link;
+  struct timespec alarm;
+
   oneshot_callback_t callback;    /* internal handler that receives callback */
   FAR void *arg;                  /* Argument that is passed to the handler */
 };
@@ -77,7 +83,7 @@ struct sim_oneshot_lowerhalf_s
  * Private Function Prototypes
  ****************************************************************************/
 
-static void sim_oneshot_handler(int argc, wdparm_t arg1, ...);
+static void sim_process_tick(sq_entry_t *entry);
 
 static int sim_max_delay(FAR struct oneshot_lowerhalf_s *lower,
                          FAR struct timespec *ts);
@@ -86,11 +92,16 @@ static int sim_start(FAR struct oneshot_lowerhalf_s *lower,
                      FAR const struct timespec *ts);
 static int sim_cancel(FAR struct oneshot_lowerhalf_s *lower,
                       FAR struct timespec *ts);
+static int sim_current(FAR struct oneshot_lowerhalf_s *lower,
+                       FAR struct timespec *ts);
 
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
+static struct timespec g_current;
+static sq_queue_t g_oneshot_list;
+
 /* Lower half operations */
 
 static const struct oneshot_operations_s g_oneshot_ops =
@@ -98,6 +109,7 @@ static const struct oneshot_operations_s g_oneshot_ops =
   .max_delay = sim_max_delay,
   .start     = sim_start,
   .cancel    = sim_cancel,
+  .current   = sim_current,
 };
 
 /****************************************************************************
@@ -105,35 +117,35 @@ static const struct oneshot_operations_s g_oneshot_ops =
  ****************************************************************************/
 
 /****************************************************************************
- * Name: sim_oneshot_handler
+ * Name: sim_process_tick
  *
  * Description:
  *   Timer expiration handler
  *
  * Input Parameters:
- *   arg - Should be the same argument provided when sim_oneshot_start()
- *         was called.
+ *   entry - Point to the link field of sim_oneshot_lowerhalf_s.
  *
  * Returned Value:
  *   None
  *
  ****************************************************************************/
 
-static void sim_oneshot_handler(int argc, wdparm_t arg1, ...)
+static void sim_process_tick(sq_entry_t *entry)
 {
   FAR struct sim_oneshot_lowerhalf_s *priv =
-    (FAR struct sim_oneshot_lowerhalf_s *)arg1;
+    container_of(entry, struct sim_oneshot_lowerhalf_s, link);
   oneshot_callback_t callback;
   FAR void *cbarg;
 
-  DEBUGASSERT(argc == 1 && priv != NULL);
-
-  /* Perhaps the callback was nullified in a race condition with
-   * sim_cancel?
-   */
+  DEBUGASSERT(priv != NULL);
 
   if (priv->callback)
     {
+      if (clock_timespec_compare(&priv->alarm, &g_current) > 0)
+        {
+          return; /* Alarm doesn't expire yet */
+        }
+
       /* Sample and nullify BEFORE executing callback (in case the callback
        * restarts the oneshot).
        */
@@ -153,7 +165,7 @@ static void sim_oneshot_handler(int argc, wdparm_t arg1, ...)
  * Name: sim_max_delay
  *
  * Description:
- *   Determine the maximum delay of the one-shot timer (in microseconds)
+ *   Determine the maximum delay of the one-shot timer
  *
  * Input Parameters:
  *   lower   An instance of the lower-half oneshot state structure.  This
@@ -172,8 +184,8 @@ static int sim_max_delay(FAR struct oneshot_lowerhalf_s *lower,
 {
   DEBUGASSERT(lower != NULL && ts != NULL);
 
-  ts->tv_sec  = INT_MAX;
-  ts->tv_nsec = 1000000000ul - 1;
+  ts->tv_sec  = UINT_MAX;
+  ts->tv_nsec = NSEC_PER_SEC - 1;
   return OK;
 }
 
@@ -203,24 +215,15 @@ static int sim_start(FAR struct oneshot_lowerhalf_s *lower,
 {
   FAR struct sim_oneshot_lowerhalf_s *priv =
     (FAR struct sim_oneshot_lowerhalf_s *)lower;
-  clock_t ticks;
-  int64_t nsec;
 
   DEBUGASSERT(priv != NULL && callback != NULL && ts != NULL);
 
-  /* Convert time to ticks */
-
-  nsec = (int64_t)ts->tv_sec * NSEC_PER_SEC +
-         (int64_t)ts->tv_nsec;
-  ticks = (clock_t)((nsec + NSEC_PER_TICK - 1) / NSEC_PER_TICK);
-
-  /* Save the callback information and start the timer */
+  clock_timespec_add(&g_current, ts, &priv->alarm);
 
   priv->callback = callback;
   priv->arg      = arg;
 
-  return wd_start(priv->wdog, ticks, (wdentry_t)sim_oneshot_handler,
-                  1, (wdparm_t)priv);
+  return OK;
 }
 
 /****************************************************************************
@@ -252,17 +255,46 @@ static int sim_cancel(FAR struct oneshot_lowerhalf_s *lower,
 {
   FAR struct sim_oneshot_lowerhalf_s *priv =
     (FAR struct sim_oneshot_lowerhalf_s *)lower;
-  int ret;
 
-  DEBUGASSERT(priv != NULL);
+  DEBUGASSERT(priv != NULL && ts != NULL);
 
-  /* Cancel the timer */
+  clock_timespec_subtract(&priv->alarm, &g_current, ts);
 
-  ret            = wd_cancel(priv->wdog);
   priv->callback = NULL;
   priv->arg      = NULL;
 
-  return ret;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: sim_current
+ *
+ * Description:
+ *  Get the current time.
+ *
+ * Input Parameters:
+ *   lower   Caller allocated instance of the oneshot state structure.  This
+ *           structure must have been previously initialized via a call to
+ *           oneshot_initialize();
+ *   ts      The location in which to return the current time. A time of zero
+ *           is returned for the initialization moment.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success, a negated errno value is returned on
+ *   any failure.
+ *
+ ****************************************************************************/
+
+static int sim_current(FAR struct oneshot_lowerhalf_s *lower,
+                       FAR struct timespec *ts)
+{
+  FAR struct sim_oneshot_lowerhalf_s *priv =
+    (FAR struct sim_oneshot_lowerhalf_s *)lower;
+
+  DEBUGASSERT(priv != NULL && ts != NULL);
+
+  *ts = g_current;
+  return OK;
 }
 
 /****************************************************************************
@@ -306,17 +338,60 @@ FAR struct oneshot_lowerhalf_s *oneshot_initialize(int chan,
 
   /* Initialize the lower-half driver structure */
 
+  sq_addlast(&priv->link, &g_oneshot_list);
   priv->lh.ops = &g_oneshot_ops;
 
-  /* Initialize the contained watchdog timer */
+  return &priv->lh;
+}
+
+/****************************************************************************
+ * Function:  up_timer_initialize
+ *
+ * Description:
+ *   This function is called during start-up to initialize
+ *   the timer hardware.
+ *
+ ****************************************************************************/
+
+void up_timer_initialize(void)
+{
+  up_alarm_set_lowerhalf(oneshot_initialize(0, 0));
+}
+
+/****************************************************************************
+ * Name: up_timer_update
+ *
+ * Description:
+ *   Called from the IDLE loop to fake one timer tick.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void up_timer_update(void)
+{
+  static const struct timespec tick =
+  {
+    .tv_sec  = 0,
+    .tv_nsec = NSEC_PER_TICK,
+  };
+  FAR sq_entry_t *entry;
+
+  clock_timespec_add(&g_current, &tick, &g_current);
+
+#ifdef CONFIG_SIM_WALLTIME
+  /* Wait a bit so that the timing is close to the correct rate. */
 
-  priv->wdog = wd_create();
-  if (priv->wdog == NULL)
+  host_sleepuntil(g_current.tv_nsec +
+    (uint64_t)g_current.tv_sec * NSEC_PER_SEC);
+#endif
+
+  for (entry = sq_peek(&g_oneshot_list); entry; entry = sq_next(entry))
     {
-      tmrerr("ERROR: Failed to create wdog\n");
-      kmm_free(priv);
-      return NULL;
+      sim_process_tick(entry);
     }
-
-  return &priv->lh;
 }
diff --git a/arch/sim/src/sim/up_tickless.c b/arch/sim/src/sim/up_tickless.c
deleted file mode 100644
index 43752f4..0000000
--- a/arch/sim/src/sim/up_tickless.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/****************************************************************************
- * arch/sim/src/sim/up_tickless.c
- *
- *   Copyright (C) 2014, 2019 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Tickless OS Support.
- *
- * When CONFIG_SCHED_TICKLESS is enabled, all support for timer interrupts
- * is suppressed and the platform specific code is expected to provide the
- * following custom functions.
- *
- *   void sim_timer_initialize(void): Initializes the timer facilities.
- *     Called early in the initialization sequence (by up_initialize()).
- *   int up_timer_gettime(FAR struct timespec *ts):  Returns the current
- *     time from the platform specific time source.
- *   int up_timer_cancel(void):  Cancels the interval timer.
- *   int up_timer_start(FAR const struct timespec *ts): Start (or re-starts)
- *     the interval timer.
- *
- * The RTOS will provide the following interfaces for use by the platform-
- * specific interval timer implementation:
- *
- *   void nxsched_timer_expiration(void):  Called by the platform-specific
- *     logic when the interval timer expires.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <time.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/clock.h>
-
-#ifdef CONFIG_SCHED_TICKLESS
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#if defined(CONFIG_SIM_WALLTIME) || defined(CONFIG_SIM_X11FB)
-/* TICK_USEC, the desired number of microseconds per clock tick (truncated) */
-
-#  define TICK_USEC      (USEC_PER_SEC / CLK_TCK)
-
-/* TICK_SEC, the integer number of seconds in the clock tick (truncated).
- * Should be zero.
- */
-
-#  define TICK_SEC       (TICK_USEC / USEC_PER_SEC)
-
-/* TICK_NSEC, the integer number of nanoseconds (in addition to the number of
- * seconds) in the clock tick.
- */
-
-#  define USEC_REMAINDER (TICK_USEC - (TICK_SEC * USEC_PER_SEC))
-#  define TICK_NSEC      (USEC_REMAINDER * NSEC_PER_USEC)
-
-#else
-
-#  define TICK_SEC       0
-#  define TICK_NSEC      NSEC_PER_TICK
-
-#endif
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static struct timespec g_elapsed_time;
-static struct timespec g_interval_delay;
-static bool            g_timer_active;
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: sim_timer_initialize
- *
- * Description:
- *   Initializes all platform-specific timer facilities.  This function is
- *   called early in the initialization sequence by up_initialize().
- *   On return, the current up-time should be available from
- *   up_timer_gettime() and the interval timer is ready for use (but not
- *   actively timing.
- *
- *   Provided by platform-specific code and called from the architecture-
- *   specific logic.
- *
- * Input Parameters:
- *   None
- *
- * Returned Value:
- *   None
- *
- * Assumptions:
- *   Called early in the initialization sequence before any special
- *   concurrency protections are required.
- *
- ****************************************************************************/
-
-void sim_timer_initialize(void)
-{
-  g_elapsed_time.tv_sec  = 0;
-  g_elapsed_time.tv_nsec = 0;
-  g_timer_active         = false;
-}
-
-/****************************************************************************
- * Name: up_timer_gettime
- *
- * Description:
- *   Return the elapsed time since power-up (or, more correctly, since
- *   sim_timer_initialize() was called).  This function is functionally
- *   equivalent to:
- *
- *      int clock_gettime(clockid_t clockid, FAR struct timespec *ts);
- *
- *   when clockid is CLOCK_MONOTONIC.
- *
- *   This function provides the basis for reporting the current time and
- *   also is used to eliminate error build-up from small erros in interval
- *   time calculations.
- *
- *   Provided by platform-specific code and called from the RTOS base code.
- *
- * Input Parameters:
- *   ts - Provides the location in which to return the up-time.
- *
- * Returned Value:
- *   Zero (OK) is returned on success; a negated errno value is returned on
- *   any failure.
- *
- * Assumptions:
- *   Called from the normal tasking context.  The implementation must
- *   provide whatever mutual exclusion is necessary for correct operation.
- *   This can include disabling interrupts in order to assure atomic register
- *   operations.
- *
- ****************************************************************************/
-
-int up_timer_gettime(FAR struct timespec *ts)
-{
-  ts->tv_sec  = g_elapsed_time.tv_sec;
-  ts->tv_nsec = g_elapsed_time.tv_nsec;
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: up_timer_cancel
- *
- * Description:
- *   Cancel the interval timer and return the time remaining on the timer.
- *   These two steps need to be as nearly atomic as possible.
- *   nxsched_timer_expiration() will not be called unless the timer is
- *   restarted with up_timer_start().
- *
- *   If, as a race condition, the timer has already expired when this
- *   function is called, then that pending interrupt must be cleared so
- *   that up_timer_start() and the remaining time of zero should be
- *   returned.
- *
- *   Provided by platform-specific code and called from the RTOS base code.
- *
- * Input Parameters:
- *   ts - Location to return the remaining time.  Zero should be returned
- *        if the timer is not active.
- *
- * Returned Value:
- *   Zero (OK) is returned on success; a negated errno value is returned on
- *   any failure.
- *
- * Assumptions:
- *   May be called from interrupt level handling or from the normal tasking
- *   level.  Interrupts may need to be disabled internally to assure
- *   non-reentrancy.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_SCHED_TICKLESS
-int up_timer_cancel(FAR struct timespec *ts)
-{
-  /* Return the time remaining on the simulated timer */
-
-  if (g_timer_active)
-    {
-      ts->tv_sec  = g_interval_delay.tv_sec;
-      ts->tv_nsec = g_interval_delay.tv_nsec;
-    }
-  else
-    {
-      ts->tv_sec  = 0;
-      ts->tv_nsec = 0;
-    }
-
-  /* Disable and reset the simulated timer */
-
-  g_interval_delay.tv_sec  = 0;
-  g_interval_delay.tv_nsec = 0;
-  g_timer_active           = false;
-
-  return 0;
-}
-#endif
-
-/****************************************************************************
- * Name: up_timer_start
- *
- * Description:
- *   Start the interval timer.  nxsched_timer_expiration() will be
- *   called at the completion of the timeout (unless up_timer_cancel
- *   is called to stop the timing.
- *
- *   Provided by platform-specific code and called from the RTOS base code.
- *
- * Input Parameters:
- *   ts - Provides the time interval until nxsched_timer_expiration() is
- *        called.
- *
- * Returned Value:
- *   Zero (OK) is returned on success; a negated errno value is returned on
- *   any failure.
- *
- * Assumptions:
- *   May be called from interrupt level handling or from the normal tasking
- *   level.  Interrupts may need to be disabled internally to assure
- *   non-reentrancy.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_SCHED_TICKLESS
-int up_timer_start(FAR const struct timespec *ts)
-{
-  g_interval_delay.tv_sec  = ts->tv_sec;
-  g_interval_delay.tv_nsec = ts->tv_nsec;
-  g_timer_active           = true;
-
-  return 0;
-}
-#endif
-
-/****************************************************************************
- * Name: up_timer_update
- *
- * Description:
- *   Called from the IDLE loop to fake one timer tick.
- *
- * Input Parameters:
- *   None
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-void up_timer_update(void)
-{
-  /* Increment the elapsed time */
-
-  g_elapsed_time.tv_nsec += TICK_NSEC;
-  if (g_elapsed_time.tv_nsec >= NSEC_PER_SEC)
-    {
-      g_elapsed_time.tv_sec++;
-      g_elapsed_time.tv_nsec -= NSEC_PER_SEC;
-    }
-
-  g_elapsed_time.tv_sec += TICK_SEC;
-
-  /* Is the interval timer active? */
-
-  if (g_timer_active)
-    {
-      /* Yes... decrement the interval timer */
-
-      if (g_interval_delay.tv_sec < TICK_SEC)
-        {
-          /* No more seconds left... the timer has expired */
-
-          g_timer_active = false;
-          nxsched_timer_expiration();
-        }
-      else
-        {
-          /* Decrement seconds.  May decrement to zero */
-
-          g_interval_delay.tv_sec -= TICK_SEC;
-
-          /* Decrement nanoseconds */
-
-          if (g_interval_delay.tv_nsec >= TICK_NSEC)
-            {
-              g_interval_delay.tv_nsec -= TICK_NSEC;
-            }
-
-          /* Handle borrow from seconds */
-
-          else if (g_interval_delay.tv_sec > 0)
-            {
-              g_interval_delay.tv_nsec += NSEC_PER_SEC;
-              g_interval_delay.tv_sec--;
-
-              g_interval_delay.tv_nsec -= TICK_NSEC;
-            }
-
-          /* Otherwise the timer has expired */
-
-          else
-            {
-              g_timer_active = false;
-              nxsched_timer_expiration();
-            }
-        }
-    }
-}
-
-#endif /* CONFIG_SCHED_TICKLESS */


[incubator-nuttx] 03/03: arch/sim: Implement arch rtc interface on top of rtc driver

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch pr274
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 3332ec3fdf8b7cb2ba3fe6f2f83245912e28f98c
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Thu Feb 13 01:53:05 2020 +0800

    arch/sim: Implement arch rtc interface on top of rtc driver
    
    Change-Id: Icd35945e0c63fe46dd38d0d432007d0d2320a56a
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 arch/Kconfig                 |   1 +
 arch/sim/src/Makefile        |   8 ++-
 arch/sim/src/nuttx-names.dat |   1 +
 arch/sim/src/sim/up_rtc.c    | 127 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 134 insertions(+), 3 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index ce5bac9..7f97c83 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -67,6 +67,7 @@ config ARCH_RISCV
 config ARCH_SIM
 	bool "Simulation"
 	select ARCH_HAVE_MULTICPU
+	select ARCH_HAVE_RTC_SUBSECONDS
 	select ARCH_HAVE_TLS
 	select ARCH_HAVE_TICKLESS
 	select ARCH_HAVE_POWEROFF
diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile
index 5204949..69781b0 100644
--- a/arch/sim/src/Makefile
+++ b/arch/sim/src/Makefile
@@ -109,6 +109,10 @@ ifeq ($(CONFIG_ONESHOT),y)
   CSRCS += up_oneshot.c
 endif
 
+ifeq ($(CONFIG_RTC_DRIVER),y)
+  CSRCS += up_rtc.c
+endif
+
 ifeq ($(CONFIG_NX_LCDDRIVER),y)
   CSRCS += up_lcd.c
 else
@@ -124,15 +128,13 @@ ifeq ($(CONFIG_SIM_TOUCHSCREEN),y)
   REQUIREDOBJS += up_touchscreen$(OBJEXT)
   HOSTCFLAGS += -DCONFIG_SIM_TOUCHSCREEN=1
   HOSTSRCS += up_x11eventloop.c
-else
-ifeq ($(CONFIG_SIM_AJOYSTICK),y)
+else ifeq ($(CONFIG_SIM_AJOYSTICK),y)
   CSRCS += up_ajoystick.c
   HOSTCFLAGS += -DCONFIG_SIM_AJOYSTICK=1
   HOSTSRCS += up_x11eventloop.c
 endif
 endif
 endif
-endif
 
 ifeq ($(CONFIG_SIM_IOEXPANDER),y)
   CSRCS += up_ioexpander.c
diff --git a/arch/sim/src/nuttx-names.dat b/arch/sim/src/nuttx-names.dat
index cd89d17..d359e45 100644
--- a/arch/sim/src/nuttx-names.dat
+++ b/arch/sim/src/nuttx-names.dat
@@ -8,6 +8,7 @@ chdir          NXchdir
 clearenv       NXclearenv
 clock          NXclock
 clock_gettime  NXclock_gettime
+clock_settime  NXclock_settime
 close          NXclose
 closedir       NXclosedir
 connect        NXconnect
diff --git a/arch/sim/src/sim/up_rtc.c b/arch/sim/src/sim/up_rtc.c
new file mode 100644
index 0000000..838d205
--- /dev/null
+++ b/arch/sim/src/sim/up_rtc.c
@@ -0,0 +1,127 @@
+/****************************************************************************
+ * arch/sim/src/sim/up_rtc.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/timers/rtc.h>
+#include <nuttx/timers/arch_rtc.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int sim_rtc_rdtime(FAR struct rtc_lowerhalf_s *lower,
+                          FAR struct rtc_time *rtctime);
+static int sim_rtc_settime(FAR struct rtc_lowerhalf_s *lower,
+                           FAR const struct rtc_time *rtctime);
+static bool sim_rtc_havesettime(FAR struct rtc_lowerhalf_s *lower);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rtc_ops_s g_sim_rtc_ops =
+{
+  .rdtime      = sim_rtc_rdtime,
+  .settime     = sim_rtc_settime,
+  .havesettime = sim_rtc_havesettime,
+};
+
+static struct rtc_lowerhalf_s g_sim_rtc =
+{
+  .ops         = &g_sim_rtc_ops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int sim_rtc_rdtime(FAR struct rtc_lowerhalf_s *lower,
+                          FAR struct rtc_time *rtctime)
+{
+  uint64_t nsec;
+  time_t sec;
+
+
+  nsec = host_gettime(true);
+  sec  = nsec / NSEC_PER_SEC;
+  nsec -= sec * NSEC_PER_SEC;
+
+  gmtime_r(&sec, (FAR struct tm *)rtctime);
+  rtctime->tm_nsec = nsec;
+
+  return OK;
+}
+
+static int sim_rtc_settime(FAR struct rtc_lowerhalf_s *lower,
+                           FAR const struct rtc_time *rtctime)
+{
+  uint64_t nsec;
+
+  nsec = mktime((FAR struct tm *)rtctime);
+  nsec *= NSEC_PER_SEC;
+  nsec += rtctime->tm_nsec;
+  host_settime(true, nsec);
+
+  return OK;
+}
+
+static bool sim_rtc_havesettime(FAR struct rtc_lowerhalf_s *lower)
+{
+  return true;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_rtc_initialize
+ *
+ * Description:
+ *   Initialize the builtin, MCU hardware RTC per the selected
+ *   configuration.  This function is called once very early in the OS
+ *   initialization sequence.
+ *
+ *   NOTE that initialization of external RTC hardware that depends on the
+ *   availability of OS resources (such as SPI or I2C) must be deferred
+ *   until the system has fully booted.  Other, RTC-specific initialization
+ *   functions are used in that case.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+int up_rtc_initialize(void)
+{
+  up_rtc_set_lowerhalf(&g_sim_rtc);
+  return rtc_initialize(0, &g_sim_rtc);
+}


[incubator-nuttx] 01/03: Make compare_timespec public so timer driver could reuse it

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch pr274
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit aa71d529965a86363aaeb044eecee6e60ad5f749
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Fri Feb 7 13:38:52 2020 +0800

    Make compare_timespec public so timer driver could reuse it
    
    Change-Id: I1d5dfbf7535876d2dbe47dcca749d0d0f7203906
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 drivers/timers/arch_alarm.c       | 15 +--------------
 include/nuttx/clock.h             | 13 +++++++++++++
 sched/clock/clock_abstime2ticks.c | 16 ++++++----------
 3 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/drivers/timers/arch_alarm.c b/drivers/timers/arch_alarm.c
index 9f8d953..c1e1918 100644
--- a/drivers/timers/arch_alarm.c
+++ b/drivers/timers/arch_alarm.c
@@ -84,19 +84,6 @@ static inline void timespec_from_usec(FAR struct timespec *ts,
   ts->tv_nsec   = microseconds * NSEC_PER_USEC;
 }
 
-static inline int timespec_compare(FAR const struct timespec *ts1,
-                                   FAR const struct timespec *ts2)
-{
-  if (ts1->tv_sec != ts2->tv_sec)
-    {
-      return ts1->tv_sec - ts2->tv_sec;
-    }
-  else
-    {
-      return ts1->tv_nsec - ts2->tv_nsec;
-    }
-}
-
 static void udelay_accurate(useconds_t microseconds)
 {
   struct timespec now;
@@ -107,7 +94,7 @@ static void udelay_accurate(useconds_t microseconds)
   timespec_from_usec(&delta, microseconds);
   clock_timespec_add(&now, &delta, &end);
 
-  while (timespec_compare(&now, &end) < 0)
+  while (clock_timespec_compare(&now, &end) < 0)
     {
       ONESHOT_CURRENT(g_oneshot_lower, &now);
     }
diff --git a/include/nuttx/clock.h b/include/nuttx/clock.h
index 1ae712c..72177f1 100644
--- a/include/nuttx/clock.h
+++ b/include/nuttx/clock.h
@@ -271,6 +271,19 @@ EXTERN volatile clock_t g_system_timer;
  ****************************************************************************/
 
 /****************************************************************************
+ * Name: clock_timespec_compare
+ *
+ * Description:
+ *    Return < 0 if time ts1 is before time ts2
+ *    Return > 0 if time ts2 is before time ts1
+ *    Return 0 if time ts1 is the same as time ts2
+ *
+ ****************************************************************************/
+
+int clock_timespec_compare(FAR const struct timespec *ts1,
+                           FAR const struct timespec *ts2);
+
+/****************************************************************************
  * Name:  clock_timespec_add
  *
  * Description:
diff --git a/sched/clock/clock_abstime2ticks.c b/sched/clock/clock_abstime2ticks.c
index 3f812c7..38dbb75 100644
--- a/sched/clock/clock_abstime2ticks.c
+++ b/sched/clock/clock_abstime2ticks.c
@@ -45,11 +45,11 @@
 #include "clock/clock.h"
 
 /****************************************************************************
- * Private Functions
+ * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: compare_timespec
+ * Name: clock_timespec_compare
  *
  * Description:
  *    Return < 0 if time a is before time b
@@ -58,8 +58,8 @@
  *
  ****************************************************************************/
 
-static long compare_timespec(FAR const struct timespec *a,
-                             FAR const struct timespec *b)
+int clock_timespec_compare(FAR const struct timespec *a,
+                           FAR const struct timespec *b)
 {
   if (a->tv_sec < b->tv_sec)
     {
@@ -71,14 +71,10 @@ static long compare_timespec(FAR const struct timespec *a,
       return 1;
     }
 
-  return (long)a->tv_nsec - (long)b->tv_nsec;
+  return a->tv_nsec - b->tv_nsec;
 }
 
 /****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
  * Name: clock_abstime2ticks
  *
  * Description:
@@ -115,7 +111,7 @@ int clock_abstime2ticks(clockid_t clockid, FAR const struct timespec *abstime,
       return EINVAL;
     }
 
-  if (compare_timespec(abstime, &currtime) < 0)
+  if (clock_timespec_compare(abstime, &currtime) < 0)
     {
       /* Every caller of clock_abstime2ticks check 'ticks < 0' to see if
        * absolute time is in the past. So lets just return negative tick