OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [kernel/] [current/] [tests/] [clockcnv.cxx] - Blame information for rev 851

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//        clockcnv.cxx
4
//
5
//        Clock Converter test
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     hmt
43
// Contributors:  hmt
44
// Date:          2000-01-24
45
// Description:   Tests the Kernel Real Time Clock Converter subsystem
46
// 
47
//####DESCRIPTIONEND####
48
 
49
#include <pkgconf/kernel.h>
50
 
51
#include <cyg/kernel/clock.hxx>
52
#include <cyg/kernel/thread.hxx>
53
 
54
#include <cyg/infra/testcase.h>
55
 
56
#include <cyg/kernel/clock.inl>
57
#include <cyg/kernel/thread.inl>
58
 
59
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
60
 
61
#include <cyg/infra/diag.h>
62
 
63
static void null_printf(const char *, ...)
64
{ /* nothing */ }
65
 
66
#define PRINTF0 diag_printf
67
#define nPRINTF0 null_printf
68
 
69
#define nPRINTF1 diag_printf
70
#define PRINTF1 null_printf
71
 
72
#define nPRINTF2 diag_printf
73
#define PRINTF2 null_printf
74
 
75
 
76
#define NTHREADS 1
77
#include "testaux.hxx"
78
 
79
static struct { cyg_uint32 ns; double scale; } ns_tickers[] = {
80
    { 70000000, 7.0 },                  // 7cS
81
    { 50000000, 5.0 },                  // 5cS
82
    { 45000000, 4.5 },                  // 4.5cS
83
    { 30000000, 3.0 },                  // 3cS
84
    { 20000000, 2.0 },                  // 2cS
85
    { 10000000, 1.0 },                  // 1cS - no change
86
    {  5000000, 0.5 },                  // 1/2 a cS
87
    {  4900000, 0.49 },                 // a bit below
88
    {  3333333, 0.3333333 },            // 1/3 cS
89
    {  1250000, 0.125 },                // 800Hz
90
    {  1000000, 0.1 },                  // 1000Hz
91
    {   909090, 0.0909090 },            // 1100Hz
92
    {   490000, 0.049 },                // 490uS
93
    {   333333, 0.0333333 },            // 1/30 cS, 1/3mS
94
    {    49000, 0.0049 },               // 49uS
95
    {    33333, 0.0033333 },            // 1/30 mS
96
    {     4900, 0.00049 },              // 4.9uS
97
    // now some outlandish ones
98
    {      170, 0.000017 },             // 170nS
99
    {       11, 0.0000011 },            // 11nS
100
    { 1000000000u, 100.0 },             // one second
101
    { 1234567777u, 123.4567777 },       // 1.234... seconds
102
    { 4294967291u, 429.4967291 },       // 4.3 seconds, nearly maxint.
103
    // now some which are prime in the nS per tick field
104
    {   909091, 0.0909091 },            // also 1100Hz - but 909091 is a prime!
105
    // and some eye-pleasing primes from the www - if they're not actually
106
    // prime, don't blame me.   http://www.rsok.com/~jrm/printprimes.html
107
    {  1000003, 0.1000003 },
108
    {  1477771, 0.1477771 },
109
    {  2000003, 0.2000003 },
110
    {  2382001, 0.2382001 },
111
    {  3333133, 0.3333133 },
112
    {  3999971, 0.3999971 },
113
    {  5555591, 0.5555591 },
114
    {  6013919, 0.6013919 },
115
    // That's enough
116
};
117
 
