Network Working Group                                          J. Mogul
Request for Comments: 2783                                   Compaq WRL
Category: Informational                                        D. Mills
                                                 University of Delaware
                                                          J. Brittenson
                                                                    Sun
                                                               J. Stone
                                                               Stanford
                                                               U. Windl
                                                Universitaet Regensburg
                                                             March 2000
        
Network Working Group                                          J. Mogul
Request for Comments: 2783                                   Compaq WRL
Category: Informational                                        D. Mills
                                                 University of Delaware
                                                          J. Brittenson
                                                                    Sun
                                                               J. Stone
                                                               Stanford
                                                               U. Windl
                                                Universitaet Regensburg
                                                             March 2000
        

Pulse-Per-Second API for UNIX-like Operating Systems, Version 1.0

用于类UNIX操作系统的每秒脉冲API,版本1.0

Status of this Memo

本备忘录的状况

This memo provides information for the Internet community. It does not specify an Internet standard of any kind. Distribution of this memo is unlimited.

本备忘录为互联网社区提供信息。它没有规定任何类型的互联网标准。本备忘录的分发不受限制。

Copyright Notice

版权公告

Copyright (C) The Internet Society (2000). All Rights Reserved.

版权所有(C)互联网协会(2000年)。版权所有。

Abstract

摘要

RFC 1589 describes a UNIX kernel implementation model for high-precision time-keeping. This model is meant for use in conjunction with the Network Time Protocol (NTP, RFC 1305), or similar time synchronization protocols. One aspect of this model is an accurate interface to the high-accuracy, one pulse-per-second (PPS) output typically available from precise time sources (such as a GPS or GOES receiver). RFC 1589 did not define an API for managing the PPS facility, leaving implementors without a portable means for using PPS sources. This document specifies such an API.

RFC1589描述了用于高精度计时的UNIX内核实现模型。该模型旨在与网络时间协议(NTP、RFC 1305)或类似的时间同步协议结合使用。该模型的一个方面是高精度、每秒一个脉冲(PPS)输出的精确接口,通常可从精确时间源(如GPS或GOES接收器)获得。RFC1589没有定义用于管理PPS设施的API,使得实施者无法使用PPS源。本文档指定了这样一个API。

Table of Contents

目录

   1 Introduction...................................................  2
   2 Data types for representing timestamps.........................  4
   2.1 Resolution...................................................  4
   2.2 Time scale...................................................  5
   3 API............................................................  5
   3.1 PPS abstraction..............................................  6
   3.2 New data structures..........................................  7
   3.3 Mode bit definitions......................................... 10
   3.4 New functions................................................ 12
   3.4.1 New functions: obtaining PPS sources....................... 13
   3.4.2 New functions: setting PPS parameters...................... 14
   3.4.3 New functions: access to PPS timestamps.................... 16
   3.4.4 New functions: disciplining the kernel timebase............ 18
   3.5 Compliance rules............................................. 20
   3.5.1 Functions.................................................. 20
   3.5.2 Mode bits.................................................. 20
   3.6 Examples..................................................... 21
   4 Security Considerations........................................ 24
   5 Acknowledgements............................................... 24
   6 References..................................................... 25
   7 Authors' Addresses............................................. 26
   A. Extensions and related APIs................................... 27
   A.1 Extension: Parameters for the "echo" mechanism............... 27
   A.2 Extension: Obtaining information about external clocks....... 27
   A.3 Extension: Finding a PPS source.............................. 28
   B. Example implementation: PPSDISC Line discipline............... 29
   B.1 Example...................................................... 29
   C. Available implementations..................................... 30
   Full Copyright Statement......................................... 31
        
   1 Introduction...................................................  2
   2 Data types for representing timestamps.........................  4
   2.1 Resolution...................................................  4
   2.2 Time scale...................................................  5
   3 API............................................................  5
   3.1 PPS abstraction..............................................  6
   3.2 New data structures..........................................  7
   3.3 Mode bit definitions......................................... 10
   3.4 New functions................................................ 12
   3.4.1 New functions: obtaining PPS sources....................... 13
   3.4.2 New functions: setting PPS parameters...................... 14
   3.4.3 New functions: access to PPS timestamps.................... 16
   3.4.4 New functions: disciplining the kernel timebase............ 18
   3.5 Compliance rules............................................. 20
   3.5.1 Functions.................................................. 20
   3.5.2 Mode bits.................................................. 20
   3.6 Examples..................................................... 21
   4 Security Considerations........................................ 24
   5 Acknowledgements............................................... 24
   6 References..................................................... 25
   7 Authors' Addresses............................................. 26
   A. Extensions and related APIs................................... 27
   A.1 Extension: Parameters for the "echo" mechanism............... 27
   A.2 Extension: Obtaining information about external clocks....... 27
   A.3 Extension: Finding a PPS source.............................. 28
   B. Example implementation: PPSDISC Line discipline............... 29
   B.1 Example...................................................... 29
   C. Available implementations..................................... 30
   Full Copyright Statement......................................... 31
        

1 Introduction

1导言

RFC 1589 [4] describes a model and programming interface for generic operating system software that manages the system clock and timer functions. The model provides improved accuracy and stability for most workstations and servers using the Network Time Protocol (NTP) [3] or similar time synchronization protocol. The model supports the use of external timing sources, such as the precision pulse-per-second (PPS) signals typically available from precise time sources (such as a GPS or GOES receiver).

RFC 1589[4]描述了管理系统时钟和定时器功能的通用操作系统软件的模型和编程接口。该模型为大多数使用网络时间协议(NTP)[3]或类似时间同步协议的工作站和服务器提供了更高的准确性和稳定性。该模型支持使用外部定时源,例如通常可从精确时间源(如GPS或GOES接收器)获得的每秒精密脉冲(PPS)信号。

However, RFC 1589 did not define an application programming interface (API) for the PPS facility. This document specifies such an interface, for use with UNIX (or UNIX-like) operating systems. Such systems often conform to the "Single UNIX Specification" [5], sometimes known as POSIX.

然而,RFC1589没有为PPS设施定义应用程序编程接口(API)。本文档指定了这样一个接口,用于UNIX(或类似UNIX的)操作系统。此类系统通常符合“单一UNIX规范”[5],有时称为POSIX。

One convenient means to provide a PPS signal to a computer system is to connect that signal to a modem-control pin on a serial-line interface to the computer. The Data Carrier Detect (DCD) pin is frequently used for this purpose. Typically, the time-code output of the time source is transmitted to the computer over the same serial line. The computer detects a signal transition on the DCD pin, usually by receiving an interrupt, and records a timestamp as soon as possible.

向计算机系统提供PPS信号的一种方便方法是将该信号连接到计算机串行线接口上的调制解调器控制引脚。数据载波检测(DCD)引脚经常用于此目的。通常,时间源的时间代码输出通过相同的串行线传输到计算机。计算机通常通过接收中断来检测DCD引脚上的信号转换,并尽快记录时间戳。

Although existing practice has focussed on the use of serial lines and DCD transitions, PPS signals might also be delivered by other kinds of devices. The API specified in this document does not require the use of a serial line, although it may be somewhat biased in that direction.

尽管现有实践集中于使用串行线和DCD转换,PPS信号也可能由其他类型的设备传输。本文档中指定的API不需要使用串行线,尽管它可能在该方向上有所偏差。

The typical use of this facility is for the operating system to record ("capture") a high-resolution timestamp as soon as possible after it detects a PPS signal transition (usually indicated by an interrupt). This timestamp can then be made available, with less stringent delay constraints, to time-related software. The software can compare the captured timestamp to the received time-code to accurately discover the offset between the system clock and the precise time source.

此功能的典型用途是,操作系统在检测到PPS信号转换(通常由中断指示)后,尽快记录(“捕获”)高分辨率时间戳。然后,该时间戳可以在不太严格的延迟约束下提供给与时间相关的软件。软件可以将捕获的时间戳与接收到的时间码进行比较,以准确发现系统时钟与精确时间源之间的偏移量。

The operating system may also deliver the PPS event to a kernel procedure, called the "in-kernel PPS consumer." One example would be the "hardpps()" procedure, described in RFC 1589, which is used to discipline the kernel's internal timebase.

操作系统还可以将PPS事件传递给内核过程,称为“内核内PPS使用者”。RFC 1589中描述的“hardpps()”过程就是一个例子,该过程用于规范内核的内部时基。

The API specified in this document allows for one or more signal sources attached to a computer system to provide PPS inputs, at the option of user-level software. User-level software may obtain signal-transition timestamps for any of these PPS sources. User-level software may optionally specify at most one of these PPS sources to be used to discipline the system's internal timebase.

本文件中规定的API允许连接到计算机系统的一个或多个信号源提供PPS输入,由用户级软件选择。用户级软件可获得这些PPS源中任何一个的信号转换时间戳。用户级软件可以选择指定最多一个PPS源,用于规范系统的内部时基。

Although the primary purpose of this API is for capturing true pulse-per-second events, the API may also be used for accurately timestamping events of other periods, or even aperiodic events, when these can be expressed as signal transitions.

尽管该API的主要目的是捕获真实的每秒脉冲事件,但该API还可用于准确地为其他时段的事件、甚至非周期事件加时间戳,当这些事件可表示为信号转换时。

This document does not define internal details of how the API must be implemented, and does not specify constraints on the accuracy, resolution, or latency of the PPS feature. However, the utility of this feature is inversely proportional to the delay (and variance of delay), and implementors are encouraged to take this seriously.

本文档未定义API必须如何实现的内部细节,也未指定PPS功能的准确性、分辨率或延迟限制。然而,该特性的效用与延迟(以及延迟的方差)成反比,我们鼓励实现者认真对待这一点。

In principle, the rate of events to be captured, or the frequency of the signals, can range from once per day (or less often) to several thousand per second. However, since in most implementations the timestamping function will be implemented as a processor interrupt at a relatively high priority, it is prudent to limit the rate of such events. This may be done either by mechanisms in the hardware that generates the signals, or by the operating system.

原则上,要捕获的事件的速率或信号的频率可以从每天一次(或更少)到每秒几千次不等。然而,由于在大多数实现中,时间戳功能将以相对较高的优先级作为处理器中断来实现,因此谨慎地限制此类事件的速率。这可以通过硬件中生成信号的机制或操作系统来完成。

2 Data types for representing timestamps

用于表示时间戳的2种数据类型

Computer systems use various representations of time. Because this API is concerned with the provision of high-accuracy, high-resolution time information, the choice of representation is significant. (Here we consider only binary representations, not human-format representations.)

