Replace the sigqueue + shared-memory IPC mechanism in ptpd_status()
with a file-based approach:
- Daemon side: on SIGUSR1, write a binary ptpd_status_s struct to
a temp file and atomically rename it to the status path.
- Client side: send kill(SIGUSR1), poll for the file to appear,
then read the struct back.
This removes the CONFIG_BUILD_FLAT restriction (the old code returned
-ENOTSUP for Protected and Kernel builds) and avoids passing pointers
across address spaces via sigqueue. The status file path is
configurable via NETUTILS_PTPD_STATUSFILE (default /tmp/ptpd.status).
The atomic temp + rename pattern ensures readers never see a partial
write.
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
The IGMP multicast join (ipmsfilter) was previously called before
the interface address (interface_addr) was populated via SIOCGIFADDR.
This meant the IGMP join had to locate the network device without
a valid local address, which could fail or join on the wrong interface.
Move the multicast group subscription to after the interface address
is queried, and guard it with an AF_INET check since IGMP only applies
to IPv4. This ensures the IGMP join can always locate the correct
network device.
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
Add ptpinfo()/ptpwarn() calls, gated by the existing
CONFIG_DEBUG_PTP_INFO/_WARN symbols (zero cost when disabled), at
points that previously failed silently: an unrecognized L2 protocol,
a domain mismatch, and a Delay_Resp rejected by the source/requester
identity check. These were essential to diagnosing the drift and
Delay_Req bugs fixed in the two preceding commits on real hardware,
and are kept for future maintainers debugging this path.
Assisted-by: Claude:claude-sonnet-5
Assisted-by: Gemini:gemini-3.8-flash-medium
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
1. On AF_PACKET SOCK_RAW sockets in NuttX, msg_name must be NULL because
the destination MAC address is already contained in the Ethernet header.
Previously, passing sockaddr_in caused sendmsg() to fail immediately
with -EAFNOSUPPORT, completely blocking transmission of Delay_Req.
2. Correct PTP primary multicast MAC address to 01:1b:19:00:00:00
(IEEE 1588 Annex F) and ensure ether_type is in network byte order.
3. Initialize delayreq_interval to 1 second default and guard against 0.
4. Set logmessageinterval to 0x7f (IEEE 1588-2008 Table 23 sentinel for
Delay_Req) instead of inheriting 0 from the announce header template.
5. Update PTP version to 0x12 (2.1, minorVersionPTP=1) to match the
value used by mature implementations such as linuxptp.
Assisted-by: Claude:claude-sonnet-5
Assisted-by: Gemini:gemini-3.8-flash-medium
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
1. Post-jump drift bootstrap: on the first Sync packet following a step
jump, do not compute frequency drift against a synthesized zero delta,
which previously caused the entire residual phase offset (~ms) to be
mistaken for frequency drift (~million ppb) and immediately absorbed.
2. Drift rate formula: normalize the adjustment contribution by the actual
measurement interval instead of the adjtime slew period, and compute
natural delta rate as (delta - last_delta + last_adjtime) / interval.
3. Remove broken last_delta > delta comparison that prevented offsets from
converging and applied inverted corrections on negative overshoots.
4. Correct ptp_adjtime() invocation to always pass adjustment_ns for
CLOCK_REALTIME slewing rather than dropping drift compensation when
delta exceeds threshold. Clamp adjustment_ns to the hardware slew limit
so last_adjtime_ns accurately mirrors the true slew applied.
5. Enable Delay_Req in E2E mode once clock is tracking (not jumping) and
allow software timestamping latency in ptp_process_delay_resp().
6. Propagate initialization return code from ptpd_start() and avoid
unconditional failure print in do_ptpd_start().
Assisted-by: Claude:claude-sonnet-5
Assisted-by: Gemini:gemini-3.8-flash-medium
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Now that time_t is unconditionally 64-bit (signed int64_t) and the
struct timespec fields tv_sec / tv_nsec are wide enough on their own,
the explicit (uint64_t)/(int64_t)/(int) casts that used to guard the
multiplications and subtractions in *_us / *_ms / *_ns helpers are no
longer needed. Drop them to keep the timekeeping math readable.
In the same spirit, this commit also normalises the printf-style format
specifiers and casts used to print tv_sec / tv_nsec / tv_usec values.
The prior code was a mix of "%d"/"%u"/"%ld"/"%lu"/"%lld" with matching
(int)/(unsigned long)/(long long) casts; some formats truncated time_t
on 32-bit hosts, others mismatched signedness or width. Replace all
such cases with the portable POSIX-recommended forms:
- tv_sec (time_t, signed, impl-defined width) -> %jd + (intmax_t)
- tv_nsec (long, signed) -> %ld (no cast)
- tv_usec (suseconds_t / long) -> %ld (no cast)
Also drop two stale `(FAR const time_t *)&ts.tv_sec` casts that are
unnecessary now that ts.tv_sec is plain time_t.
Arithmetic-cleanup files (existing scope):
- benchmarks/cyclictest/cyclictest.c: timediff_us()
- benchmarks/sd_bench/sd_bench_main.c: get_time_delta_us()
- examples/oneshot/oneshot_main.c: maxus computation
- examples/watchdog/watchdog_main.c: current_time_ms (x2)
- industry/nxmodbus/nxmb_internal.h: nxmb_util_clock_ms()
- netutils/ntpclient/ntpclient.c: timespec2ntp()
- netutils/ptpd/ptpd.c: ptp_adjtime()
- system/dd/dd_main.c: elapsed accounting
- testing/drivers/drivertest/drivertest_posix_timer.c:
get_timestamp()
- testing/drivers/sd_stress/sd_stress_main.c:get_time_delta()
- testing/sched/getprime/getprime_main.c: elapsed accounting
- testing/sched/pthread_mutex_perf/pthread_mutex_perf.c:
timespec_avg()
Printf-format-fix files (new in this revision):
- examples/adjtime/adjtime_main.c
- examples/charger/charger_main.c
- examples/netpkt/netpkt_ethercat.c
- fsutils/mkfatfs/mkfatfs.c
- graphics/tiff/tiff_initialize.c
- netutils/ptpd/ptpd.c
- nshlib/nsh_timcmds.c
- system/coredump/coredump.c
- system/ptpd/ptpd_main.c
- testing/drivers/drivertest/drivertest_oneshot.c
- testing/mm/kasantest/kasantest.c
- testing/ostest/semtimed.c
- testing/sched/pthread_mutex_perf/pthread_mutex_perf.c
- testing/sched/timerjitter/timerjitter.c
- testing/testsuites/kernel/time/cases/clock_test_clock01.c
- testing/testsuites/kernel/time/cases/clock_test_smoke.c
No behavioural change.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
NuttX always uses a 64-bit system clock now (time_t/clock_t are
always 64-bit). Remove the obsolete CONFIG_SYSTEM_TIME64 #ifdef
branches and Kconfig dependency.
- examples/dronecan: drop SYSTEM_TIME64 dependency
- examples/netlink_route: always use PRIx64
- netutils/netinit: always use the 1-hour LONG_TIME_SEC
- netutils/ptpd: always pack the 48-bit seconds field and apply
the 64-bit overflow guard in timespec_delta_ns()
- testing/ostest/semtimed: always validate tv_sec >= 0
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Replace app-side includes of <debug.h> with <nuttx/debug.h> to use the
header from the NuttX tree explicitly after the header move.
Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
In some scenarios, dynamic memory allocation is not allowed, so it is modified to a static allocation method.
Signed-off-by: gaohedong <gaohedong@xiaomi.com>
The current gPTP stack does not support path delay correction of the Switch.
This patch adds the path delay correction field in the Header.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
fix compile warning when only enable PTPD_CLIENT or PTPD_SERVER
ptpd.c:493:38: error: 'CONFIG_NETUTILS_PTPD_PRIORITY1' undeclared (first
use in this function); did you mean 'CONFIG_NETUTILS_PTPD_CLIENT'?
ptpd.c:494:39: error: 'CONFIG_NETUTILS_PTPD_CLASS' undeclared (first use
in this function); did you mean 'CONFIG_NETUTILS_PTPD_CLIENT'?
ptpd.c:495:39: error: 'CONFIG_NETUTILS_PTPD_ACCURACY' undeclared (first
use in this function); did you mean 'CONFIG_NETUTILS_PTPD_DEBUG'?
ptpd.c:498:38: error: 'CONFIG_NETUTILS_PTPD_PRIORITY2' undeclared (first
use in this function); did you mean 'CONFIG_NETUTILS_PTPD_CLIENT'?
ptpd.c:502:36: error: 'CONFIG_NETUTILS_PTPD_CLOCKSOURCE' undeclared
(first use in this function); did you mean
'CONFIG_NETUTILS_PTPD_STACKSIZE'?
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
The original implementation only checked if each field was less than,
but didn't check for greater than before proceeding to the next field.
This caused incorrect clock selection behavior in the PTP Best Master
Clock Algorithm (BMCA).
The fix expands each comparison to explicitly check both < and >
conditions, returning the appropriate result immediately. This ensures
proper precedence evaluation according to IEEE 1588 specification:
- gm_priority1
- gm_quality (class, accuracy, variance)
- gm_priority2
- gm_identity
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
Fixed bug where negative offsets were not properly handled because
clock_timespec_subtract clamps values to zero.
Implement support for SO_TIMESTAMP to get accurate packet
reception timestamp.
Implemented delay requests for measuring packet transfer delay.
Implemented clock drift estimation to bring the clocks closer to
sync and to filter out measurement jitter.
If multicast PTP packets are not being received, rejoin the multicast group.
This automatically recovers from situations such as rebooting a network switch.
What works:
- Basic server & client operation
- Transmission and reception of announce, sync and follow-up
Still missing:
- SO_TIMINGS for getting more precise packet timestamps
- Implementation of delay_req and delay_resp packets
- Status and stop interfaces for the daemon