This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 3edf6de552d drivers/timers/arch_alarm: Revert removal of
ndelay_accurate
3edf6de552d is described below
commit 3edf6de552d863e7a0c83305c84ce750948c2dfb
Author: Matteo Golin <[email protected]>
AuthorDate: Mon Oct 20 20:36:05 2025 -0400
drivers/timers/arch_alarm: Revert removal of ndelay_accurate
This reverts the removal of ndelay_accurate from #14450, since as
mentioned in #17011, this fails to consider the `sim` architecture
where CONFIG_BOARD_LOOPSPERMSEC was set to 0 because of reliance on the
accurate implementations of the up_delay functions. All the commit did
was remove a more accurate implementation in favour of a less accurate
one.
Signed-off-by: Matteo Golin <[email protected]>
---
drivers/timers/arch_alarm.c | 120 ++++++++++++++++++++++++++++++++++++++++++++
sched/clock/CMakeLists.txt | 2 +-
sched/clock/Make.defs | 4 +-
3 files changed, 124 insertions(+), 2 deletions(-)
diff --git a/drivers/timers/arch_alarm.c b/drivers/timers/arch_alarm.c
index 7a825b06446..de1019ab871 100644
--- a/drivers/timers/arch_alarm.c
+++ b/drivers/timers/arch_alarm.c
@@ -30,6 +30,14 @@
#include <nuttx/clock.h>
#include <nuttx/timers/arch_alarm.h>
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10)
+#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100)
+#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000)
+
/****************************************************************************
* Private Data
****************************************************************************/
@@ -44,6 +52,69 @@ static clock_t g_current_tick;
* Private Functions
****************************************************************************/
+static void udelay_coarse(useconds_t microseconds)
+{
+ volatile int i;
+
+ /* We'll do this a little at a time because we expect that the
+ * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in
+ * the divisions of its calculation. We'll use the largest values that
+ * we can in order to prevent significant error buildup in the loops.
+ */
+
+ while (microseconds > 1000)
+ {
+ for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++)
+ {
+ }
+
+ microseconds -= 1000;
+ }
+
+ while (microseconds > 100)
+ {
+ for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++)
+ {
+ }
+
+ microseconds -= 100;
+ }
+
+ while (microseconds > 10)
+ {
+ for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++)
+ {
+ }
+
+ microseconds -= 10;
+ }
+
+ while (microseconds > 0)
+ {
+ for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++)
+ {
+ }
+
+ microseconds--;
+ }
+}
+
+static void ndelay_accurate(unsigned long nanoseconds)
+{
+ struct timespec now;
+ struct timespec end;
+ struct timespec delta;
+
+ ONESHOT_CURRENT(g_oneshot_lower, &now);
+ clock_nsec2time(&delta, nanoseconds);
+ clock_timespec_add(&now, &delta, &end);
+
+ while (clock_timespec_compare(&now, &end) < 0)
+ {
+ ONESHOT_CURRENT(g_oneshot_lower, &now);
+ }
+}
+
static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
FAR void *arg)
{
@@ -74,6 +145,55 @@ static void oneshot_callback(FAR struct oneshot_lowerhalf_s
*lower,
* Public Functions
****************************************************************************/
+/****************************************************************************
+ * Name: up_mdelay
+ *
+ * Description:
+ * Delay inline for the requested number of milliseconds.
+ * WARNING: NOT multi-tasking friendly
+ *
+ ****************************************************************************/
+
+void weak_function up_mdelay(unsigned int milliseconds)
+{
+ up_udelay(USEC_PER_MSEC * milliseconds);
+}
+
+/****************************************************************************
+ * Name: up_udelay
+ *
+ * Description:
+ * Delay inline for the requested number of microseconds.
+ * WARNING: NOT multi-tasking friendly
+ *
+ ****************************************************************************/
+
+void weak_function up_udelay(useconds_t microseconds)
+{
+ up_ndelay(NSEC_PER_USEC * microseconds);
+}
+
+/****************************************************************************
+ * Name: up_ndelay
+ *
+ * Description:
+ * Delay inline for the requested number of nanoseconds.
+ * WARNING: NOT multi-tasking friendly
+ *
+ ****************************************************************************/
+
+void weak_function up_ndelay(unsigned long nanoseconds)
+{
+ if (g_oneshot_lower != NULL)
+ {
+ ndelay_accurate(nanoseconds);
+ }
+ else /* Oneshot timer hasn't been initialized yet */
+ {
+ udelay_coarse((nanoseconds + NSEC_PER_USEC - 1) / NSEC_PER_USEC);
+ }
+}
+
void up_alarm_set_lowerhalf(FAR struct oneshot_lowerhalf_s *lower)
{
#ifdef CONFIG_SCHED_TICKLESS
diff --git a/sched/clock/CMakeLists.txt b/sched/clock/CMakeLists.txt
index 9599bb972fd..62c4346bf0d 100644
--- a/sched/clock/CMakeLists.txt
+++ b/sched/clock/CMakeLists.txt
@@ -35,7 +35,7 @@ set(SRCS
# include the base delay definition (busy-loop) as a minimum-viable product. We
# don't want the weak references to conflict.
-if(NOT CONFIG_TIMER_ARCH)
+if(NOT CONFIG_TIMER_ARCH AND NOT CONFIG_ALARM_ARCH)
list(APPEND SRCS delay.c)
endif()
diff --git a/sched/clock/Make.defs b/sched/clock/Make.defs
index 00b723b8af0..e61da4dbd9e 100644
--- a/sched/clock/Make.defs
+++ b/sched/clock/Make.defs
@@ -29,7 +29,9 @@ CSRCS += clock_perf.c clock_realtime2absticks.c
# don't want the weak references to conflict.
ifneq ($(CONFIG_TIMER_ARCH),y)
- CSRCS += delay.c
+ ifneq ($(CONFIG_ALARM_ARCH),y)
+ CSRCS += delay.c
+ endif
endif
ifeq ($(CONFIG_CLOCK_TIMEKEEPING),y)