计算机系统使用各种时间表示法。由于此API涉及提供高精度、高分辨率的时间信息,因此表示方式的选择非常重要。(这里我们只考虑二进制表示,而不是人类格式表示。)

The two interesting questions are:

这两个有趣的问题是:

1. what is the resolution of the representation?

1. 代表的决议是什么?

2. what time scale is represented?

2. 所代表的时间尺度是什么?

These questions often lead to contentious arguments. Since this API is intended for use with NTP and POSIX-compliant systems, however, we can limit the choices to representations compatible with existing NTP and POSIX practice, even if that practice is considered "wrong" in some quarters.

这些问题往往导致有争议的争论。由于此API旨在与NTP和POSIX兼容的系统一起使用,因此我们可以将选择限制为与现有NTP和POSIX实践兼容的表示,即使在某些方面认为该实践是“错误的”。

2.1 Resolution
2.1 决议

In the NTP protocol, "timestamps are represented as a 64-bit unsigned fixed-point number, in seconds relative to 0h on 1 January 1900. The integer part is in the first 32 bits and the fraction part in the last 32 bits [...] The precision of this representation is about 200 picoseconds" [3].

在NTP协议中,“时间戳表示为64位无符号定点数字,相对于1900年1月1日的0h,以秒为单位。整数部分在前32位,小数部分在后32位[…]此表示的精度约为200皮秒”[3]。

However, most computer systems cannot measure time to this resolution (this represents a clock rate of 5 GHz). The POSIX gettimeofday() function returns a "struct timeval" value, with a resolution of 1 microsecond. The POSIX clock_gettime() function returns a "struct timespec" value, with a resolution of 1 nanosecond.

然而,大多数计算机系统无法测量达到该分辨率的时间(这表示5 GHz的时钟频率)。函数的作用是:返回一个“struct timeval”值,分辨率为1微秒。函数的作用是:返回一个“struct timespec”值,分辨率为1纳秒。

This API uses an extensible representation, but defaults to the "struct timespec" representation.

此API使用可扩展表示,但默认为“struct timespec”表示。

2.2 Time scale
2.2 时间尺度

Several different time scales have been proposed for use in computer systems. UTC and TAI are the two obvious candidates.

在计算机系统中已经提出了几种不同的时间尺度。UTC和TAI是两个明显的候选者。

Some people would prefer the use of TAI, which is identical to UTC except that it does not correct for leap seconds. Their preference for TAI stems from the difficulty of computing precise time differences when leap seconds are involved, especially when using times in the future (for which the exact number of leap seconds is, in general, unknowable).

有些人更喜欢使用TAI,它与UTC相同,只是它不适用于闰秒。他们对TAI的偏好源于在涉及闰秒时难以计算精确的时差,特别是在将来使用时间时(通常,闰秒的确切数量是不可知的)。

However, POSIX and NTP both use UTC, albeit with different base dates. Given that support for TAI would, in general, require other changes to the POSIX specification, this API uses the POSIX base date of 00:00 January 1, 1970 UTC, and conforms to the POSIX use of the UTC time scale.

然而,POSIX和NTP都使用UTC,尽管基准日期不同。鉴于对TAI的支持通常需要对POSIX规范进行其他更改,此API使用POSIX基准日期UTC 1970年1月1日00:00,并符合POSIX对UTC时间刻度的使用。

3 API

3 API

A PPS facility can be used in two different ways:

PPS设施可通过两种不同的方式使用:

1. An application can obtain a timestamp, using the system's internal timebase, for the most recent PPS event.

1. 应用程序可以使用系统的内部时基获取最近PPS事件的时间戳。

2. The kernel may directly utilize PPS events to discipline its internal timebase, thereby providing highly accurate time to all applications.

2. 内核可以直接利用PPS事件来调整其内部时基,从而为所有应用程序提供高度精确的时间。

This API supports both uses, individually or in combination. The timestamping feature may be used on any number of PPS sources simultaneously; the timebase-disciplining feature may be used with at most one PPS source.

此API支持单独使用或组合使用。时间戳特征可同时用于任意数量的PPS源;时基规则功能最多可用于一个PPS源。

Although the proper implementation of this API requires support from the kernel of a UNIX system, this document defines the API in terms of a set of library routines. This gives the implementor some freedom to divide the effort between kernel code and library code (different divisions might be appropriate on microkernels and monolithic kernels, for example).

尽管此API的正确实现需要UNIX系统内核的支持,但本文档根据一组库例程定义了API。这给了实现者一些在内核代码和库代码之间划分工作的自由(例如,不同的划分可能适用于微内核和单片内核)。

3.1 PPS abstraction
3.1 PPS抽象

A PPS signal consists of a series of pulses, each with an "asserted" (logical true) phase, and a "clear" (logical false) phase. The two phases may be of different lengths. The API may capture an "assert timestamp" at the moment of the transition into the asserted phase, and a "clear timestamp" at the moment of the transition into the clear phase.

PPS信号由一系列脉冲组成,每个脉冲具有“断言”(逻辑真)相位和“清除”(逻辑假)相位。这两个阶段可能具有不同的长度。API可以在转换到断言阶段的时刻捕获“断言时间戳”,并在转换到清除阶段的时刻捕获“清除时间戳”。

The specific assignment of the logical values "true" and "false" with specific voltages of a PPS signal, if applicable, is outside the scope of this specification. However, these assignments SHOULD be consistent with applicable standards. Implementors of PPS sources SHOULD document these assignments.

PPS信号特定电压下逻辑值“真”和“假”的具体分配(如适用)不在本规范范围内。但是,这些分配应符合适用标准。PPS源的实施者应记录这些任务。

Reminder to implementors of DCD-based PPS support: TTL and RS-232C (V.24/V.28) interfaces both define the "true" state as the one having the highest positive voltage. TTL defines a nominal absence of voltage as the "false" state, but RS-232C (V.24/V.28) defines the "false" state by the presence of a negative voltage.

提醒基于DCD的PPS支持的实施者:TTL和RS-232C(V.24/V.28)接口都将“真实”状态定义为具有最高正电压的状态。TTL将标称无电压定义为“假”状态,但RS-232C(V.24/V.28)通过存在负电压定义为“假”状态。

The API supports the direct provision of PPS events (and timestamps) to an in-kernel PPS consumer. This could be the function called "hardpps()", as described in RFC 1589 [4], but the API does not require the kernel implementation to use that function name internally. The current version of the API supports at most one in-kernel PPS consumer, and does not provide a way to explicitly name it. The implementation SHOULD impose access controls on the use of this feature.

API支持直接向内核内PPS使用者提供PPS事件(和时间戳)。这可能是RFC1589[4]中描述的名为“hardpps()”的函数,但API不要求内核实现在内部使用该函数名。当前版本的API最多支持一个内核PPS使用者,并且没有提供显式命名它的方法。实现应该对该功能的使用实施访问控制。

The API optionally supports an "echo" feature, in which events on the incoming PPS signal may be reflected through software, after the capture of the corresponding timestamp, to an output signal pin. This feature may be used to discover an upper bound on the actual delay between the edges of the PPS signal and the capture of the timestamps; such information may be useful in precise calibration of the system.

API可选地支持“echo”特性,其中,在捕获相应的时间戳之后,传入PPS信号上的事件可以通过软件反射到输出信号管脚。该特征可用于发现PPS信号的边缘与时间戳的捕获之间的实际延迟的上界;这些信息可能有助于系统的精确校准。

The designation of an output pin for the echo signal, and sense and shape of the output transition, is outside the scope of this specification, but SHOULD be documented for each implementation. The output pin MAY also undergo transitions at other times besides those caused by PPS input events.

回波信号输出引脚的指定以及输出转换的感测和形状不在本规范的范围内,但应针对每个实施进行记录。除了PPS输入事件引起的转换外,输出引脚还可能在其他时间发生转换。

Note: this allows an implementation of the echo feature to generate an output pulse per input pulse, or an output edge per input pulse, or an output pulse per input edge. It also allows the same signal pin to be used for several purposes simultaneously.

注:这允许回声功能的实现为每个输入脉冲生成一个输出脉冲,或为每个输入脉冲生成一个输出边,或为每个输入边生成一个输出脉冲。它还允许相同的信号引脚同时用于多种用途。

Also, the API optionally provides an application with the ability to specify an offset value to be applied to captured timestamps. This can be used to correct for cable and/or radio-wave propagation delays, or to compensate for systematic jitter in the external signal. The implementation SHOULD impose access controls on the use of this feature.

此外,API还可选地为应用程序提供指定要应用于捕获的时间戳的偏移值的能力。这可用于纠正电缆和/或无线电波传播延迟,或补偿外部信号中的系统抖动。实现应该对该功能的使用实施访问控制。

3.2 New data structures
3.2 新的数据结构

The data structure declarations and symbol definitions for this API will appear in the header file <sys/timepps.h>. The header file MUST define all constants described in this specification, even if they are not supported by the implementation.

此API的数据结构声明和符号定义将显示在头文件<sys/timepps.h>中。头文件必须定义本规范中描述的所有常量,即使实现不支持这些常量。

The API includes several implementation-specific types:

API包括几种特定于实现的类型:

      typedef ... pps_handle_t;       /* represents a PPS source */
        
      typedef ... pps_handle_t;       /* represents a PPS source */
        
      typedef unsigned ... pps_seq_t; /* sequence number */
        
      typedef unsigned ... pps_seq_t; /* sequence number */
        

The "pps_handle_t" type is an opaque scalar type used to represent a PPS source within the API.

“pps\u handle\u t”类型是一种不透明的标量类型,用于表示API中的pps源。

The "pps_seq_t" type is an unsigned integer data type of at least 32 bits.

“pps_seq_t”类型是至少32位的无符号整数数据类型。

The precise declaration of the pps_handle_t and pps_seq_t types is system-dependent.

pps_handle_t和pps_seq_t类型的精确声明取决于系统。

The API imports the standard POSIX definition for this data type:

API导入此数据类型的标准POSIX定义:

      struct timespec {
              time_t  tv_sec;         /* seconds */
              long    tv_nsec;        /* nanoseconds */
      };
        
      struct timespec {
              time_t  tv_sec;         /* seconds */
              long    tv_nsec;        /* nanoseconds */
      };
        

The API defines this structure as an internal (not "on the wire") representation of the NTP "64-bit unsigned fixed-point" timestamp format [3]:

