mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-10-07 22:25:12 +00:00
netutils/ptpd: phase-lock hardware clock via POSIX clock_adjtime.
When state->clockid is configured to a hardware PTP clock device (e.g., /dev/ptp0) instead of CLOCK_REALTIME, ptp_adjtime() previously passed only the measured frequency drift (-ppb) to clock_adjtime(), ignoring the residual phase offset (delta_ns / adjustment_ns). As a result, while the hardware counter tracked frequency, its phase was never pulled into alignment with the master clock. Convert delta_ns (which combines frequency drift and current phase error clamped to max_adjust_ns) to ppb over CONFIG_CLOCK_ADJTIME_PERIOD_MS, acting as a proportional-integral (PI) phase servo. This drives the hardware clock to phase lock with the master via POSIX clock_adjtime() using ADJ_FREQUENCY without requiring proprietary ioctl calls. Assisted-by: Claude:claude-sonnet-5 Assisted-by: Gemini:gemini-3.8-flash-medium Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
This commit is contained in:
parent
e8fa49dc72
commit
6d10b44bc1
1 changed files with 25 additions and 2 deletions
|
|
@ -30,9 +30,10 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timex.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -441,9 +442,31 @@ static int ptp_adjtime(FAR struct ptp_state_s *state, int64_t delta_ns,
|
|||
else
|
||||
{
|
||||
struct timex buf;
|
||||
int64_t hw_ppb;
|
||||
const int64_t slew_limit_ppb =
|
||||
CONFIG_CLOCK_ADJTIME_SLEWLIMIT_PPM * 1000;
|
||||
|
||||
/* delta_ns passed here is adjustment_ns, which already
|
||||
* combines frequency drift and current phase error clamped
|
||||
* to max_adjust_ns. Converting it to ppb over
|
||||
* CONFIG_CLOCK_ADJTIME_PERIOD_MS produces the rate needed to
|
||||
* pull the hardware counter into phase lock.
|
||||
*/
|
||||
|
||||
hw_ppb = delta_ns * MSEC_PER_SEC /
|
||||
CONFIG_CLOCK_ADJTIME_PERIOD_MS;
|
||||
|
||||
if (hw_ppb > slew_limit_ppb)
|
||||
{
|
||||
hw_ppb = slew_limit_ppb;
|
||||
}
|
||||
else if (hw_ppb < -slew_limit_ppb)
|
||||
{
|
||||
hw_ppb = -slew_limit_ppb;
|
||||
}
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
buf.freq = (long)(-ppb * 65536 / 1000);
|
||||
buf.freq = hw_ppb * 65536 / 1000;
|
||||
buf.modes = ADJ_FREQUENCY;
|
||||
|
||||
return clock_adjtime(state->clockid, &buf);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue