]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/kernel/v2_0/include/clock.hxx
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / kernel / v2_0 / include / clock.hxx
1 #ifndef CYGONCE_KERNEL_CLOCK_HXX
2 #define CYGONCE_KERNEL_CLOCK_HXX
3
4 //==========================================================================
5 //
6 //      clock.hxx
7 //
8 //      Clock and Alarm class declaration(s)
9 //
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.
15 //
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.
19 //
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
23 // for more details.
24 //
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.
28 //
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.
35 //
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.
38 //
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####
45 //
46 // Author(s):   nickg
47 // Contributors:        nickg
48 // Date:        1997-09-09
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,
52 //              Clocks and Alarms.
53 // Usage:       #include <cyg/kernel/clock.hxx>
54 //
55 //####DESCRIPTIONEND####
56 //
57 //==========================================================================
58
59 #include <cyg/kernel/ktypes.h>
60 #include <cyg/infra/cyg_ass.h>            // assertion macros
61
62 #include <cyg/infra/clist.hxx>
63
64 // -------------------------------------------------------------------------
65 // Forward definitions and typedefs.
66
67 class Cyg_Alarm;
68
69 typedef void cyg_alarm_fn(Cyg_Alarm *alarm, CYG_ADDRWORD data);
70
71 typedef Cyg_CList_T<Cyg_Alarm> Cyg_Alarm_List;
72
73 // -------------------------------------------------------------------------
74 // Counter object.
75
76 class Cyg_Counter
77 {
78
79     friend class Cyg_Alarm;
80
81 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST)
82
83     Cyg_Alarm_List      alarm_list;     // Linear list of Alarms
84
85 #elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST)
86
87     Cyg_Alarm_List      alarm_list[CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE];
88     
89 #endif
90
91     volatile cyg_tick_count counter;    // counter value
92
93     cyg_uint32          increment;      // increment per tick
94
95     // Add an alarm to this counter
96     void add_alarm( Cyg_Alarm *alarm );
97
98     // Remove an alarm from this counter
99     void rem_alarm( Cyg_Alarm *alarm );
100     
101 public:
102
103     CYGDBG_DEFINE_CHECK_THIS
104     
105     Cyg_Counter(
106         cyg_uint32      increment = 1
107     );
108
109     ~Cyg_Counter();
110     
111     // Return current value of counter
112     cyg_tick_count current_value();
113
114     // Return low and high halves of the
115     // counter value.
116     cyg_uint32 current_value_lo();
117     cyg_uint32 current_value_hi();
118     
119     // Set the counter's current value
120     void set_value( cyg_tick_count new_value);
121         
122     // Advance counter by some number of ticks
123     void tick( cyg_uint32 ticks = 1);
124
125 };
126
127 // -------------------------------------------------------------------------
128 // Clock class. This is derived from a Counter and defines extra
129 // features to support clock-like behaviour.
130
131 class Cyg_Clock
132     : public Cyg_Counter
133 {
134
135 public:
136
137     CYGDBG_DEFINE_CHECK_THIS
138
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
142     // per tick.
143     struct cyg_resolution {
144         cyg_uint32  dividend;
145         cyg_uint32  divisor;
146     };
147
148 private:
149
150     cyg_resolution      resolution;     // Current clock resolution
151
152 public:
153
154     Cyg_Clock(                          // Create clock with given resolution
155         cyg_resolution resolution
156         );
157
158     ~Cyg_Clock();                       // Destructor
159         
160     cyg_resolution get_resolution();    // Return current resolution
161
162     void set_resolution(                // Set new resolution
163         cyg_resolution resolution
164         ); 
165
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.
171     struct converter {
172         cyg_uint64 mul1, div1, mul2, div2;
173     };
174
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 );
181
182     void get_clock_to_other_converter( cyg_uint64 ns_per_other_tick,
183                                        struct converter *pcc );
184
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 );
190         
191 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK 
192     
193     // There is a system supplied real time clock...
194
195     static Cyg_Clock *real_time_clock;
196
197 #endif    
198         
199 };
200
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.
204
205 class Cyg_Alarm
206 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) || defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST)
207     : public Cyg_DNode_T<Cyg_Alarm>
208 #endif
209 {
210     friend class Cyg_Counter;
211     
212 protected:
213     Cyg_Counter         *counter;       // Attached to this counter/clock
214
215     cyg_alarm_fn        *alarm;         // Call-back function
216
217     CYG_ADDRWORD        data;           // Call-back data
218
219     cyg_tick_count      trigger;        // Absolute trigger time
220
221     cyg_tick_count      interval;       // Retrigger interval
222
223     cyg_bool            enabled;        // True if enabled
224
225     Cyg_Alarm();
226
227     void synchronize( void );           // deal with times in the past,
228                                         // make next alarm in synch.
229     
230 public:
231
232     CYGDBG_DEFINE_CHECK_THIS
233     
234     Cyg_Alarm                           // Constructor
235     (
236         Cyg_Counter     *counter,       // Attached to this counter
237         cyg_alarm_fn    *alarm,         // Call-back function
238         CYG_ADDRWORD    data            // Call-back data
239         );
240
241     ~Cyg_Alarm();                       // Destructor
242         
243     void initialize(                    // Initialize Alarm
244         cyg_tick_count    trigger,      // Absolute trigger time
245         cyg_tick_count    interval = 0  // Relative retrigger interval
246         );
247
248     void enable();                      // Ensure alarm enabled
249
250     void disable();                     // Ensure alarm disabled
251     
252     void get_times(
253         cyg_tick_count  *trigger,       // Next trigger time
254         cyg_tick_count  *interval       // Current interval
255         );
256 };
257
258 // -------------------------------------------------------------------------
259
260 #endif // ifndef CYGONCE_KERNEL_CLOCK_HXX
261 // EOF clock.hxx