API将此结构定义为NTP“64位无符号定点”时间戳格式[3]的内部(而非“在线”)表示形式:

      typedef struct ntp_fp {
              unsigned int    integral;
              unsigned int    fractional;
      } ntp_fp_t;
        
      typedef struct ntp_fp {
              unsigned int    integral;
              unsigned int    fractional;
      } ntp_fp_t;
        

The two fields in this structure may be declared as any unsigned integral type, each of at least 32 bits.

此结构中的两个字段可以声明为任何无符号整数类型,每个字段至少有32位。

The API defines this new union as an extensible type for representing times:

API将此新联合定义为可扩展类型,用于表示时间:

      typedef union pps_timeu {
              struct timespec tspec;
              ntp_fp_t        ntpfp;
              unsigned long   longpad[3];
      } pps_timeu_t;
        
      typedef union pps_timeu {
              struct timespec tspec;
              ntp_fp_t        ntpfp;
              unsigned long   longpad[3];
      } pps_timeu_t;
        

Future revisions of this specification may add more fields to this union.

本规范的未来版本可能会向该联合体添加更多字段。

Note: adding a field to this union that is larger than 3*sizeof(long) will break binary compatibility.

注意:将大于3*sizeof(long)的字段添加到此联合会将破坏二进制兼容性。

The API defines these new data structures:

API定义了这些新的数据结构:

      typedef struct {
          pps_seq_t   assert_sequence;        /* assert event seq # */
          pps_seq_t   clear_sequence;         /* clear event seq # */
          pps_timeu_t assert_tu;
          pps_timeu_t clear_tu;
          int         current_mode;           /* current mode bits */
      } pps_info_t;
        
      typedef struct {
          pps_seq_t   assert_sequence;        /* assert event seq # */
          pps_seq_t   clear_sequence;         /* clear event seq # */
          pps_timeu_t assert_tu;
          pps_timeu_t clear_tu;
          int         current_mode;           /* current mode bits */
      } pps_info_t;
        

#define assert_timestamp assert_tu.tspec #define clear_timestamp clear_tu.tspec

#定义assert_timestamp assert_tu.tspec#定义clear_timestamp clear_tu.tspec

#define assert_timestamp_ntpfp assert_tu.ntpfp #define clear_timestamp_ntpfp clear_tu.ntpfp

#定义assert_timestamp_ntpfp assert_tu.ntpfp#定义clear_timestamp_ntpfp clear_tu.ntpfp

      typedef struct {
          int         api_version;            /* API version # */
          int         mode;                   /* mode bits */
          pps_timeu_t assert_off_tu;
          pps_timeu_t clear_off_tu;
      } pps_params_t;
        
      typedef struct {
          int         api_version;            /* API version # */
          int         mode;                   /* mode bits */
          pps_timeu_t assert_off_tu;
          pps_timeu_t clear_off_tu;
      } pps_params_t;
        

#define assert_offset assert_off_tu.tspec #define clear_offset clear_off_tu.tspec

#定义assert_offset assert_off_tu.tspec#定义clear_offset clear_off_tu.tspec

#define assert_offset_ntpfp assert_off_tu.ntpfp #define clear_offset_ntpfp clear_off_tu.ntpfp

#定义assert_offset_ntpfp assert_off_tu.ntpfp#定义clear_offset_ntpfp clear_off_tu.ntpfp

The "pps_info_t" type is returned on an inquiry to PPS source. It contains the timestamps for the most recent assert event, and the most recent clear event. The order in which these events were actually received is defined by the timetamps, not by any other

“pps\u信息”类型在查询pps源时返回。它包含最近的断言事件和最近的清除事件的时间戳。实际接收这些事件的顺序由时间戳定义,而不是由任何其他时间戳定义

aspect of the specification. Each timestamp field represents the value of the operating system's internal timebase when the timestamped event occurred, or as close as possible to that time (with the optional addition of a specified offset). The current_mode field contains the value of the mode bits (see section 3.3) at the time of the most recent transition was captured for this PPS source. An application can use current_mode to discover the format of the timestamps returned.

规范的方面。每个时间戳字段表示时间戳事件发生时操作系统的内部时基值,或尽可能接近该时间(可选添加指定偏移量)。current_mode(当前_模式)字段包含为该PPS源捕获最新转换时的模式位值(见第3.3节)。应用程序可以使用当前_模式来发现返回的时间戳的格式。

The assert_sequence number increases once per captured assert timestamp. Its initial value is undefined. If incremented past the largest value for the type, the next value is zero. The clear_sequence number increases once per captured clear timestamp. Its initial value is undefined, and may be different from the initial value of assert_sequence. If incremented past the largest value for the type, the next value is zero. Due to possible signal loss or excessive signal noise, the assert-sequence number and the clear-sequence number might not always increase in step with each other.

每个捕获的断言时间戳,断言\u序列号增加一次。其初始值未定义。如果增量超过类型的最大值,则下一个值为零。清除序列号每捕获一个清除时间戳增加一次。它的初始值未定义,可能与assert_序列的初始值不同。如果增量超过类型的最大值,则下一个值为零。由于可能的信号丢失或过多的信号噪声,断言序列号和清除序列号可能并不总是同步增加。

Note that these sequence numbers are most useful in applications where events other than PPS transitions are to be captured, which might be involved in a precision stopwatch application, for example. In such cases, the sequence numbers may be used to detect overruns, where the application has missed one or more events. They may also be used to detect an excessive event rate, or to detect that an event has failed to occur between two calls to the time_pps_fetch() function (defined later).

请注意,这些序列号在要捕获PPS转换以外的事件的应用程序中最有用,例如,在精密秒表应用程序中可能会涉及到这些事件。在这种情况下,序列号可用于检测溢出,其中应用程序错过了一个或多个事件。它们还可用于检测过高的事件速率,或检测在两次调用time_pps_fetch()函数(稍后定义)之间未发生事件。

In order to obtain an uninterrupted series of sequence numbers (and hence of event timestamps), it may be necessary to sample the pps_info_t values at a rate somewhat faster than the underlying event rate. For example, an application interested in both assert and clear timestamps may need to sample at least twice per second. Proper use of the sequence numbers allows an application to discover if it has missed any event timestamps due to an insufficient sampling rate.

为了获得一系列不间断的序列号(从而获得事件时间戳),可能需要以略快于基本事件速率的速率对pps\u info\t值进行采样。例如,对断言和清除时间戳都感兴趣的应用程序可能需要每秒至少采样两次。正确使用序列号允许应用程序发现是否由于采样率不足而错过了任何事件时间戳。

The pps_params_t data type is used to discover and modify parameters of a PPS source. The data type includes a mode field, described in section 3.3. It also includes an api_version field, a read-only value giving the version of the API. Currently, the only defined value is:

pps_参数数据类型用于发现和修改pps源的参数。数据类型包括模式字段,如第3.3节所述。它还包括一个api_version字段,该字段是一个只读值,表示api的版本。目前,唯一定义的值是:

#define PPS_API_VERS_1 1

#定义PPS_API_VERS_1 1

This field is present to enable binary compatibility with future versions of the API.

此字段用于启用与API未来版本的二进制兼容性。

Note: the term "read-only" in this specification means that an application cannot modify the relevant data item; only the implementation can modify the value. The implementation MUST ignore attempts by the application to modify a read-only field.

注:本规范中的术语“只读”表示应用程序不能修改相关数据项;只有实现可以修改该值。实现必须忽略应用程序修改只读字段的尝试。

As an OPTIONAL feature of the API, the implementation MAY support adding offsets to the timestamps that are captured. (Values of type "struct timespec" can represent negative offsets.) The assert_offset field of a pps_params_t value specifies a value to be added to generate a captured assert_timestamp. The clear_offset of a pps_params_t value field specifies a value to be added to generate a captured clear_timestamp. Since the offsets, if any, apply to all users of a given PPS source, the implementation SHOULD impose access controls on the use of this feature; for example, allowing only the super-user to set the offset values. The default value for both offsets is zero.

作为API的可选特性,该实现可以支持向捕获的时间戳添加偏移量。(类型为“struct timespec”的值可以表示负偏移量。)pps_params_t值的assert_offset字段指定要添加的值,以生成捕获的assert_时间戳。pps_参数值字段的clear_偏移量指定要添加的值,以生成捕获的clear_时间戳。由于偏移量(如有)适用于给定PPS源的所有用户,因此实施应对该功能的使用实施访问控制;例如,仅允许超级用户设置偏移值。两个偏移的默认值均为零。

3.3 Mode bit definitions
3.3 模式位定义

A set of mode bits is associated with each PPS source.

一组模式位与每个PPS源相关联。

The bits in the mode field of the pps_params_t type are:

pps参数类型的模式字段中的位为:

      /* Device/implementation parameters */
      #define PPS_CAPTUREASSERT       0x01
      #define PPS_CAPTURECLEAR        0x02
      #define PPS_CAPTUREBOTH         0x03
        
      /* Device/implementation parameters */
      #define PPS_CAPTUREASSERT       0x01
      #define PPS_CAPTURECLEAR        0x02
      #define PPS_CAPTUREBOTH         0x03
        

#define PPS_OFFSETASSERT 0x10 #define PPS_OFFSETCLEAR 0x20

#定义PPS_偏移开始0x10#定义PPS_偏移清除0x20

#define PPS_CANWAIT 0x100 #define PPS_CANPOLL 0x200

#定义PPS_CANWAIT 0x100#定义PPS_CANPOLL 0x200

      /* Kernel actions */
      #define PPS_ECHOASSERT          0x40
      #define PPS_ECHOCLEAR           0x80
        
      /* Kernel actions */
      #define PPS_ECHOASSERT          0x40
      #define PPS_ECHOCLEAR           0x80
        
      /* Timestamp formats */
      #define PPS_TSFMT_TSPEC         0x1000
      #define PPS_TSFMT_NTPFP         0x2000
        
      /* Timestamp formats */
      #define PPS_TSFMT_TSPEC         0x1000
      #define PPS_TSFMT_NTPFP         0x2000
        

These mode bits are divided into three categories:

这些模式位分为三类:

1. Device/implementation parameters: These are parameters either of the device or of the implementation. If the implementation allows these to be changed, then these bits are read/write for users with sufficient privilege (such as the super-user), and

1. 设备/实现参数:这些是设备或实现的参数。如果实现允许更改这些位,那么这些位将为具有足够权限的用户(如超级用户)读/写,并且

read-only for other users. If the implementation does not allow these bits to be changed, they are read-only.

其他用户只读。如果实现不允许更改这些位,则它们是只读的。

