第 1 章 - Azure RTOS NetX Duo SNTP 简介

Azure RTOS NetX 简单网络时间协议 (SNTP) 是为通过 Internet 同步时钟而设计的协议。 SNTP 版本 4 是基于网络时间协议 (NTP) 的简化协议。 它利用用户数据报协议 (UDP) 服务,以简单的无状态协议执行时间更新。 尽管 SNTP 不像 NTP 那样复杂,但它高度可靠且准确。 在当今 Internet 的大多数位置,SNTP 根据同步源和网络路径的特性提供 1-50 毫秒的准确度。 SNTP 拥有多个用于提供接收时间更新可靠性的选项。 可以切换到备用服务器、应用回退轮询算法和自动时间服务器发现只是 SNTP 客户端处理可变 Internet 时间服务环境的几种方法。 它在准确性方面的不足,在简单性和易于实现方面得到了弥补。 SNTP 主要用于提供广泛的机制来访问国家/地区时间和频率散播(例如 NTP 服务器)服务。

NetX Duo SNTP 客户端要求

NetX Duo SNTP 客户端要求已创建 IP 实例。 此外,还必须在同一个 IP 实例上启用 UDP,并且应该能够访问众所周知的端口 123,以便将时间数据发送到 SNTP 服务器(尽管备用端口也可以工作)。 广播客户端应绑定客户端的广播服务器正在其上进行发送的 UDP 端口,通常为端口 123. NetX Duo SNTP 客户端应用程序必须具有一个或多个 IP SNTP 服务器地址。

NetX Duo SNTP 客户端限制

SNTP 客户端 API 处理的 NTP 时间更新中采用本地时间表示的准确度仅限毫秒解析。

SNTP 客户端随时仅持有单个 SNTP 服务器地址。 如果该服务器似乎不再有效,则应用程序必须停止 SNTP 客户端任务,并使用广播或单播 SNTP 通信将其重新初始化为另一个 SNTP 服务器地址。

SNTP 客户端不支持选播。

NetX Duo SNTP 客户端不支持验证收到的数据包数据的身份验证机制。

NetX Duo SNTP 客户端操作

RFC 4330 建议仅在 SNTP 客户端本地网络的最高层次上对此类客户端进行操作,并且最好是在没有 NTP 或 SNTP 客户端依赖它们进行同步的配置中操作。 层次级别反映了 NTP 时间层次结构中的主机位置,其中层次 1 是最高级别(根时间服务器),层次 15 是最低允许级别(客户端)。 SNTP 客户端默认的最低层次为 2。

可以在以下两种基本模式之一中操作 NetX Duo SNTP 客户端:单播或广播,以通过 Internet 获取时间。 在单播模式下,客户端定期轮询其 SNTP 服务器,并等待接收来自该服务器的答复。 接收到一个答复后,客户端将通过应用 RFC 4330 建议的一组“健全性检查”来验证答复是否包含有效的时间更新。 然后,客户端会应用服务器时钟与其本地时钟的时间差(如果有)。 在广播模式下,客户端只需侦听时间更新广播,并在应用一组类似的健全性检查来验证更新时间数据后保持其本地时钟不变。 下面的“SNTP 健全性检查”部分中详细介绍了健全性检查。

客户端必须先建立其操作参数,然后才能在任一模式下运行。 通过针对单播或广播模式分别调用 nx_sntp_client_initialize_unicast 或 nx_sntp_client_initialize_broadcast 来完成此操作。 在没有有效更新、收到的连续无效更新的限制、单播模式的轮询间隔和操作模式(如单播与广播)和 SNTP 服务器的情况下,这些服务设置的超时时间最长。

如果超出接收到的最大超时或最大无效更新数,SNTP 客户端将继续运行,但会将当前 SNTP 服务器状态设置为无效。 应用程序可以使用 nx_sntp_client_receiving_updates 服务轮询 SNTP 客户端,以验证 SNTP 服务器是否仍在发送有效更新。 如果不是,则它应使用 nx_sntp_client_stop 服务停止 SNTP 客户端线程,并调用两项初始化服务中的任何一项来设置另一个 SNTP 服务器地址。 若要重新启动 SNTP 客户端,应用程序将调用 nx_sntp_client_run_broadcast 或 nx_sntp_client_run_unicast。 请注意,应用程序可以在初始化调用中更改 SNTP 客户端运行模式以根据需要切换到单播或广播。

