1 #ifndef CYGONCE_KERNEL_CLOCK_HXX
2 #define CYGONCE_KERNEL_CLOCK_HXX
4 //==========================================================================
8 // Clock and Alarm class declaration(s)
10 //==========================================================================
11 //####ECOSGPLCOPYRIGHTBEGIN####
12 // -------------------------------------------
13 // This file is part of eCos, the Embedded Configurable Operating System.
14 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
16 // eCos is free software; you can redistribute it and/or modify it under
17 // the terms of the GNU General Public License as published by the Free
18 // Software Foundation; either version 2 or (at your option) any later version.
20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 // You should have received a copy of the GNU General Public License along
26 // with eCos; if not, write to the Free Software Foundation, Inc.,
27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
29 // As a special exception, if other files instantiate templates or use macros
30 // or inline functions from this file, or you compile this file and link it
31 // with other works to produce a work based on this file, this file does not
32 // by itself cause the resulting work to be covered by the GNU General Public
33 // License. However the source code for this file must still be made available
34 // in accordance with section (3) of the GNU General Public License.
36 // This exception does not invalidate any other reasons why a work based on
37 // this file might be covered by the GNU General Public License.
39 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
40 // at http://sources.redhat.com/ecos/ecos-license/
41 // -------------------------------------------
42 //####ECOSGPLCOPYRIGHTEND####
43 //==========================================================================
44 //#####DESCRIPTIONBEGIN####
47 // Contributors: nickg
49 // Purpose: Define Clock and Alarm class interfaces
50 // Description: The classes defined here collectively implement the
51 // internal API used to create, configure and manage Counters,
53 // Usage: #include <cyg/kernel/clock.hxx>
55 //####DESCRIPTIONEND####
57 //==========================================================================
59 #include <cyg/kernel/ktypes.h>
60 #include <cyg/infra/cyg_ass.h> // assertion macros
62 #include <cyg/infra/clist.hxx>
64 // -------------------------------------------------------------------------
65 // Forward definitions and typedefs.
69 typedef void cyg_alarm_fn(Cyg_Alarm *alarm, CYG_ADDRWORD data);
71 typedef Cyg_CList_T<Cyg_Alarm> Cyg_Alarm_List;
73 // -------------------------------------------------------------------------
79 friend class Cyg_Alarm;
81 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST)
83 Cyg_Alarm_List alarm_list; // Linear list of Alarms
85 #elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST)
87 Cyg_Alarm_List alarm_list[CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE];
91 volatile cyg_tick_count counter; // counter value
93 cyg_uint32 increment; // increment per tick
95 // Add an alarm to this counter
96 void add_alarm( Cyg_Alarm *alarm );
98 // Remove an alarm from this counter
99 void rem_alarm( Cyg_Alarm *alarm );
103 CYGDBG_DEFINE_CHECK_THIS
106 cyg_uint32 increment = 1
111 // Return current value of counter
112 cyg_tick_count current_value();
114 // Return low and high halves of the
116 cyg_uint32 current_value_lo();
117 cyg_uint32 current_value_hi();
119 // Set the counter's current value
120 void set_value( cyg_tick_count new_value);
122 // Advance counter by some number of ticks
123 void tick( cyg_uint32 ticks = 1);
127 // -------------------------------------------------------------------------
128 // Clock class. This is derived from a Counter and defines extra
129 // features to support clock-like behaviour.
137 CYGDBG_DEFINE_CHECK_THIS
139 // This structure allows a more accurate representation
140 // of the resolution than a single integer would allow.
141 // The resolution is defined as dividend/divisor nanoseconds
143 struct cyg_resolution {
150 cyg_resolution resolution; // Current clock resolution
154 Cyg_Clock( // Create clock with given resolution
155 cyg_resolution resolution
158 ~Cyg_Clock(); // Destructor
160 cyg_resolution get_resolution(); // Return current resolution
162 void set_resolution( // Set new resolution
163 cyg_resolution resolution
166 // There is a need for converting from "other" ticks to clock ticks.
167 // We will construct 4 numbers to do the conversion as:
168 // clock_ticks = (((otherticks*mul1)/div1)*mul2/div2)
169 // with the values chosen to minimize the possibility of overflow.
170 // Do the arithmetic in cyg_uint64s throughout.
172 cyg_uint64 mul1, div1, mul2, div2;
175 // There are two of these because the 4 numbers are different depending
176 // on the direction of the conversion, to prevent loss of significance.
177 // NB these relate to the resolution of the clock object they are
178 // called against, not necessarily "the" system real time clock.
179 void get_other_to_clock_converter( cyg_uint64 ns_per_other_tick,
180 struct converter *pcc );
182 void get_clock_to_other_converter( cyg_uint64 ns_per_other_tick,
183 struct converter *pcc );
185 // A utility to perform the conversion in the obvious way, with
186 // rounding to nearest at each stage. Static because it uses a
187 // previously acquired converter.
188 static cyg_tick_count convert( cyg_tick_count value,
189 struct converter *pcc );
191 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
193 // There is a system supplied real time clock...
195 static Cyg_Clock *real_time_clock;
201 // -------------------------------------------------------------------------
202 // Alarm class. An alarm may be attached to a counter (or a clock) to be
203 // called when the trigger value is reached.
206 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) || defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST)
207 : public Cyg_DNode_T<Cyg_Alarm>
210 friend class Cyg_Counter;
213 Cyg_Counter *counter; // Attached to this counter/clock
215 cyg_alarm_fn *alarm; // Call-back function
217 CYG_ADDRWORD data; // Call-back data
219 cyg_tick_count trigger; // Absolute trigger time
221 cyg_tick_count interval; // Retrigger interval
223 cyg_bool enabled; // True if enabled
227 void synchronize( void ); // deal with times in the past,
228 // make next alarm in synch.
232 CYGDBG_DEFINE_CHECK_THIS
234 Cyg_Alarm // Constructor
236 Cyg_Counter *counter, // Attached to this counter
237 cyg_alarm_fn *alarm, // Call-back function
238 CYG_ADDRWORD data // Call-back data
241 ~Cyg_Alarm(); // Destructor
243 void initialize( // Initialize Alarm
244 cyg_tick_count trigger, // Absolute trigger time
245 cyg_tick_count interval = 0 // Relative retrigger interval
248 void enable(); // Ensure alarm enabled
250 void disable(); // Ensure alarm disabled
253 cyg_tick_count *trigger, // Next trigger time
254 cyg_tick_count *interval // Current interval
258 // -------------------------------------------------------------------------
260 #endif // ifndef CYGONCE_KERNEL_CLOCK_HXX