118
static void entry0( CYG_ADDRWORD data )
119
{
120
    // First just try it with the clock as default:
121
    Cyg_Clock *rtc = Cyg_Clock::real_time_clock;
122
 
123
    Cyg_Clock::converter cv, rcv;
124
    Cyg_Clock::cyg_resolution res;
125
 
126
    unsigned int counter = 0;
127
    unsigned int skipped = 0;
128
 
129
    unsigned int i;
130
    for ( i = 0; i < sizeof( ns_tickers )/sizeof( ns_tickers[0] ); i++ ) {
131
 
132
        unsigned int lcounter = 0;
133
        unsigned int lskipped = 0;
134
 
135
        rtc->get_other_to_clock_converter( ns_tickers[i].ns, &cv );
136
        rtc->get_clock_to_other_converter( ns_tickers[i].ns, &rcv );
137
 
138
        PRINTF1( "ns per tick: %d\n", ns_tickers[i].ns );
139
        PRINTF1( "  converter: * %d / %d * %d / %d\n",
140
                     (int)cv.mul1, (int)cv.div1, (int)cv.mul2,(int) cv.div2 );
141
        PRINTF1( "   reverser: * %d / %d * %d / %d\n",
142
                     (int)rcv.mul1, (int)rcv.div1, (int)rcv.mul2, (int)rcv.div2 );
143
 
144
        double d = 1.0;
145
        d *= (double)cv.mul1;
146
        d /= (double)cv.div1;
147
        d *= (double)cv.mul2;
148
        d /= (double)cv.div2;
149
        d *= (double)rcv.mul1;
150
        d /= (double)rcv.div1;
151
        d *= (double)rcv.mul2;
152
        d /= (double)rcv.div2;
153
        PRINTF1( "       composite product %d.%d\n",
154
                     (int)d, ((int)(d * 1000000) % 1000000 ) );
155
        d -= 1.0;
156
        CYG_TEST_CHECK( d < +0.0001, "Overflow in composite product" );
157
        CYG_TEST_CHECK( d > -0.0001, "Underflow in composite product" );
158
 
159
        res = rtc->get_resolution();
160
 
161
        double factor_other_to_clock;
162
        double factor_clock_to_other;
163
 
164
        // res.dividend/res.divisor is the number of nS in a system
165
        // clock tick.  So:
166
        d = (double)res.dividend/(double)res.divisor;
167
 
168
        factor_other_to_clock = ns_tickers[i].scale * 1.0e7 / d ;
169
        factor_clock_to_other = d / (ns_tickers[i].scale * 1.0e7);
170
 
171
        unsigned int j;
172
        for ( j = 1; j < 100; j++ ) {
173
            cyg_uint64 delay;
174
            if (cyg_test_is_simulator)
175
                j += 30;                // test fewer values
176
                                   /* tr.b..m..k.. */
177
 
178
#ifdef CYGPKG_HAL_V85X_V850_CEB
179
            j += 30;                    // test fewer values
180
#endif
181
 
182
            for ( delay = j; delay < 1000000000000ll; delay *= 10 ) {
183
                // get the converted result
184
                cyg_uint64 result = Cyg_Clock::convert( delay, &cv );
185
 
186
                counter++; lcounter++;
187
                if ( (double)delay * (double)cv.mul1 > 1.6e+19 ||
188
                     (double)delay * (double)rcv.mul1 > 1.6e+19 ) {
189
                    // in silly territory now, give up.
190
                    // (that's MAXINT squared, approx.)
191
                    skipped++; lskipped++;
192
                    continue; // so the counter is accurate
193
                }
194
 
195
                PRINTF2( "delay %x%08x to result %x%08x\n",
196
                             (int)(delay >> 32), (int)delay,
197
                             (int)(result >> 32), (int)result );
198
 
199
                // get what it should be in double maths
200
                double delta = factor_other_to_clock * (double)delay;
201
                if ( delta > 1000.0 ) {
202
                    delta = (double)result - delta;
203
                    delta /= (double)result;
204
                    CYG_TEST_CHECK( delta <= +0.01,
205
                          "Proportional overflow in conversion to" );
206
                    CYG_TEST_CHECK( delta >= -0.01,
207
                          "Proportional underflow in conversion to" );
208
                }
209
                else {
210
                    cyg_uint64 lo = (cyg_uint64)(delta); // assume TRUNCATION
211
                    cyg_uint64 hi = lo + 1;
212
                    CYG_TEST_CHECK( hi >= result,
213
                                    "Range overflow in conversion to" );
214
                    CYG_TEST_CHECK( lo <= result,
215
                                    "Range underflow in conversion to" );
216
                }
217
 
218
                // get the converted result
219
                result = Cyg_Clock::convert( delay, &rcv );
220
 
221
                PRINTF2( "delay %x%08x from result %x%08x\n",
222
                             (int)(delay >> 32), (int)delay,
223
                             (int)(result >> 32), (int)result );
224
 
225
                // get what it should be in double maths
226
                delta = factor_clock_to_other * (double)delay;
227
                if ( delta > 1000.0 ) {
228
                    delta = (double)result - delta;
229
                    delta /= (double)result;
230
                    CYG_TEST_CHECK( delta <= +0.01,
231
                          "Proportional overflow in conversion from" );
232
                    CYG_TEST_CHECK( delta >= -0.01,
233
                          "Proportional underflow in conversion from" );
234
                }
235
                else {
236
                    cyg_uint64 lo = (cyg_uint64)(delta); // assume TRUNCATION
237
                    cyg_uint64 hi = lo + 1;
238
                    CYG_TEST_CHECK( hi >= result,
239
                                    "Range overflow in conversion from" );
240
                    CYG_TEST_CHECK( lo <= result,
241
                                    "Range underflow in conversion from" );
242
                }
243
 
244
                if (cyg_test_is_simulator)
245
                    break;
246
            }
247
        }
248
        PRINTF0( "INFO:<%d nS/tick: tested %d values, skipped %d because of overflow>\n",
249
                 ns_tickers[i].ns, lcounter, lskipped );
250
    }
251
 
252
    PRINTF0( "INFO:<tested %d values, total skipped %d because of overflow>\n",
253
             counter, skipped );
254
 
255
    CYG_TEST_PASS_FINISH("ClockCnv OK");
256
}
257
 
258
void clockcnv_main( void )
259
{
260
    CYG_TEST_INIT();
261
    new_thread(entry0, (CYG_ADDRWORD)&thread_obj[0]);
262
    Cyg_Scheduler::start();
263
}
264
 
265
externC void
266
cyg_start( void )
267
{
268
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
269
    cyg_hal_invoke_constructors();
270
#endif
271
    clockcnv_main();
272
}
273
 
274
#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
275
 
276
externC void
277
cyg_start( void )
278
{
279
    CYG_TEST_INIT();
280
    CYG_TEST_NA( "Kernel real-time clock disabled");
281
}
282
 
283
#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
284
 
285
// EOF clockcnv.cxx

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.