2. Kernel actions: These bits specify certain kernel actions to be taken on arrival of a signal. If the implementation supports one of these actions, then the corresponding bit is read/write for users with sufficient privilege (such as the super-user), and read-only for other users. If the implementation does not support the action, the corresponding bit is always zero.

2. 内核操作:这些位指定信号到达时要采取的某些内核操作。如果实现支持这些操作之一,则对应的位对于具有足够权限的用户(如超级用户)是读/写的,而对于其他用户是只读的。如果实现不支持该操作,则相应的位始终为零。

3. Timestamp formats: These bits indicate the set of timestamp formats available for the device. They are always read-only.

3. 时间戳格式:这些位表示设备可用的时间戳格式集。它们总是只读的。

In more detail, the meanings of the Device/implementation parameter mode bits are:

更详细地说,设备/实现参数模式位的含义是:

PPS_CAPTUREASSERT If this bit is set, the assert timestamp for the associated PPS source will be captured.

PPS_CAPTUREASSERT如果设置了此位,则将捕获关联PPS源的断言时间戳。

PPS_CAPTURECLEAR If this bit is set, the clear timestamp for the associated PPS source will be captured.

PPS_CAPTURECLEAR如果设置了此位,则将捕获相关PPS源的清除时间戳。

PPS_CAPTUREBOTH Defined as the union of PPS_CAPTUREASSERT and PPS_CAPTURECLEAR, for convenience.

为方便起见,PPS_CAPTUREASSERT和PPS_CAPTURECLEAR均定义为PPS_CAPTUREASSERT和PPS_CAPTURECLEAR的联合体。

PPS_OFFSETASSERT If set, the assert_offset value is added to the current value of the operating system's internal timebase in order to generate the captured assert_timestamp.

PPS_OFFSETASSERT如果已设置,则将assert_offset值添加到操作系统内部时基的当前值,以生成捕获的assert_时间戳。

PPS_OFFSETCLEAR If set, the clear_offset value is added to the current value of the operating system's internal timebase in order to generate the captured clear_timestamp.

PPS_OFFSETCLEAR如果设置,则clear_offset值将添加到操作系统内部时基的当前值,以生成捕获的clear_时间戳。

PPS_CANWAIT If set, the application may request that the time_pps_fetch() function (see section 3.4.3) should block until the next timestamp arrives. Note: this mode bit is read-only.

PPS_CANWAIT如果设置,应用程序可能会请求time_PPS_fetch()函数(参见第3.4.3节)应阻止,直到下一个时间戳到达。注意:此模式位为只读。

PPS_CANPOLL This bit is reserved for future use. An application SHOULD NOT depend on any functionality implied either by its presence or by its absence.

PPS_CANPOLL此位保留供将来使用。应用程序不应依赖于其存在或不存在所隐含的任何功能。

If neither PPS_CAPTUREASSERT nor PPS_CAPTURECLEAR is set, no valid timestamp will be available via the API.

如果未设置PPS_CAPTUREASSERT或PPS_CAPTURECLEAR,则API将无法提供有效的时间戳。

The meanings of the Kernel action mode bits are:

内核操作模式位的含义如下:

PPS_ECHOASSERT If set, after the capture of an assert timestamp, the implementation generates a signal transition as rapidly as possible on an output signal pin. This MUST NOT affect the delay between the PPS source's transition to the asserted phase and the capture of the assert timestamp.

PPS_ECHOASSERT如果设置,则在捕获断言时间戳后,实现将在输出信号管脚上尽可能快地生成信号转换。这不得影响PPS源转换到断言阶段和捕获断言时间戳之间的延迟。

PPS_ECHOCLEAR If set, after the capture of a clear timestamp, the implementation generates a signal transition as rapidly as possible on an output signal pin. This MUST NOT affect the delay between the PPS source's transition to the clear phase and the capture of the clear timestamp.

PPS_ECHOCLEAR如果设置,则在捕获清除时间戳后,实现在输出信号管脚上尽可能快地生成信号转换。这不得影响PPS源转换到清除阶段和捕获清除时间戳之间的延迟。

The timestamp formats are:

时间戳格式为:

PPS_TSFMT_TSPEC Timestamps and offsets are represented as values of type "struct timespec". All implementations MUST support this format, and this format is the default unless an application specifies otherwise.

PPS_TSFMT_TSPEC时间戳和偏移量表示为“struct timespec”类型的值。所有实现都必须支持此格式,并且此格式是默认格式,除非应用程序另有指定。

PPS_TSFMT_NTPFP Timestamps and offsets are represented as values of type "ntp_fp_t", which corresponds to the NTP "64-bit unsigned fixed-point" timestamp format [3]. Support for this format is OPTIONAL.

PPS_TSFMT_NTPFP时间戳和偏移量表示为“ntp_fp_t”类型的值,对应于ntp“64位无符号定点”时间戳格式[3]。对此格式的支持是可选的。

Other timestamp format bits may be defined as fields are added to the "pps_timeu_t" union.

当字段添加到“pps_timeu_t”联合时,可以定义其他时间戳格式位。

The operating system may implement all of these mode bits, or just a subset of them. If an attempt is made to set an unsupported mode bit, the API will return an error. If an attempt is made to modify a read-only mode bit, the API will return an error.

操作系统可以实现所有这些模式位,或者只是其中的一个子集。如果试图设置不受支持的模式位,API将返回错误。如果试图修改只读模式位,API将返回错误。

3.4 New functions
3.4 新功能

In the description of functions that follows, we use the following function parameters:

在下面的函数描述中,我们使用以下函数参数:

filedes A file descriptor (type: int), for a serial line or other source of PPS events.

filedes文件描述符(类型:int),用于串行行或其他PPS事件源。

ppshandle A variable of type "pps_handle_t", as defined in section 3.2.

PPSHADLE第3.2节中定义的“pps_handle_t”类型的变量。

ppsinfobuf A record of type "pps_info_t", as defined in section 3.2.

ppsinfobuf第3.2节中定义的“pps_info_t”类型的记录。

ppsparams A record of type "pps_params_t", as defined in section 3.2.

pps参数是第3.2节中定义的“pps_参数S_t”类型的记录。

tsformat An integer with exactly one of the timestamp format bits set.

tsformat正好设置了一个时间戳格式位的整数。

3.4.1 New functions: obtaining PPS sources
3.4.1 新功能:获取PPS源

The API includes functions to create and destroy PPS source "handles".

API包含创建和销毁PPS源“句柄”的函数。

SYNOPSIS

提要

      int time_pps_create(int filedes, pps_handle_t *handle);
      int time_pps_destroy(pps_handle_t handle);
        
      int time_pps_create(int filedes, pps_handle_t *handle);
      int time_pps_destroy(pps_handle_t handle);
        

DESCRIPTION

描述

All of the other functions in the PPS API operate on PPS handles (type: pps_handle_t). The time_pps_create() is used to convert an already-open UNIX file descriptor, for an appropriate special file, into a PPS handle.

PPS API中的所有其他函数都在PPS句柄(类型:PPS\u handle\t)上运行。time_pps_create()用于将已打开的UNIX文件描述符(针对适当的特殊文件)转换为pps句柄。

The definition of what special files are appropriate for use with the PPS API is outside the scope of this specification, and may vary based on both operating system implementation, and local system configuration. One typical case is a serial line, whose DCD pin is connected to a source of PPS events.

适用于PPS API的特殊文件的定义不在本规范的范围内,可能因操作系统实现和本地系统配置而异。一种典型情况是串行线路,其DCD引脚连接到PPS事件源。

The mode in which the UNIX file descriptor was originally opened affects what operations are allowed on the PPS handle. The time_pps_setparams() and time_pps_kcbind() functions (see sections 3.4.2 and 3.4.4) SHOULD be prohibited by the implementation if the descriptor is open only for reading (O_RDONLY).

UNIX文件描述符最初打开的模式会影响PPS句柄上允许的操作。如果描述符仅为读取而打开(O_RDONLY),则实现应禁止使用time_pps_setparams()和time_pps_kcbind()函数(参见第3.4.2和3.4.4节)。

Note: operations on a descriptor opened with an inappropriate mode might fail with EBADF.

注意:使用EBADF对以不适当模式打开的描述符的操作可能会失败。

The time_pps_destroy() function makes the PPS handle unusable, and frees any storage that might have been allocated for it. It does not close the associated file descriptor, nor does it change any of the parameter settings for the PPS source.

time_pps_destroy()函数使pps句柄不可用,并释放可能已分配给它的所有存储。它不会关闭关联的文件描述符,也不会更改PPS源的任何参数设置。

Note: If this API is adapted to an operating system that does not follow UNIX conventions for representing an accessible PPS source as an integer file descriptor, the time_pps_create() function may take different parameters from those shown here.

注意:如果此API适用于不遵循UNIX约定将可访问PPS源表示为整数文件描述符的操作系统,则time_PPS_create()函数的参数可能与此处显示的参数不同。

RETURN VALUES

返回值

On successful completion, the time_pps_create() function returns 0. Otherwise, a value of -1 is returned and errno is set to indicate the error.

成功完成后,time_pps_create()函数返回0。否则,将返回值-1,并设置errno以指示错误。

If called with a valid handle parameter, the time_pps_destroy() function returns 0. Otherwise, it returns -1.

如果使用有效的handle参数调用,time_pps_destroy()函数将返回0。否则,它返回-1。

ERRORS

错误

If the time_pps_create() function fails, errno may be set to one of the following values:

如果time_pps_create()函数失败,可以将errno设置为以下值之一:

[EBADF] The filedes parameter is not a valid file descriptor.

[EBADF]filedes参数不是有效的文件描述符。

[EOPNOTSUPP] The use of the PPS API is not supported for the file descriptor.

[EOPNOTSUPP]文件描述符不支持使用PPS API。

[EPERM] The process's effective user ID does not have the required privileges to use the PPS API.

[EPERM]流程的有效用户ID没有使用PPS API所需的权限。

3.4.2 New functions: setting PPS parameters
3.4.2 新功能:设置PPS参数

The API includes several functions use to set or obtain the parameters of a PPS source.

API包括几个用于设置或获取PPS源参数的函数。

SYNOPSIS

提要

      int time_pps_setparams(pps_handle_t handle,
                              const pps_params_t *ppsparams);
      int time_pps_getparams(pps_handle_t handle,
                              pps_params_t *ppsparams);
      int time_pps_getcap(pps_handle_t handle, int *mode);
        
      int time_pps_setparams(pps_handle_t handle,
                              const pps_params_t *ppsparams);
      int time_pps_getparams(pps_handle_t handle,
                              pps_params_t *ppsparams);
      int time_pps_getcap(pps_handle_t handle, int *mode);
        

