High Performance OPC UA Server SDK  1.1.1.177
Timer Module

The SDK needs timers in several places like periodic sampling of data, subscription handling, etc.

The timer module encapsulates platform specific implementation details. You can add your own timer backends based on native system APIs like e.g. POSIX timers. This would allows to get timers with higher precision, what is not necessary for the SDK itself, but maybe useful if you need more accurate timers for sampling data.

Software Based Timers

We created a pure software based timer implementation that is based on ua_time_tickcount(). This make this timer backend platform independent, so that it can be used on all platforms which provide a correct ua_time_tickcount() implementation. Note that ua_time_tickcount() is a monotonic tickcount and must not be affected by time synchronization (e.g. NTP).

This timer backend does not creates its own thread or something like that, so to be able to send a timer callback it must be polled periodically from your main thread (single-threaded architecture). This is done by calling the function timer_update. When calling this function all due timers will be fired. The other purpose is that it will the time when the next timer will be due. This value is used as timeout parameter for the ua_net_do_events() call. This call is the only allowed blocking call in the single-threaded application. When using the Berkeley sockets network backend this calls select() internally and uses the timeout parameter for the select() call. This way ua_net_do_events will return in time for the next timer_update() call.

Note that this implementation does not provide high accuracy. The latency due the other operations like processing network events may delay timer events. However timer events cannot stack up and the timer implementation tries to compensates any delays. But delays longer than timer interval lead to "lost" timer events, which is normally preferable over timer events the get queued.

If you need high precision timers you either need a different timer backends, or use a different API for this task. One example might be highly precise data sampling using a hardware based timer in an interrupt service routine. It would not make sense to drive all timers from such an ISR.