Name

NTP Client API — NTP client API and configuration

NTP Client API

The NTP client provides two main entry points:

    #include <ntpclient.h>

     __externC void cyg_ntpclient_start( cyg_ntpclient_config *config );

     __externC void cyg_ntpclient_stop( void );

    __externC void cyg_ntpclient_status( cyg_ntpclient_status *status );

    __externC void cyg_ntpclient_log( int log_mask );

The cyg_ntpclient_start() function starts the NTP client running using parameters defined in the config argument. The cyg_ntpclient_stop() stops the NTP client, after which it can be restarted with a new configuration.

The config argument contains the following fields that the user may set to control the behaviour of the NTP client. The config structure and its contents must remain accessible until cyg_ntpclient_stop() is called, as the NTP client stores a reference to it rather than copying it. Therefore it is likely it will want to be allocated persistently, typically as a static or global.

const char *server[]
A list of server IP addresses to access. These are specified as strings in standard dot notation. Unused slots should be set to NULL. The size of this array is controlled by CYGNUM_NET_NTPCLIENT_SERVER_MAX.
int settime

If non-zero this will force the NTP client to set the system time immediately from the NTP servers. Otherwise it will wait for the time to stabilize before doing this. This is useful on targets that do not have a built-in battery-backed real time clock. Note that by taking the first server time supplied, the initial time set may be less accurate than one would normally expect, it will be adjusted to track the server times more closely as the client accumulates samples.

If this option is set, then the call to cyg_ntpclient_start() will not return until the initial time has been set.

The cyg_ntpclient_status_get() function returns some information on the state of the client and the NTP peers it is communicating with. On return the status argument is filled in with the following information.

double *last_adjustment
This records the last adjustment made to the clock expressed as a whole number plus fraction of seconds.
peer[]

A structure for each peer. The size of this array is controlled by CYGNUM_NET_NTPCLIENT_SERVER_MAX. Each entry contains the following fields:

const char *addr
The IP address of the peer expressed as a string. This is actually just a pointer to the string passed to cyg_ntpclient_start() in the configuration. If the value is NULL then this peer table entry is invalid.
int trustlevel
The level of trust the client has in this peer. This is a value between 0 and 10. For a good peer, this will be near the upper end of this range.
int lasterror
If non-zero this records the last communication error raised by this peer.
double delay
The most recent smallest communication delay to the peer.
double offset
The offset between the local and the remote clock for the same transaction as the delay field.

The cyg_ntpclient_log() function sets some logging option in the NTP client. These are output on the standard output using printf(). The log_mask is a bitwise OR of the following values: CYG_NTPCLIENT_LOG_DEBUG, CYG_NTPCLIENT_LOG_INFO and CYG_NTPCLIENT_LOG_CRIT which generate debug, information and critical error messages respectively. The value CYG_NTPCLIENT_LOG_ALL enables all flags. All flags can be cleared by calling this function with a zero parameter.

The normal idiom for use of the NTP client is to define the cyg_ntpclient structure statically and to then call cyg_ntpclient_start() with a pointer to that. The following is a somewhat contrived example:

#include <ntpclient.h>

//==========================================================================

static cyg_ntpclient_config ntp_config =
{
    .server             = { "10.0.1.1", "149.255.102.233", NULL },
    .settime            = 1,
};

//==========================================================================

void start_ntp(void)
{
    cyg_ntpclient_start( &ntp_config );
}

Configuration Options

The NTP client is enabled by including the CYGPKG_NET_NTPCLIENT together with the CYGPKG_CLOCK_COMMON package. It also needs the FreeBSD network stack, POSIX and the C library; therefore, it is best to start from the net template. The NTP client package contains a number of configuration options:

CYGNUM_NET_NTPCLIENT_PORT
This option defines the port number to which the client will direct NTP packets. This should normally be the standard NTP port number of 123, but for testing it may be useful to change it to a non-standard value.
CYGNUM_NET_NTPCLIENT_STACK_SIZE
This option defines the size of the stack used by the NTP client thread. This value defines how much more stack than the value given by CYGNUM_HAL_STACK_SIZE_TYPICAL is used. The default of 4KiB should be sufficient for most purposes.
CYGNUM_NET_NTPCLIENT_THREAD_PRIORITY
This option defines the priority at which the NTP thread will run. If it is important that the client maintains synchronization with the servers, then this value should be small, giving the client thread a high priority. The default value is 2, making the thread one of the higher priority threads in the system.
CYGNUM_NET_NTPCLIENT_SERVER_MAX
This option defines the maximum number of NTP servers the client can access. This controls the number that can be passed in the configuration and the size and number of various data structures allocated statically in the code.