DESCRIPTION

描述

A suitably privileged application may use time_pps_setparams() to set the parameters (mode bits and timestamp offsets) for a PPS source. The pps_params_t type is defined in section 3.2; mode bits are defined in section 3.3. An application may use time_pps_getparams() to discover the current settings of the PPS parameters. An application that needs to change only a subset of the existing

具有适当特权的应用程序可以使用time_pps_setparams()为pps源设置参数(模式位和时间戳偏移)。pps参数类型在第3.2节中定义;模式位在第3.3节中定义。应用程序可以使用time_pps_getparams()来发现pps参数的当前设置。只需要更改现有应用程序的一个子集的应用程序

parameters must first call time_pps_getparams() to obtain the current parameter values, then set the new values using time_pps_setparams().

参数必须首先调用time_pps_getparams()以获取当前参数值,然后使用time_pps_setparams()设置新值。

Note: a call to time_pps_setparams() replaces the current values of all mode bits with those specified via the ppsparams argument, except those bits whose state cannot be changed. Bits might be read-only due to access controls, or because they are fixed by the implementation.

注意:调用time_pps_setparams()会将所有模式位的当前值替换为通过ppsparams参数指定的值,但状态无法更改的位除外。位可能是只读的,这是因为访问控制,或者因为它们是由实现固定的。

The timestamp format of the assert_offset and clear_offset fields is defined by the mode field. That is, on a call to time_pps_setparams(), the kernel interprets the supplied offset values using the timestamp format given in the mode field of the ppsparams argument. If the requested timestamp format is not supported, the time_pps_setparams() function has no effect and returns an error value. On a call to time_pps_getparams(), the kernel provides the timestamp format of the offsets by setting one of the timestamp format bits in the mode field.

assert_offset和clear_offset字段的时间戳格式由mode字段定义。也就是说,在调用time_pps_setparams()时,内核使用ppsparams参数的mode字段中给出的时间戳格式解释提供的偏移量值。如果不支持请求的时间戳格式,则time_pps_setparams()函数无效,并返回错误值。在调用time_pps_getparams()时,内核通过在mode字段中设置一个时间戳格式位来提供偏移量的时间戳格式。

Note: an application that uses time_pps_getparams() to read the current offset values cannot specify which format is used. The implementation SHOULD return the offsets using the same timestamp format as was used when the offsets were set.

注意:使用time_pps_getparams()读取当前偏移值的应用程序无法指定使用哪种格式。实现应该使用设置偏移时使用的相同时间戳格式返回偏移。

An application wishing to discover which mode bits it may set, with its current effective user ID, may call time_pps_getcap(). This function returns the set of mode bits that may be set by the application, without generating an EINVAL or EPERM error, for the specified PPS source. It does not return the current values for the mode bits. A call to time_pps_getcap() returns the mode bits corresponding to all supported timestamp formats.

如果应用程序希望发现它可以使用当前有效用户ID设置哪些模式位,则可以调用time\u pps\u getcap()。此函数返回可由应用程序设置的模式位集,而不生成指定PPS源的EINVAL或EPERM错误。它不会返回模式位的当前值。调用time_pps_getcap()返回与所有支持的时间戳格式对应的模式位。

The time_pps_getcap() function MAY ignore the mode in which the associated UNIX file descriptor was opened, so the application might still receive an EBADF error on a call to time_pps_setparams(), even if time_pps_getcap() says that the chosen mode bits are allowed.

time_pps_getcap()函数可能会忽略打开关联UNIX文件描述符的模式,因此应用程序在调用time_pps_setparams()时仍可能收到EBADF错误,即使time_pps_getcap()表示允许选择的模式位。

The mode bits returned by time_pps_getcap() for distinct PPS handles may differ, reflecting the specific capabilities of the underlying hardware connection to the PPS source, or of the source itself.

time_pps_getcap()为不同的pps句柄返回的模式位可能不同,反映到pps源的底层硬件连接或源本身的特定功能。

RETURN VALUES

返回值

On successful completion, the time_pps_setparams(), time_pps_getparams(), and time_pps_getcap() functions return 0. Otherwise, a value of -1 is returned and errno is set to indicate the error.

成功完成后,time_pps_setparams()、time_pps_getparams()和time_pps_getcap()函数返回0。否则,将返回值-1,并设置errno以指示错误。

ERRORS

错误

If the time_pps_setparams(), time_pps_getparams(), or time_pps_getcap() function fails, errno may be set to one of the following values:

如果time_pps_setparams()、time_pps_getparams()或time_pps_getcap()函数失败,则可能会将errno设置为以下值之一:

[EBADF] The handle parameter is not associated with a valid file descriptor, or the descriptor is not open for writing.

[EBADF]句柄参数未与有效的文件描述符关联,或者描述符未打开进行写入。

[EFAULT] A parameter points to an invalid address.

[EFAULT]参数指向无效地址。

[EOPNOTSUPP] The use of the PPS API is not supported for the associated file descriptor.

[EOPNOTSUPP]关联的文件描述符不支持使用PPS API。

[EINVAL] The operating system does not support all of the requested mode bits.

[EINVAL]操作系统不支持所有请求的模式位。

[EPERM] The process's effective user ID does not have the required privileges to use the PPS API, or to set the given mode bits.

[EPERM]进程的有效用户ID没有使用PPS API或设置给定模式位所需的权限。

3.4.3 New functions: access to PPS timestamps
3.4.3 新功能:访问PPS时间戳

The API includes one function that gives applications access to PPS timestamps. As an implementation option, the application may request the API to block until the next timestamp is captured. (The API does not directly support the use of the select() or poll() system calls to wait for PPS events.)

API包括一个函数,该函数允许应用程序访问PPS时间戳。作为一种实现选项,应用程序可以请求API阻塞,直到捕获下一个时间戳。(API不直接支持使用select()或poll()系统调用来等待PPS事件。)

SYNOPSIS

提要

int time_pps_fetch(pps_handle_t handle, const int tsformat, pps_info_t *ppsinfobuf, const struct timespec *timeout);

int time_pps_fetch(pps_handle_t handle,常量int tsformat,pps_info_t*ppsinfobuf,常量结构timespec*超时);

DESCRIPTION

描述

An application may use time_pps_fetch() to obtain the most recent timestamps captured for the PPS source specified by the handle parameter. The tsformat parameter specifies the desired timestamp format; if the requested timestamp format is not supported, the call fails and returns an error value. The application MUST specify exactly one timestamp format.

应用程序可以使用time_pps_fetch()获取由handle参数指定的pps源捕获的最新时间戳。tsformat参数指定所需的时间戳格式;如果不支持请求的时间戳格式,则调用将失败并返回错误值。应用程序必须只指定一种时间戳格式。

This function blocks until either a timestamp is captured from the PPS source, or until the specified timeout duration has expired. If the timeout parameter is a NULL pointer, the function simply blocks until a timestamp is captured. If the timeout parameter specifies a delay of zero, the function returns immediately.

此函数将一直阻止,直到从PPS源捕获时间戳,或者直到指定的超时持续时间过期。如果timeout参数是空指针,则函数只会阻塞,直到捕获时间戳为止。如果timeout参数指定延迟为零,则函数立即返回。

Support for blocking behavior is an implementation option. If the PPS_CANWAIT mode bit is clear, and the timeout parameter is either NULL or points to a non-zero value, the function returns an EOPNOTSUPP error. An application can discover whether the feature is implemented by using time_pps_getcap() to see if the PPS_CANWAIT mode bit is set.

对阻塞行为的支持是一种实现选项。如果PPS_CANWAIT mode位为清除状态,且timeout参数为NULL或指向非零值,则函数返回EOPNOTSUPP错误。应用程序可以通过使用time_pps_getcap()查看是否设置了pps_CANWAIT mode位来发现是否实现了该功能。

The result is stored in the ppsinfobuf parameter, whose fields are defined in section 3.2. If the function returns as the result of a timeout or error, the contents of the ppsinfobuf are undefined.

结果存储在ppsinfobuf参数中,其字段在第3.2节中定义。如果函数由于超时或错误而返回,则ppsinfobuf的内容未定义。

If this function is invoked before the system has captured a timestamp for the signal source, the ppsinfobuf returned will have its timestamp fields set to the time format's base date (e.g., for PPS_TSFMT_TSPEC, both the tv_sec and tv_nsec fields will be zero).

如果在系统捕获信号源的时间戳之前调用此函数,则返回的ppsinfobuf将其时间戳字段设置为时间格式的基准日期(例如,对于PPS_TSFMT_TSPEC,tv_sec和tv_nsec字段都将为零)。

RETURN VALUES

返回值

On successful completion, the time_pps_fetch() function returns 0. Otherwise, a value of -1 is returned and errno is set to indicate the error.

成功完成后,time_pps_fetch()函数返回0。否则,将返回值-1,并设置errno以指示错误。

ERRORS

错误

If the time_pps_fetch() function fails, errno may be set to one of the following values:

如果time_pps_fetch()函数失败,可以将errno设置为以下值之一:

[EBADF] The handle parameter is not associated with a valid file descriptor.

[EBADF]句柄参数未与有效的文件描述符关联。

[EFAULT] A parameter points to an invalid address.

[EFAULT]参数指向无效地址。

[EINTR] A signal was delivered before the time limit specified by the timeout parameter expired and before a timestamp has been captured.

[EINTR]在超时参数指定的时间限制到期之前和捕获时间戳之前发送了信号。

[EINVAL] The requested timestamp format is not supported.

[EINVAL]不支持请求的时间戳格式。

[EOPNOTSUPP] The use of the PPS API is not supported for the associated file descriptor.

[EOPNOTSUPP]关联的文件描述符不支持使用PPS API。

[ETIMEDOUT] The timeout duration has expired.

[ETIMEDOUT]超时持续时间已过期。

3.4.4 New functions: disciplining the kernel timebase
3.4.4 新函数:规范内核时基

The API includes one OPTIONAL function to specify if and how a PPS source is provided to a kernel consumer of PPS events, such as the code used to discipline the operating system's internal timebase.

API包含一个可选函数,用于指定PPS源是否以及如何提供给PPS事件的内核使用者,例如用于规范操作系统内部时基的代码。

SYNOPSIS

提要

int time_pps_kcbind(pps_handle_t handle, const int kernel_consumer, const int edge, const int tsformat); DESCRIPTION

