void cyg_counter_create(cyg_handle_t* handle, cyg_counter* counter);
void cyg_counter_delete(cyg_handle_t counter);
cyg_tick_count_t cyg_counter_current_value(cyg_handle_t counter);
void cyg_counter_set_value(cyg_handle_t counter, cyg_tick_count_t new_value);
void cyg_counter_tick(cyg_handle_t counter);
Kernel counters can be used to keep track of how many times a particular event has occurred. Usually this event is an external signal of some sort. The most common use of counters is in the implementation of clocks, but they can be useful with other event sources as well. Application code can attach alarms to counters, causing a function to be called when some number of events have occurred.
A new counter is initialized by a call to
cyg_counter_create. The first argument is used to
return a handle to the new counter which can be used for subsequent
operations. The second argument allows the application to provide the
memory needed for the object, thus eliminating any need for dynamic
memory allocation within the kernel. If a counter is no longer
required and does not have any alarms attached then
cyg_counter_delete can be used to release the
resources, allowing the
structure to be re-used.
Initializing a counter does not automatically attach it to any source
of events. Instead some other code needs to call
cyg_counter_tick whenever a suitable event
occurs, which will cause the counter to be incremented and may cause
alarms to trigger. The current value associated with the counter can
be retrieved using
the latter function is only used during initialization, for example to
set a clock to wallclock time, but it can be used to reset a counter
if necessary. However
never trigger any alarms. A newly initialized counter has a starting
value of 0.
The kernel provides two different implementations of counters. The
stores all alarms attached to the counter on a single list. This is
simple and usually efficient. However when a tick occurs the kernel
code has to traverse this list, typically at DSR level, so if there
are a significant number of alarms attached to a single counter this
will affect the system's dispatch latency. The alternative
stores each alarm in one of an array of lists such that at most one of
the lists needs to be searched per clock tick. This involves extra
code and data, but can improve real-time responsiveness in some
circumstances. Another configuration option that is relevant here
CYGIMP_KERNEL_COUNTERS_SORT_LIST, which is
disabled by default. This provides a trade off between doing work
whenever a new alarm is added to a counter and doing work whenever a
tick occurs. It is application-dependent which of these is more
cyg_counter_create is typically called during
system initialization but may also be called in thread context.
cyg_counter_delete may be called during
initialization or in thread context.
cyg_counter_tick may be called during
initialization or from thread or DSR context. In fact,
cyg_counter_tick is usually called from inside a
DSR in response to an external event of some sort.