本地时钟操作

SNTP 时间,基于主机 NTP 时钟上的秒数或在第一个 NTP 时期中运行的秒数,例如从 1 月 1 日 1900 00:00:00 到 1 月 1 日 1999 00:00:00。 01-01-1999 的意义在于最后一个闰秒发生的时间。 此值定义如下:

#define NTP_SECONDS_AT_01011999 0xBA368E80

在 SNTP 客户端运行之前,应用程序可以选择初始化该客户端的 SNTP 客户端本地时间,以用作基线时间。 为此,它必须使用 nx_sntp_client_set_local_time 服务。 此操作采用 NTP 格式的时间、秒和小数,其中小数是 NTP 压缩时间中的毫秒数。 理想情况下,应用程序可以从独立的源获取 SNTP 时间。 NetX Duo SNTP 客户端中没有将年、月、日期和时间转换为 NTP 时间的 API。 有关 NTP 时间格式的说明,请参阅 RFC4330“用于 IPv4、IPv6 和 OSI 的简单网络时间协议 (SNTP) 版本 4”。

如果 SNTP 客户端启动时未提供任何基准本地时间,则在第一次更新时,SNTP 客户端将接受 SNTP 更新,而不会与其本地时间进行比较。 此后,它将应用最大和最小时间更新值,以确定它是否会修改其本地时间。

若要获取 SNTP 客户端本地时间,应用程序可以使用 nx_sntp_client_get_local_time_extended 服务。

SNTP 健全性检查

客户端检查传入的数据包是否符合以下条件:

  • 源 IP 地址必须与当前服务器的 IP 地址匹配。

  • 发送方源端口必须与当前服务器源端口匹配。

  • 数据包的长度必须为保留 SNTP 时间消息所需的最小长度。

接下来,从数据包缓冲区中提取时间数据,然后客户端将对其应用一组特定的“健全性检查”:

  • Leap 指示符设置为 3,表示服务器未同步。 客户端应尝试查找备用服务器。

  • 设置为“零”的“层次”字段称为“导致必败的操作 (KOD)”数据包。 此情况下的 SMTP 客户端 KOD 处理程序是用户定义的回调。 小型示例演示文件包含用于此种情况的简单 KOD 处理程序。 “引用 ID”字段可选择包含指示 KOD 答复原因的代码。 在任何速率下,KOD 处理程序都必须指示如何处理从 SNTP 服务器接收导致必败的操作 (kiss of death)。 通常情况下,它需要通过另一个 SNTP 服务器重新初始化 SNTP 客户端。

  • 服务器 SNTP 版本、层次和操作模式均必须与客户端服务匹配。

  • 如果客户端配置了服务器时钟最大离散,则客户端仅会在接收的第一个更新时检查服务器时钟离散,如果它超过客户端最大值,客户端将拒绝服务器。

  • 服务器时间戳字段还必须通过特定检查。 对于单播服务器,必须填写所有时间字段,不能为 NULL。 在客户端的 SNTP 时间消息请求中,源时间戳必须等于传输时间戳。 这样可以免受客户端恶意入侵者和恶意服务器行为带来的影响。 广播服务器只需填写传输时间戳。 由于它不会从客户端接收任何内容,因此它没有要填写的接收或起源字段。

    失败的健全性检查将时间更新标记为无效的时间更新。 SNTP 客户端健全性检查服务跟踪从同一服务器收到的连续无效时间更新数。

当 SNTP 客户端线程任务检查 SNTP 数据包的有效性以应用于本地 SNTP 客户端时间,它会递增 SNTP 客户端 nx_sntp_client_invalid_time_updates. 的计数。它也会向调用方返回错误状态,但这是内部处理的全部,因此不会立即显示在应用程序中。 检测失败时间更新的方法是在收到 SNTP 服务器时间更新后查询 SNTP 客户端 nx_sntp_client_invalid_time_updates 的值。