int time_pps_kcbind(pps_handle_t handle,const int kernel_consumer,const int edge,const int tsformat);描述

An application with appropriate privileges may use time_pps_kcbind() to bind a kernel consumer to the PPS source specified by the handle.

具有适当权限的应用程序可以使用time_pps_kcbind()将内核使用者绑定到句柄指定的pps源。

The kernel consumer is identified by the kernel_consumer parameter. In the current version of the API, the possible values for this parameter are:

内核使用者由kernel_consumer参数标识。在当前版本的API中,此参数的可能值为:

#define PPS_KC_HARDPPS 0 #define PPS_KC_HARDPPS_PLL 1 #define PPS_KC_HARDPPS_FLL 2

#定义PPS_KC_hardps 0#定义PPS_KC_hardps_PLL 1#定义PPS_KC_hardps_FLL 2

with these meanings:

具有以下含义:

PPS_KC_HARDPPS The kernel's hardpps() function (or equivalent).

PPS_KC_HARDPPS内核的HARDPPS()函数(或等效函数)。

PPS_KC_HARDPPS_PLL A variant of hardpps() constrained to use a phase-locked loop.

PPS_KC_HARDPPS_PLL一种HARDPPS()的变体,被限制使用锁相环。

PPS_KC_HARDPPS_FLL A variant of hardpps() constrained to use a frequency-locked loop.

PPS_KC_HARDPPS_FLL是HARDPPS()的一种变体,受限制使用频率锁定环路。

Implementation of any or all of these values is OPTIONAL.

任何或所有这些值的实现都是可选的。

The edge parameter indicates which edge of the PPS signal causes a timestamp to be delivered to the kernel consumer. It may have the value PPS_CAPTUREASSERT, PPS_CAPTURECLEAR, or PPS_CAPTUREBOTH, depending on particular characteristics of the PPS source. It may also be zero, which removes any binding between the PPS source and the kernel consumer.

edge参数指示PPS信号的哪个边缘导致时间戳被传递到内核消费者。根据PPS源的特定特征,其值可能为PPS_CAPTUREASSERT、PPS_CAPTURECLEAR或PPS_CAPTUREASSERT。它也可以是零,这将删除PPS源和内核使用者之间的任何绑定。

The tsformat parameter specifies the format for the timestamps delivered to the kernel consumer. If this value is zero, the implementation MAY choose the appropriate format, or return EINVAL. The implementation MAY ignore a non-zero value for this parameter.

tsformat参数指定传递给内核使用者的时间戳的格式。如果该值为零,则实现可以选择适当的格式,或返回EINVAL。实现可能会忽略此参数的非零值。

The binding created by this call persists until it is changed by a subsequent call specifying the same kernel_consumer. In particular, a subsequent call to time_pps_destroy() for the specified handle does not affect the binding.

此调用创建的绑定将一直保持,直到它被指定相同内核\u使用者的后续调用更改。特别是,对指定句柄的time_pps_destroy()的后续调用不会影响绑定。

The binding is independent of any prior or subsequent changes to the PPS_CAPTUREASSERT and PPS_CAPTURECLEAR mode bits for the device. However, if either the edge or the tsformat parameter values are inconsistent with the capabilities of the PPS source, an error is returned. The implementation MAY also return an error if the tsformat value is unsupported for time_pps_kcbind(), even if it is supported for other uses of the API.

绑定独立于设备的PPS_CAPTUREASSERT和PPS_CAPTURECLEAR模式位的任何先前或后续更改。但是,如果edge或tsformat参数值与PPS源的功能不一致,则返回错误。如果time_pps_kcbind()不支持tsformat值,则实现也可能返回错误,即使API的其他用途也支持tsformat值。

The operating system may enforce two restrictions on the bindings created by time_pps_kcbind():

操作系统可能会对time_pps_kcbind()创建的绑定实施两个限制:

1. the kernel MAY return an error if an attempt is made to bind a kernel consumer to more than one PPS source a time.

1. 如果试图一次将内核使用者绑定到多个PPS源,内核可能会返回错误。

2. the kernel MAY restrict the ability to set bindings to processes with sufficient privileges to modify the system's internal timebase. (On UNIX systems, such modification is normally done using settimeofday() and/or adjtime(), and is restricted to users with superuser privilege.)

2. 内核可能会限制为具有修改系统内部时基的足够权限的进程设置绑定的能力。(在UNIX系统上,此类修改通常使用settimeofday()和/或adjtime()完成,并且仅限于具有超级用户权限的用户。)

Warning: If this feature is configured for a PPS source that does not have an accurate 1-pulse-per-second signal, or is otherwise inappropriately configured, use of this feature may result in seriously incorrect timekeeping for the entire system. For best results, the 1-PPS signal should have much better frequency stability than the system's internal clock source (usually a crystal-controlled oscillator), and should have jitter (variation in interarrival time) much less than the system's clock-tick interval.

警告:如果为没有精确的每秒1脉冲信号的PPS源配置此功能,或者配置不当,则使用此功能可能会导致整个系统的计时严重错误。为获得最佳结果,1-PPS信号应比系统内部时钟源(通常为晶体控制振荡器)具有更好的频率稳定性,且抖动(到达间隔时间的变化)应比系统的时钟滴答间隔小得多。

See RFC 1589 [4] for more information about how the system's timebase may be disciplined using a PPS signal.

有关如何使用PPS信号调节系统时基的更多信息,请参见RFC 1589[4]。

RETURN VALUES

返回值

On successful completion, the time_pps_kcbind() function returns 0. Otherwise, a value of -1 is returned and errno is set to indicate the error.

成功完成后,time_pps_kcbind()函数返回0。否则,将返回值-1,并设置errno以指示错误。

ERRORS

错误

If the time_pps_kcbind() function fails, errno may be set to one of the following values:

如果time_pps_kcbind()函数失败,errno可设置为以下值之一:

[EBADF] The handle parameter is not associated with a valid file descriptor, or the descriptor is not open for writing.

[EBADF]句柄参数未与有效的文件描述符关联,或者描述符未打开进行写入。

[EFAULT] A parameter points to an invalid address.

[EFAULT]参数指向无效地址。

[EINVAL] The requested timestamp format is not supported.

[EINVAL]不支持请求的时间戳格式。

[EOPNOTSUPP] The use of the PPS API is not supported for the associated file descriptor, or this OPTIONAL function is not supported.

[EOPNOTSUPP]关联的文件描述符不支持使用PPS API,或者不支持此可选函数。

[EPERM] The process's effective user ID does not have the required privileges to set the binding.

[EPERM]进程的有效用户ID没有设置绑定所需的权限。

3.5 Compliance rules
3.5 遵守规则

The key words "MUST", "MUST NOT", "REQUIRED","SHOULD", SHOULD NOT", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [1].

本文件中的关键词“必须”、“不得”、“必需”、“应该”、“不应该”、“可能”和“可选”应按照RFC 2119[1]中的说明进行解释。

Some features of this specification are OPTIONAL, but others are REQUIRED.

本规范的某些功能是可选的,但其他功能是必需的。

3.5.1 Functions
3.5.1 功能

An implementation MUST provide these functions:

实现必须提供以下功能:

- time_pps_create() - time_pps_destroy() - time_pps_setparams() - time_pps_getparams() - time_pps_getcap() - time_pps_fetch()

- 时间pps\U创建()-时间pps\U销毁()-时间pps\U设置参数()-时间pps\U获取参数()-时间pps\U获取上限()-时间pps\U获取()

An implementation MUST provide this function, but it may be implemented as a function that always return an EOPNOTSUPP error, possibly on a per-source basis:

实现必须提供此函数,但可以将其实现为始终返回EOPNOTSUPP错误的函数,可能是基于每个源的:

- time_pps_kcbind()

- 时间_pps_kcbind()

3.5.2 Mode bits
3.5.2 模式位

An implementation MUST support at least one of these mode bits for each PPS source:

对于每个PPS源,实现必须至少支持其中一个模式位:

- PPS_CAPTUREASSERT - PPS_CAPTURECLEAR

- PPS_CAPTUREASSERT-PPS_CAPTURECLEAR

and MAY support both of them. If an implementation supports both of these bits for a PPS source, it SHOULD allow them to be set simultaneously.

并且可能支持这两个。如果实现支持PPS源的这两个位,则应允许同时设置它们。

An implementation MUST support this timestamp format:

实现必须支持此时间戳格式:

- PPS_TSFMT_TSPEC

- PPS_TSFMT_TSPEC

An implementation MAY support these mode bits:

实现可以支持这些模式位:

- PPS_ECHOASSERT - PPS_ECHOCLEAR - PPS_OFFSETASSERT - PPS_OFFSETCLEAR

- PPS_ECHOASSERT-PPS_ECHOCLEAR-PPS_OFFSETASSERT-PPS_OFFSETCLEAR

An implementation MAY support this timestamp format:

实现可支持此时间戳格式:

- PPS_TSFMT_NTPFP

- PPS_TSFMT_NTPFP

3.6 Examples
3.6 例子

A very simple use of this API might be:

此API的一个非常简单的用法可能是:

      int fd;
      pps_handle_t handle;
      pps_params_t params;
      pps_info_t infobuf;
      struct timespec timeout;
        
      int fd;
      pps_handle_t handle;
      pps_params_t params;
      pps_info_t infobuf;
      struct timespec timeout;
        
      /* Open a file descriptor and enable PPS on rising edges */
      fd = open(PPSfilename, O_RDWR, 0);
      time_pps_create(fd, &handle);
      time_pps_getparams(handle, &params);
      if ((params.mode & PPS_CAPTUREASSERT) == 0) {
          fprintf(stderr, "%s cannot currently CAPTUREASSERT\n",
                PPSfilename);
          exit(1);
      }
        
      /* Open a file descriptor and enable PPS on rising edges */
      fd = open(PPSfilename, O_RDWR, 0);
      time_pps_create(fd, &handle);
      time_pps_getparams(handle, &params);
      if ((params.mode & PPS_CAPTUREASSERT) == 0) {
          fprintf(stderr, "%s cannot currently CAPTUREASSERT\n",
                PPSfilename);
          exit(1);
      }
        
      /* create a zero-valued timeout */
        
      /* create a zero-valued timeout */
        
      timeout.tv_sec = 0;
      timeout.tv_nsec = 0;
        
      timeout.tv_sec = 0;
      timeout.tv_nsec = 0;
        
      /* loop, printing the most recent timestamp every second or so */
      while (1) {
          sleep(1);
          time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, &timeout);
          printf("Assert timestamp: %d.%09d, sequence: %ld\n",
                      infobuf.assert_timestamp.tv_sec,
                      infobuf.assert_timestamp.tv_nsec,
                      infobuf.assert_sequence);
      }
        
      /* loop, printing the most recent timestamp every second or so */
      while (1) {
          sleep(1);
          time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, &timeout);
          printf("Assert timestamp: %d.%09d, sequence: %ld\n",
                      infobuf.assert_timestamp.tv_sec,
                      infobuf.assert_timestamp.tv_nsec,
                      infobuf.assert_sequence);
      }
        

