diff --git a/include/nuttx/clock.h b/include/nuttx/clock.h index 05b568af6a4..71718f45064 100644 --- a/include/nuttx/clock.h +++ b/include/nuttx/clock.h @@ -29,6 +29,7 @@ #include +#include #include #include #include @@ -839,6 +840,18 @@ int nxclock_settime(clockid_t clock_id, FAR const struct timespec *tp); int nxclock_gettime(clockid_t clock_id, FAR struct timespec *tp); +/**************************************************************************** + * Name: nxclock_adjtime + * + * Description: + * Adjust the frequency and/or phase of a clock. + * + ****************************************************************************/ + +#ifdef CONFIG_CLOCK_ADJTIME +int nxclock_adjtime(clockid_t clock_id, FAR struct timex *buf); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/include/sys/timex.h b/include/sys/timex.h index 19418da7f94..bbd8b16a903 100644 --- a/include/sys/timex.h +++ b/include/sys/timex.h @@ -90,6 +90,37 @@ extern "C" #define EXTERN extern #endif +/**************************************************************************** + * Name: clock_adjtime + * + * Description: + * Adjust the frequency and/or phase of a clock. + * This function allows the adjustment of the frequency and/or phase of a + * specified clock. It can be used to synchronize the clock with an + * external time source or to apply a frequency offset. + * + * Input Parameters: + * clk_id - The identifier of the clock to be adjusted. This is typically + * one of the predefined clock IDs such as CLOCK_REALTIME, + * CLOCK_MONOTONIC, or CLOCK_BOOTTIME. + * + * buf - A pointer to a `timex` structure that specifies the adjustment + * parameters. This structure includes fields for the frequency + * adjustment (`freq`), the maximum frequency error (`maxerror`), + * the estimated error (`esterror`), the phase offset (`offset`), + * and flags to indicate the type of adjustment (`status`). + * + * Returned Value: + * Return On success, the function returns 0. On error, it returns + * -1 and sets 'errno` to indicate the specific error that + * occurred. + * + ****************************************************************************/ + +#ifdef CONFIG_CLOCK_ADJTIME +int clock_adjtime(clockid_t clk_id, FAR struct timex *buf); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/sched/Kconfig b/sched/Kconfig index e4c021265c8..17892ad4b88 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -188,7 +188,7 @@ config ARCH_HAVE_ADJTIME config CLOCK_ADJTIME bool "Support adjtime function" default n - depends on ARCH_HAVE_ADJTIME || RTC_ADJTIME + depends on ARCH_HAVE_ADJTIME || RTC_ADJTIME || PTP_CLOCK ---help--- Enables usage of adjtime() interface used to correct the system time clock. This requires specific architecture support. @@ -196,6 +196,9 @@ config CLOCK_ADJTIME Adjustment can affect system timer period and/or high-resolution RTC. These are implemented by interfaces up_adjtime() and up_rtc_adjtime(). + Enables usage of clock_adjtime() interface used to correct the system + and other ptp time clock. This requires ptp clock support. + This is not a POSIX interface but derives from 4.3BSD, System V. It is also supported for Linux compatibility. diff --git a/sched/clock/clock_adjtime.c b/sched/clock/clock_adjtime.c index a46924b7033..4091cef2c77 100644 --- a/sched/clock/clock_adjtime.c +++ b/sched/clock/clock_adjtime.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include "clock/clock.h" @@ -215,4 +217,96 @@ int adjtime(FAR const struct timeval *delta, FAR struct timeval *olddelta) } } +/**************************************************************************** + * Name: nxclock_adjtime + * + * Description: + * Adjust the frequency and/or phase of a clock. + * This function allows the adjustment of the frequency and/or phase of a + * specified clock. It can be used to synchronize the clock with an + * external time source or to apply a frequency offset. + * + * Input Parameters: + * clk_id - The identifier of the clock to be adjusted. This is typically + * one of the predefined clock IDs such as CLOCK_REALTIME, + * CLOCK_MONOTONIC, or CLOCK_BOOTTIME. + * + * buf - A pointer to a `timex` structure that specifies the adjustment + * parameters. This structure includes fields for the frequency + * adjustment (`freq`), the maximum frequency error (`maxerror`), + * the estimated error (`esterror`), the phase offset (`offset`), + * and flags to indicate the type of adjustment (`status`). + * + * Returned Value: + * Return On success, the function returns 0. On error, it returns + * -1 and sets 'errno` to indicate the specific error that + * occurred. + * + ****************************************************************************/ + +int nxclock_adjtime(clockid_t clock_id, FAR struct timex *buf) +{ + int ret = -EINVAL; + +#ifdef CONFIG_PTP_CLOCK + if ((clock_id & CLOCK_MASK) == CLOCK_FD) + { + FAR struct file *filep; + + ret = ptp_clockid_to_filep(clock_id, &filep); + if (ret < 0) + { + return ret; + } + + ret = file_ioctl(filep, PTP_CLOCK_ADJTIME, + (unsigned long)(uintptr_t)buf); + fs_putfilep(filep); + } +#endif + + return ret; +} + +/**************************************************************************** + * Name: clock_adjtime + * + * Description: + * Adjust the frequency and/or phase of a clock. + * This function allows the adjustment of the frequency and/or phase of a + * specified clock. It can be used to synchronize the clock with an + * external time source or to apply a frequency offset. + * + * Input Parameters: + * clk_id - The identifier of the clock to be adjusted. This is typically + * one of the predefined clock IDs such as CLOCK_REALTIME, + * CLOCK_MONOTONIC, or CLOCK_BOOTTIME. + * + * buf - A pointer to a `timex` structure that specifies the adjustment + * parameters. This structure includes fields for the frequency + * adjustment (`freq`), the maximum frequency error (`maxerror`), + * the estimated error (`esterror`), the phase offset (`offset`), + * and flags to indicate the type of adjustment (`status`). + * + * Returned Value: + * Return On success, the function returns 0. On error, it returns + * -1 and sets 'errno` to indicate the specific error that + * occurred. + * + ****************************************************************************/ + +int clock_adjtime(clockid_t clk_id, FAR struct timex *buf) +{ + int ret; + + ret = nxclock_adjtime(clk_id, buf); + if (ret < 0) + { + set_errno(-ret); + return ERROR; + } + + return ret; +} + #endif /* CONFIG_CLOCK_ADJTIME */