如果服务器时间更新通过了健全性检查,之后客户端会尝试将时间数据处理为其本地时间。 如果将客户端配置为往返计算(例如从发送更新请求到收到请求的时间),则计算往返时间。 此值将被减半,然后会被添加到服务器的时间上。

接下来,如果这是从当前 SNTP 服务器收到的第一次更新,则 SNTP 客户端将确定其是否应忽略服务器和客户端本地时间之间的差值。 此后,将针对与客户端本地时间之间的差值评估 SNTP 服务器上的所有更新。

将客户端和服务器时间之间的差值与 NX_SNTP_CLIENT_MAX_TIME_ADJUSTMENT 进行比较。 如果超出此值,则将引发数据。如果差值小于 NX_SNTP_CLIENT_MIN_TIME_ADJUSTMENT,则认为差值过小,无需调整。

通过所有这些检查,然后将时间更新应用于 SNTP 客户端,并对内部 SNTP 客户端处理中的延迟进行一些更正。

SNTP 异步单播请求

SNTP 客户端允许主机应用程序异步发送来自 NTP 服务器的当前时间的单播请求。

UINT _nx_sntp_client_request_unicast_time(
NX_SNTP_CLIENT *client_ptr, 
UINT wait_option)

等待选项是等待响应的到期时间。

如果 NTP 服务器做出响应,则数据包将接受与前一部分中所述的相同处理和健全性检查,然后更新 SNTP 客户端本地时间。

如果调用返回成功完成,则应用程序可以调用 nx_sntp_client_utility_display_date_time 或 nx_sntp_client_get_local_time_extended 来获取更新的本地时间。

这些单播请求不会干扰发送下一个单播请求的正常 SNTP 客户端计划或下一个 NTP 广播的预期时间(如果是广播模式)。

定期本地时间更新

在 NX_SNTP_CLIENT_MAX_TIME_ADJUSTMENT 选项(以毫秒为单位)中设置对本地时间的最大调整。 在 NX_SNTP_CLIENT_UNICAST_POLL_INTERVAL 选项(以秒为单位)中设置单播 SNTP 客户端操作的轮询更新间隔。 如果轮询间隔大于最大调整,则在第一次服务器更新之后的后续服务器更新将遭到拒绝。 为避免出现这种情况,SNTP 客户端将定期更新定义为 NX_SNTP_UPDATE_TIMEOUT_INTERVAL 的本地时间。

如果记载 RTC 和服务器时间(SNTP 客户端本地时间应设置的时间)之间存在时间差,则 RTC 应同步到 SNTP 客户端时间(本用户指南中未针对此内容进行说明)。

由于 SNTP 服务器的更新频率不应超过每小时一次,因此轮询 SNTP 客户端的服务器更新或服务器状态的频率不应超出这一频率。 但是,SNTP 客户端应经常更新其本地时钟,以避免其与最大时间调整参数 NX_SNTP_CLIENT_MAX_TIME_LAPSE 相差过多。

或者,可将最大调整 NX_SNTP_CLIENT_MAX_TIME_LAPSE 设置为大于单播轮询更新(或预期的广播间隔)。 后者消除了独立实时时钟的需求。 但是,SNTP 协议的目的在于避免对本地 RTC 或网络时间更新的总体依赖。 此外,SNTP 服务器更新旨在防止本地时间时钟发生偏差。

多个网络接口

可以将 NetX Duo SNTP 客户端配置为在辅助网络上运行,只要这些网络注册了 IP 实例。 有关如何注册辅助网络的详细信息,请参阅 NetX Duo 或 NetX 用户指南。

在 nx_sntp_client_create 调用中,将第三个输入 iface_index 设置为要在其上接收时间更新的 SNTP 客户端的网络索引。 主接口始终位于索引 0 处。 NetX Duo SNTP 客户端无法同时支持多个网络接口上的时间更新。

SNTP 和 NTP RFC

NetX Duo SNTP 客户端符合 RFC4330“用于 IPv4、IPv6 和 OSI 的简单网络时间协议 (SNTP) 版本 4”和相关 RFC。