Note that this example omits most of the error-checking that would be expected in a reliable program.

请注意,此示例省略了可靠程序中预期的大多数错误检查。

Also note that, on a system that supports PPS_CANWAIT, the function of these lines:

还请注意,在支持PPS_CANWAIT的系统上,以下行的功能:

         sleep(1);
         time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, &timeout);
        
         sleep(1);
         time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, &timeout);
        

might be more reliably accomplished using:

可通过以下方式更可靠地完成:

         timeout.tv_sec = 100;
         timeout.tv_nsec = 0;
         time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, &timeout);
        
         timeout.tv_sec = 100;
         timeout.tv_nsec = 0;
         time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, &timeout);
        

The (arbitrary) timeout value is used to protect against the possibility that another application might disable PPS timestamps, or that the hardware generating the timestamps might fail.

(任意)超时值用于防止其他应用程序可能禁用PPS时间戳,或者生成时间戳的硬件可能失败。

A slightly more elaborate use of this API might be:

此API的一个稍微复杂的用法可能是:

      int fd;
      pps_handle_t handle;
      pps_params_t params;
      pps_info_t infobuf;
      int avail_mode;
      struct timespec timeout;
        
      int fd;
      pps_handle_t handle;
      pps_params_t params;
      pps_info_t infobuf;
      int avail_mode;
      struct timespec timeout;
        
      /* Open a file descriptor */
      fd = open(PPSfilename, O_RDWR, 0);
      time_pps_create(fd, &handle);
        
      /* Open a file descriptor */
      fd = open(PPSfilename, O_RDWR, 0);
      time_pps_create(fd, &handle);
        
      /*
       * Find out what features are supported
       */
        
      /*
       * Find out what features are supported
       */
        
      time_pps_getcap(handle, &avail_mode);
      if ((avail_mode & PPS_CAPTUREASSERT) == 0) {
          fprintf(stderr, "%s cannot CAPTUREASSERT\n", PPSfilename);
          exit(1);
      }
      if ((avail_mode & PPS_OFFSETASSERT) == 0) {
          fprintf(stderr, "%s cannot OFFSETASSERT\n", PPSfilename);
          exit(1);
      }
        
      time_pps_getcap(handle, &avail_mode);
      if ((avail_mode & PPS_CAPTUREASSERT) == 0) {
          fprintf(stderr, "%s cannot CAPTUREASSERT\n", PPSfilename);
          exit(1);
      }
      if ((avail_mode & PPS_OFFSETASSERT) == 0) {
          fprintf(stderr, "%s cannot OFFSETASSERT\n", PPSfilename);
          exit(1);
      }
        
      /*
       * Capture assert timestamps, and
       *   compensate for a 675 nsec propagation delay
       */
        
      /*
       * Capture assert timestamps, and
       *   compensate for a 675 nsec propagation delay
       */
        
      time_pps_getparams(handle, &params);
      params.assert_offset.tv_sec = 0;
      params.assert_offset.tv_nsec = 675;
      params.mode |= PPS_CAPTUREASSERT | PPS_OFFSETASSERT;
      time_pps_setparams(handle, &params);
        
      time_pps_getparams(handle, &params);
      params.assert_offset.tv_sec = 0;
      params.assert_offset.tv_nsec = 675;
      params.mode |= PPS_CAPTUREASSERT | PPS_OFFSETASSERT;
      time_pps_setparams(handle, &params);
        
      /* create a zero-valued timeout */
      timeout.tv_sec = 0;
      timeout.tv_nsec = 0;
        
      /* create a zero-valued timeout */
      timeout.tv_sec = 0;
      timeout.tv_nsec = 0;
        
      /* loop, printing the most recent timestamp every second or so */
      while (1) {
          if (avail_mode & PPS_CANWAIT) {
              time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, NULL);
                              /* waits for the next event */
          } else {
              sleep(1);
              time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf,
                timeout);
        
      /* loop, printing the most recent timestamp every second or so */
      while (1) {
          if (avail_mode & PPS_CANWAIT) {
              time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, NULL);
                              /* waits for the next event */
          } else {
              sleep(1);
              time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf,
                timeout);
        
          }
          printf("Assert timestamp: %d.%09d, sequence: %ld\n",
                      infobuf.assert_timestamp.tv_sec,
                      infobuf.assert_timestamp.tv_nsec,
                      infobuf.assert_sequence);
      }
        
          }
          printf("Assert timestamp: %d.%09d, sequence: %ld\n",
                      infobuf.assert_timestamp.tv_sec,
                      infobuf.assert_timestamp.tv_nsec,
                      infobuf.assert_sequence);
      }
        

Again, most of the necessary error-checking has been omitted from this example.

同样,本例中省略了大多数必要的错误检查。

4 Security Considerations

4安全考虑

This API gives applications three capabilities:

此API为应用程序提供了三种功能:

- Causing the system to capture timestamps on certain events.

- 导致系统捕获特定事件的时间戳。

- Obtaining timestamps for certain events.

- 获取特定事件的时间戳。

- Affecting the system's internal timebase.

- 影响系统的内部时基。

The first capability should not affect security directly, but might cause a slight increase in interrupt latency and interrupt-handling overhead.

第一种功能不应直接影响安全性,但可能会导致中断延迟和中断处理开销略微增加。

The second capability might be useful in implementing certain kinds of covert communication channels.

第二种功能可能有助于实现某些类型的隐蔽通信通道。

In most cases, neither of these first two issues is a significant security threat, because the traditional UNIX file protection facility may be used to to limit access to the relevant special files. Provision of the PPS API adds minimal additional risk.

在大多数情况下,前两个问题都不是重大的安全威胁,因为传统的UNIX文件保护功能可能被用来限制对相关特殊文件的访问。PPS API的提供增加了最小的额外风险。

The final capability is reserved to highly privileged users. In UNIX systems, this means those with superuser privilege. Such users can evade protections based on file permissions; however, such users can in general cause unbounded havoc, and can set the internal timebase (and its rate of change), so this API creates no new vulnerabilities.

最后的功能保留给具有高度特权的用户。在UNIX系统中,这意味着具有超级用户权限的系统。此类用户可以规避基于文件权限的保护;但是,这些用户通常会造成无限的破坏,并且可以设置内部时基(及其变化率),因此此API不会创建新的漏洞。

5 Acknowledgements

5致谢

The API in this document draws some of its inspiration from the LBL "ppsclock" distribution [2], originally implemented in 1993 by Steve McCanne, Craig Leres, and Van Jacobson. We also thank Poul-Henning Kamp, Craig Leres, Judah Levine, and Harlan Stenn for helpful comments they contributed during the drafting of this document.

本文中的API从LBL“PPSCALL”发行版[2]中获得了一些灵感,该发行版最初由Steve McCanne、Craig Leres和Van Jacobson于1993年实施。我们还感谢Poul Henning Kamp、Craig Leres、Judah Levine和Harlan Stenn在本文件起草过程中提供的有用意见。

6 References

6参考文献

1. Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

1. Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,1997年3月。

2. Steve McCanne, Craig Leres, and Van Jacobson. PPSCLOCK. ftp://ftp.ee.lbl.gov/ppsclock.tar.Z.

2. Steve McCanne、Craig Leres和Van Jacobson。时钟。ftp://ftp.ee.lbl.gov/ppsclock.tar.Z.

3. Mills, D., "Network Time Protocol (Version 3): Specification, Implementation and Analysis", RFC 1305, March 1992.

3. Mills,D.,“网络时间协议(版本3):规范、实现和分析”,RFC13051992年3月。

4. Mills, D., "A Kernel Model for Precision Timekeeping", RFC 1589, March, 1994.

4. Mills,D.,“精确计时的内核模型”,RFC1589,1994年3月。

5. The Open Group. The Single UNIX Specification, Version 2 - 6 Vol Set for UNIX 98. Document number T912, The Open Group, February, 1997.

5. 开放组。UNIX 98的单一UNIX规范,版本2-6卷集。文件编号T912,公开组,1997年2月。

7 Authors' Addresses

7作者地址

Jeffrey C. Mogul Western Research Laboratory Compaq Computer Corporation 250 University Avenue Palo Alto, California, 94305, U.S.A.

Jeffrey C.Mogul西部研究实验室康柏计算机公司美国加利福尼亚州帕洛阿尔托大学大道250号,邮编94305。

Phone: 1 650 617 3304 (email preferred) EMail: mogul@wrl.dec.com

电话:16506173304(首选电子邮件)电子邮件:mogul@wrl.dec.com

David L. Mills Electrical and Computer Engineering Department University of Delaware Newark, DE 19716

David L. Mills电气与计算机工程系德拉瓦大学NeWK,DE 19716

Phone: (302) 831-8247 EMail: mills@udel.edu

电话:(302)831-8247电子邮件:mills@udel.edu

Jan Brittenson Sun Microsystems, Inc. 901 San Antonio Rd M/S MPK17-202 Palo Alto, CA 94303 Email: Jan.Brittenson@Eng.Sun.COM

Jan Brittenson Sun Microsystems,Inc.加利福尼亚州帕洛阿尔托市圣安东尼奥路901号MPK17-202邮编94303电子邮件:Jan。Brittenson@Eng.Sun.COM

Jonathan Stone Stanford Distributed Systems Group Stanford, CA 94305

Jonathan Stone斯坦福分布式系统集团加利福尼亚州斯坦福94305

Phone: (650) 723-2513 EMail: jonathan@dsg.stanford.edu

电话:(650)723-2513电子邮件:jonathan@dsg.stanford.edu

Ulrich Windl Universitaet Regensburg, Klinikum

克林库姆雷根斯堡乌尔里希·温德尔大学

   EMail: ulrich.windl@rz.uni-regensburg.de
        
   EMail: ulrich.windl@rz.uni-regensburg.de
        

A. Extensions and related APIs

A.扩展和相关API

