Chapter 188. Dependencies

188.1. HAL

This package relies on the HAL clock API. It is strongly recommended that the HAL clocks are implemented using the full newer version of the HAL clock API, and not the older backward compatibility API (HAL_CLOCK_INITIALIZE(), HAL_CLOCK_READ(), HAL_CLOCK_RESET()). The package will still operate with the older form of API implementation, but it is likely to be less accurate, and possibly slightly slower.

The HAL clock API provides a high-resolution interface to an appropriate hardware clock, allowing fine-grained access with subtick access. Naturally, the resolution and accuracy that this package is able to provide is subject to what the hardware and HAL clock implementation provides. It is desirable, if possible, for the HAL clock to be configured with auto-reloading on interrupt. This reduces clock drift.

188.2. Kernel

At the present time, the common clock package relies on kernel facilities. It is hoped in future that this dependency will be removed.

However at the present time, a clock management thread is used to provide an asynchronous route for managing clock operations. This can be important if the package is required to update the wallclock, since with some wallclock drivers, it can take over one second to update the wallclock time in hardware, and it would be inappropriate for applications to stall and wait for such operations to complete.

It also allows modules to be notified that time has changed, either by a step change or by gradual fine adjustment. It can either use a user-supplied callback function, or broadcast a nominated kernel condition variable as the mechanism for notification. When it does so, it passes both the newly set time, and the cumulative time offset since the last received notification.

If a callback function has been provided, it should return as soon as possible, as no further notifications or other processing by the clock management thread can proceed until control is returned to it.

At present, the only underlying HAL clock supported must be the same clock as that used by the kernel, however the API and implementation have been designed to accommodate alternative clocks, and very little is required to complete such an implementation, once an appropriate platform which requires it has been selected, so that it can be verified. Users of this package should certainly not assume that the clock being used to control system time will continue to be the same as the kernel's clock.

The package also makes use of the kernel clock conversion facilities in order to translate clock ticks to or from real time in a scalable way when calling this package's tick conversion functions. The HAL clock API also provides a mechanism to convert ticks to and from real time, but this is not designed to scale beyond nanosecond times, nor tick values greater than 32-bits in width.

It is strongly recommended that users use the time conversion functions provided by this package, not only to avoid duplication, but also because in the case of conversion of absolute time values, the values returned can be affected by any fine adjustment in progress at that time.

188.3. Wallclock (RTC)

This package can optionally be configured to use a wallclock (RTC) device driver if configured in the system (the CYGPKG_CLOCK_COMMON_USE_WALLCLOCK CDL configuration option). If enabled, time will be retrieved from the wallclock device when the system starts, which is then used to initialize system time.

If no wallclock device is present in the configuration, then time will be initialized to a default date of 2012-01-01 00:00:00 UTC, although obviously it can then be subsequently set to the correct time by the user, or by services such as a network time client.

The user is free to trigger an update of the wallclock from the system time with the API function cyg_clock_sync_wallclock(). This will cause the clock management thread to wake up and set the wallclock time. An argument to the function indicates whether to do so synchronously (i.e. to wait for completion) or asynchronously (complete in the background).

Alternatively, CDL configuration options are provided to force the wallclock to be updated whenever time is set. However this can be expensive if time is updated frequently, which can sometimes happen, for example, with Network Time Protocol (NTP) clients.

A second alternative is also provided to periodically wake the clock management thread up regularly after a configured number of kernel ticks.

188.4. C library and POSIX layers

The C library time functions, and POSIX layer clock and timer functions will always use this package if present in the configuration. Obviously there can only be one notional system time, so when this package is present, no other means of providing a system time is used.

It also avoids significant duplication. In particular, similarly implemented clock conversion functions had existed in multiple locations prior to this package being used.