The API specified in the main body of this document could be more useful with the provision of several extensions or companion APIs.

本文档主体中指定的API在提供几个扩展或配套API时可能更有用。

At present, the interfaces listed in this appendix are not part of the formal specification in this document.

目前,本附录中列出的接口不是本文件正式规范的一部分。

A.1 Extension: Parameters for the "echo" mechanism
A.1扩展:“回声”机制的参数

The "echo" mechanism described in the body of this specification leaves most of the details to the implementor, especially the designation of one or more output pins.

本规范正文中描述的“echo”机制将大部分细节留给实现者,特别是一个或多个输出管脚的指定。

It might be useful to extend this API to provide either or both of these features:

扩展此API以提供以下任一或两种功能可能很有用:

- A means by which the application can discover which output pin is echoing the input pin.

- 应用程序可以发现哪个输出引脚与输入引脚相呼应的一种方法。

- A means by which the application can select which output pin is echoing the input pin.

- 应用程序可以选择哪个输出引脚与输入引脚相呼应的一种方法。

A.2 Extension: Obtaining information about external clocks
A.2扩展:获取有关外部时钟的信息

The PPS API may be useful with a wide variety of reference clocks, connected via several different interface technologies (including serial lines, parallel interfaces, and bus-level interfaces). These reference clocks can have many features and parameters, some of which might not even have been invented yet.

PPS API可用于通过多种不同接口技术(包括串行线、并行接口和总线级接口)连接的各种参考时钟。这些参考时钟可以有许多特性和参数,其中一些可能还没有发明出来。

We believe that it would be useful to have a mechanism by which an application can discover arbitrary features and parameters of a reference clock. These might include:

我们相信,拥有一种应用程序可以发现参考时钟的任意特征和参数的机制是非常有用的。这些措施可能包括:

- Clock manufacturer, model number, and revision level - Whether the clock is synchronized to an absolute standard - For synchronized clocks, * The specific standard * The accuracy of the standard * The path used (direct connection, shortwave, longwave, satellite, etc.) * The distance (offset) and variability of this path

- 时钟制造商、型号和修订级别-时钟是否与绝对标准同步-对于同步时钟,*具体标准*标准的精度*使用的路径(直接连接、短波、长波、卫星等)*该路径的距离(偏移)和可变性

- For PPS sources, * The pulse rate * The pulse shape * Which edge of the pulse corresponds to the epoch

- 对于PPS源,*脉冲率*脉冲形状*脉冲边缘对应于历元

- The time representation format

- 时间表示格式

This information might best be provided by an API analogous to the standard "curses" API, with a database analogous to the standard "terminfo" database. That is, a "clockinfo" database would contain a set of (attribute, value) pairs for each type of clock, and the API would provide a means to query this database.

此信息最好由类似于标准“curses”API的API提供,数据库类似于标准“terminfo”数据库。也就是说,“clockinfo”数据库将为每种类型的时钟包含一组(属性、值)对,API将提供查询该数据库的方法。

Additional mechanisms would allow an application to discover the clock or clocks connected to the local system, and to discover the clockinfo type of a specific clock device.

附加机制将允许应用程序发现连接到本地系统的时钟,并发现特定时钟设备的时钟信息类型。

A.3 Extension: Finding a PPS source
A.3扩展:查找PPS源

Although the clockinfo database described in section A.2, together with the discover mechanisms described there, would allow an application to discover the PPS source (or sources) connected to a system, it might be more complex than necessary.

尽管第A.2节中描述的clockinfo数据库以及其中描述的发现机制允许应用程序发现连接到系统的PPS源,但它可能比必要的复杂。

A simpler approach would be to support a single function that provides the identity of one or more PPS sources.

更简单的方法是支持单个函数,该函数提供一个或多个PPS源的标识。

For example, the function might be declared as

例如,函数可以声明为

int time_pps_findsource(int index, char *path, int pathlen, char *idstring, int idlen);

int-time\u-pps\u-findsource(int-index,char*path,int-pathlen,char*idstring,int-idlen);

The index argument implicitly sets up an ordering on the PPS sources attached to the system. An application would use this function to inquire about the Nth source. The function would return -1 if no such source exists; otherwise, it would return 0, and would place the pathname of the associated special file in the path argument. It would also place an identification string in the idstring argument. The identification string could include the clock make, model, version, etc., which could then be used by the application to control its behavior.

index参数隐式地设置连接到系统的PPS源的顺序。应用程序将使用此函数查询第n个源。如果不存在这样的源,函数将返回-1;否则,它将返回0,并将关联特殊文件的路径名放在path参数中。它还将在idstring参数中放置一个标识字符串。标识字符串可以包括时钟品牌、型号、版本等,然后应用程序可以使用它们来控制其行为。

This function might simply read the Nth line from a simple database, containing lines such as:

此函数可能只是从简单数据库中读取第n行,其中包含以下行:

      /dev/tty00      "TrueTime 468-DC"
      /dev/pps1       "Homebrew rubidium frequency standard"
        
      /dev/tty00      "TrueTime 468-DC"
      /dev/pps1       "Homebrew rubidium frequency standard"
        

allowing the system administrator to describe the configuration of PPS sources.

允许系统管理员描述PPS源的配置。

B. Example implementation: PPSDISC Line discipline

B.实施示例:PPSDISC生产线规程

One possible implementation of the PPS API might be to define a new "line discipline" and then map the API onto a set of ioctl() commands. Here we sketch such an implementation; note that this is not part of the specification of the API, and applications should not expect this low-level interface to be available.

PPS API的一个可能实现可能是定义一个新的“行规程”,然后将API映射到一组ioctl()命令上。在这里,我们勾勒出这样一个实现;请注意,这不是API规范的一部分,应用程序不应期望此低级接口可用。

In this approach, the set of line disciplines is augmented with one new line discipline, PPSDISC. This discipline will act exactly the same as the TTYDISC discipline, except for its handling of modem DCD interrupts.

在这种方法中,线规程集增加了一个新的线规程PPSDISC。除处理调制解调器DCD中断外,该规程的作用与TTYDISC规程完全相同。

Once the TIOCSETD ioctl() has been used to select this line discipline, PPS-related operations on the serial line may be invoked using new ioctl() commands. For example (values used only for illustration):

一旦使用TIOCSETD ioctl()来选择该线路规程,就可以使用新的ioctl()命令调用串行线路上与PPS相关的操作。例如(仅用于说明的值):

   #define PPSFETCH      _IOR('t', 75, pps_info_t)
   #define PPSSETPARAM   _IOW('t', 76, pps_params_t)
   #define PPSGETPARAM   _IOR('t', 77, pps_params_t)
   #define PPSGETCAP     _IOR('t', 78, int)
        
   #define PPSFETCH      _IOR('t', 75, pps_info_t)
   #define PPSSETPARAM   _IOW('t', 76, pps_params_t)
   #define PPSGETPARAM   _IOR('t', 77, pps_params_t)
   #define PPSGETCAP     _IOR('t', 78, int)
        
B.1 Example
B.1示例

A typical use might be:

典型用途可能是:

      int ldisc = PPSDISC;
      pps_params_t params;
      pps_info_t infobuf;
        
      int ldisc = PPSDISC;
      pps_params_t params;
      pps_info_t infobuf;
        
      ioctl(fd, TIOCSETD, &ldisc);    /* set discipline */
        
      ioctl(fd, TIOCSETD, &ldisc);    /* set discipline */
        
      /*
       * Check the capabilities of this PPS source to see
       * if it supports what we need.
       */
      ioctl(fd, PPSGETCAP, &params);
      if ((params.mode & PPS_CAPTUREASSERT) == 0) {
          fprintf(stderr, "PPS source is not suitable\n");
          exit(1);
      }
        
      /*
       * Check the capabilities of this PPS source to see
       * if it supports what we need.
       */
      ioctl(fd, PPSGETCAP, &params);
      if ((params.mode & PPS_CAPTUREASSERT) == 0) {
          fprintf(stderr, "PPS source is not suitable\n");
          exit(1);
      }
        
      /*
       * Set this line to timestamp on a rising-edge interrupt
        
      /*
       * Set this line to timestamp on a rising-edge interrupt
        
       */
      ioctl(fd, PPSGETPARAMS, &params);
      params.mode |= PPS_CAPTUREASSERT;
      ioctl(fd, PPSSETPARAMS, &params);
        
       */
      ioctl(fd, PPSGETPARAMS, &params);
      params.mode |= PPS_CAPTUREASSERT;
      ioctl(fd, PPSSETPARAMS, &params);
        
      sleep(2);       /* allow time for the PPS pulse to happen */
        
      sleep(2);       /* allow time for the PPS pulse to happen */
        
      /* obtain most recent timestamp and sequence # for this line */
      ioctl(fd, PPSFETCH, &infobuf);
        
      /* obtain most recent timestamp and sequence # for this line */
      ioctl(fd, PPSFETCH, &infobuf);
        

Again, this example imprudently omits any error-checking.

同样,这个示例不小心忽略了任何错误检查。

C. Available implementations

C.可用的实施

Several available implementations of this API are listed at <http://www.ntp.org/ppsapi/PPSImpList.html>. Note that not all of these implementations correspond to the current version of the specification.

下面列出了此API的几种可用实现<http://www.ntp.org/ppsapi/PPSImpList.html>. 请注意,并非所有这些实现都对应于规范的当前版本。

Full Copyright Statement

完整版权声明

Copyright (C) The Internet Society (2000). All Rights Reserved.

版权所有(C)互联网协会(2000年)。版权所有。

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

本文件及其译本可复制并提供给他人,对其进行评论或解释或协助其实施的衍生作品可全部或部分编制、复制、出版和分发,不受任何限制,前提是上述版权声明和本段包含在所有此类副本和衍生作品中。但是,不得以任何方式修改本文件本身,例如删除版权通知或对互联网协会或其他互联网组织的引用,除非出于制定互联网标准的需要,在这种情况下,必须遵循互联网标准过程中定义的版权程序,或根据需要将其翻译成英语以外的其他语言。

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

上述授予的有限许可是永久性的,互联网协会或其继承人或受让人不会撤销。

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

本文件和其中包含的信息是按“原样”提供的,互联网协会和互联网工程任务组否认所有明示或暗示的保证,包括但不限于任何保证,即使用本文中的信息不会侵犯任何权利,或对适销性或特定用途适用性的任何默示保证。

Acknowledgement

确认

Funding for the RFC Editor function is currently provided by the Internet Society.

RFC编辑功能的资金目前由互联网协会提供。