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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [eth/] [arm/] [ebsa285/] [current/] [tests/] [test_net_realtime.h] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
#ifndef CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H
2
#define CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H
3
/*==========================================================================
4
//
5
//        test_net_realtime.h
6
//
7
//        Auxiliary test header file
8
//        Provide a thread that runs on EBSA only, which verifies that
9
//        realtime characteristics are preserved.
10
//
11
//==========================================================================
12
// ####ECOSGPLCOPYRIGHTBEGIN####
13
// -------------------------------------------
14
// This file is part of eCos, the Embedded Configurable Operating System.
15
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
16
//
17
// eCos is free software; you can redistribute it and/or modify it under
18
// the terms of the GNU General Public License as published by the Free
19
// Software Foundation; either version 2 or (at your option) any later
20
// version.
21
//
22
// eCos is distributed in the hope that it will be useful, but WITHOUT
23
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25
// for more details.
26
//
27
// You should have received a copy of the GNU General Public License
28
// along with eCos; if not, write to the Free Software Foundation, Inc.,
29
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
30
//
31
// As a special exception, if other files instantiate templates or use
32
// macros or inline functions from this file, or you compile this file
33
// and link it with other works to produce a work based on this file,
34
// this file does not by itself cause the resulting work to be covered by
35
// the GNU General Public License. However the source code for this file
36
// must still be made available in accordance with section (3) of the GNU
37
// General Public License v2.
38
//
39
// This exception does not invalidate any other reasons why a work based
40
// on this file might be covered by the GNU General Public License.
41
// -------------------------------------------
42
// ####ECOSGPLCOPYRIGHTEND####
43
//==========================================================================
44
//#####DESCRIPTIONBEGIN####
45
//
46
// Author(s):     hmt
47
// Contributors:  hmt
48
// Date:          2000-05-03
49
// Description:
50
//
51
//####DESCRIPTIONEND####
52
*/
53
 
54
// This is the API to this file:
55
 
56
#define TNR_OFF() tnr_active = 0
57
#define TNR_ON()  tnr_active = 1
58
#define TNR_INIT() tnr_init()
59
#define TNR_PRINT_ACTIVITY() tnr_print_activity() 
60
 
61
// Tests should use these if they are defined to test that the realtime
62
// characteristics of the world are preserved during a test.
63
//
64
// It is accepted that printing stuff via diag_printf() (and the test
65
// infra) disables interrupts for a long time.  So invoke TNR_OFF/ON()
66
// either side of diagnostic prints, to prevent boguf firings of the
67
// realtime test.
68
 
69
// ------------------------------------------------------------------------
70
 
71
// This file rather assumes that the network is in use, and that therefore
72
// there is also a kernel, and so on....
73
 
74
#include <cyg/infra/testcase.h>         // CYG_TEST_FAIL et al
75
#include <cyg/infra/diag.h>             // diag_printf()
76
#include <cyg/kernel/kapi.h>            // Thread API
77
 
78
#include <cyg/hal/hal_arch.h>           // CYGNUM_HAL_STACK_SIZE_TYPICAL
79
#include <cyg/hal/hal_intr.h>           // Interrupt names
80
#include <cyg/hal/hal_ebsa285.h>        // Hardware definitions
81
 
82
// The EBSA has 4 hardware timers; timer 3 is the kernel's realtime clock
83
// because it is connected to a separate, indepenent 3.68MHz signal; timer
84
// 4 can be used as a watchdog.  So we have timers 1 and 2 to use.
85
// Timers 1 and 2 have an input clock of 50MHz on fclk_in.
86
// Timer 2 should be initialized for periodic interrupts per 500uS.
87
// Timer 1 should be initialized for a one-shot interrupt after 1mS (1000uS).
88
//
89
// Timer 2's ISR examines the state of timer 1; if it has expired, the test
90
// has failed.  7 out of 8 hits, timer 1 is reinitialized for the 1mS; on
91
// the 8th event, timer1 is set for 2mS.  The next timer 2 event calls its
92
// DSR, which in turn signals a semaphore which awakens a real task, which
93
// again checks and re-initializes timer1 in the same way.
94
//
95
// All this ensures that interrupts are never delayed by more than 500uS,
96
// and that signalling a real task always takes less than 1500uS.
97
//
98
// This system, once activated, will run non-intrusively along with all
99
// networking tests.
100
//
101
// Special care (aka a hack) may be needed to make it work with the
102
// diagnostic channel; that disables interrupts typically for
103
//   100[characters] * 8[bits/byte] / 38400[Baud]  [Seconds] = 20mS.
104
 
105
// Use the fclk_in divided-by 256 mode:
106
#if 0 // Default, really 1mS, 2mS, 500uS
107
#define TNR_TIMER1_PERIOD_1mS     ((50 * 1000)     >>8)
108
#define TNR_TIMER1_PERIOD_2mS     ((50 * 1000 * 2) >>8)
109
#define TNR_TIMER2_PERIOD_500uS   ((50 *  500)     >>8)
110
#else // pushing the envelope... 1/5 as much:
111
#define FACTOR 200 // 1000 is "normal"
112
#define TNR_TIMER1_PERIOD_1mS     ((50 * FACTOR)     >>8)
113
#define TNR_TIMER1_PERIOD_2mS     ((50 * FACTOR * 2) >>8)
114
#define TNR_TIMER2_PERIOD_500uS   ((50 * FACTOR / 2) >>8)
115
#endif
116
 
117
#define TNR_TIMER1_INIT   (0x88)  // Enabled, free running, fclk_in/256
118
#define TNR_TIMER2_INIT   (0xc8)  // Enabled, periodic, fclk_in/256
119
 
120
// This way, if timer1 is > TNR_TIMER1_PERIOD_2mS, then we know it has
121
// wrapped; its full range is 85 seconds, one would hope to get back in
122
// that time!
123
 
124
static volatile int tnr_active = 0;
125
static volatile int tnr_t2_counter = 0;
126
 
127
static  cyg_sem_t tnr_sema;
128
 
129
static char tnr_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
130
static cyg_thread tnr_thread_data;
131
static cyg_handle_t tnr_thread_handle;
132
 
133
static cyg_interrupt tnr_t1_intr, tnr_t2_intr;
134
static cyg_handle_t tnr_t1_inth, tnr_t2_inth;
135
 
136
struct {
137
    int timer1_isr;
138
    int timer2_isr;
139
    int timer2_isr_active;
140
    int timer2_dsr;
141
    int timer2_thd;
142
    int timer2_thd_active;
143
} tnr_activity_counts = { 0,0,0,0,0,0 };
144
 
145
 
146
static cyg_uint32 tnr_timer1_isr(cyg_vector_t vector, cyg_addrword_t data)
147
{
148
    tnr_activity_counts.timer1_isr++;
149
 
150
    if ( tnr_active )
151
        CYG_TEST_FAIL_EXIT( "test_net_realtime: Timer1 fired" );
152
 
153
    *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt (Data: don't care)
154
    HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_TIMER_1 );
155
 
156
    return CYG_ISR_HANDLED;
157
}
158
 
159
static cyg_uint32 tnr_timer2_isr(cyg_vector_t vector, cyg_addrword_t data)
160
{
161
    tnr_activity_counts.timer2_isr++;
162
 
163
    *SA110_TIMER2_CLEAR = 0; // Clear any pending interrupt (Data: don't care)
164
    HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_TIMER_2 );
165
 
166
    if ( tnr_active ) {
167
        tnr_activity_counts.timer2_isr_active++;
168
        if ( (*SA110_TIMER1_VALUE) > (4 * TNR_TIMER1_PERIOD_1mS) ) {
169
            // Then it has wrapped around, bad bad bad
170
            CYG_TEST_FAIL_EXIT( "tnr_timer2_isr: Timer1 wrapped" );
171
        }
172
    }
173
    tnr_t2_counter++;
174
    // We go though each of the following states in turn:
175
    switch ( tnr_t2_counter & 7 ) {
176
    case 0:
177
        // Then this is an 8th event:
178
        *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_2mS;
179
        return CYG_ISR_HANDLED;
180
    case 1:
181
        return CYG_ISR_CALL_DSR; // See how long to call a DSR &c..
182
        // without resetting timer1: 1500uS left now
183
    default:
184
        // Reset timer1 again.  By doing this in time every time it should
185
        // never fire.
186
        *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_1mS;
187
    }
188
    return CYG_ISR_HANDLED;
189
}
190
 
191
static void tnr_timer2_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
192
{
193
    tnr_activity_counts.timer2_dsr++;
194
 
195
    if ( CYGNUM_HAL_INTERRUPT_TIMER_2 != vector )
196
        CYG_TEST_FAIL_EXIT( "tnr_timer2_dsr: Bad vector" );
197
 
198
    cyg_semaphore_post( &tnr_sema );
199
}
200
 
201
static void tnr_timer2_service_thread( cyg_addrword_t param )
202
{
203
    while (1) {
204
        cyg_semaphore_wait( &tnr_sema );
205
        tnr_activity_counts.timer2_thd++;
206
        if ( tnr_active ) {
207
            tnr_activity_counts.timer2_thd_active++;
208
            if ( (*SA110_TIMER1_VALUE) > (4 * TNR_TIMER1_PERIOD_1mS) ) {
209
                // Then it has wrapped around, bad bad bad
210
                CYG_TEST_FAIL_EXIT( "tnr_timer2_service_thread: Timer1 wrapped" );
211
            }
212
        }
213
        // Reset timer1 again.  By doing this in time every time it should
214
        // never fire.
215
        *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_1mS;
216
    }
217
}
218
 
219
 
220
static void tnr_init( void )
221
{
222
    // init the semaphore
223
    cyg_semaphore_init( &tnr_sema, 0 );
224
 
225
    // create and start the thread
226
    cyg_thread_create(2,                  // Priority - just a number
227
                      tnr_timer2_service_thread,
228
                      0,                  // entry parameter
229
                      "Test Net Realtime tnr_timer2_service_thread",
230
                     &tnr_stack[0],       // Stack
231
                      sizeof(tnr_stack),  // Size
232
                      &tnr_thread_handle, // Handle
233
                      &tnr_thread_data    // Thread data structure
234
        );
235
    cyg_thread_resume( tnr_thread_handle );
236
 
237
    // set up and attach the interrupts et al...
238
    cyg_interrupt_create(
239
        CYGNUM_HAL_INTERRUPT_TIMER_2,   /* Vector to attach to       */
240
        0,                              /* Queue priority            */
241
        0,                              /* Data pointer              */
242
        tnr_timer2_isr,                 /* Interrupt Service Routine */
243
        tnr_timer2_dsr,                 /* Deferred Service Routine  */
244
        &tnr_t2_inth,                   /* returned handle           */
245
        &tnr_t2_intr                    /* put interrupt here        */
246
        );
247
 
248
    cyg_interrupt_create(
249
        CYGNUM_HAL_INTERRUPT_TIMER_1,   /* Vector to attach to       */
250
        0,                              /* Queue priority            */
251
        0,                              /* Data pointer              */
252
        tnr_timer1_isr,                 /* Interrupt Service Routine */
253
        tnr_timer2_dsr, /* re-use! */   /* Deferred Service Routine  */
254
        &tnr_t1_inth,                   /* returned handle           */
255
        &tnr_t1_intr                    /* put interrupt here        */
256
        );
257
 
258
    cyg_interrupt_attach( tnr_t1_inth );
259
    cyg_interrupt_attach( tnr_t2_inth );
260
 
261
    *SA110_TIMER1_CONTROL = 0;          // Disable while we are setting up
262
    *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_2mS;
263
    *SA110_TIMER1_CLEAR = 0;            // Clear any pending interrupt
264
    *SA110_TIMER1_CONTROL = TNR_TIMER1_INIT;
265
    *SA110_TIMER1_CLEAR = 0;            // Clear any pending interrupt again
266
 
267
    *SA110_TIMER2_CONTROL = 0;          // Disable while we are setting up
268
    *SA110_TIMER2_LOAD = TNR_TIMER2_PERIOD_500uS;
269
    *SA110_TIMER2_CLEAR = 0;            // Clear any pending interrupt
270
    *SA110_TIMER2_CONTROL = TNR_TIMER2_INIT;
271
    *SA110_TIMER2_CLEAR = 0;            // Clear any pending interrupt again
272
 
273
    cyg_interrupt_unmask( CYGNUM_HAL_INTERRUPT_TIMER_2 );
274
    cyg_interrupt_unmask( CYGNUM_HAL_INTERRUPT_TIMER_1 );
275
}
276
 
277
static void tnr_print_activity( void )
278
{
279
    int tmp = tnr_active;
280
    tnr_active = 0;
281
    diag_printf( "Test-net-realtime: interrupt activity log:\n" );
282
    diag_printf( "    timer1_isr %10d\n", tnr_activity_counts.timer1_isr );
283
    diag_printf( "    timer2_isr %10d\n", tnr_activity_counts.timer2_isr );
284
    diag_printf( "      (active) %10d\n", tnr_activity_counts.timer2_isr_active );
285
    diag_printf( "    timer2_dsr %10d\n", tnr_activity_counts.timer2_dsr );
286
    diag_printf( "    timer2_thd %10d\n", tnr_activity_counts.timer2_thd );
287
    diag_printf( "      (active) %10d\n", tnr_activity_counts.timer2_thd_active );
288
    tnr_active = tmp;
289
}
290
 
291
#endif /* ifndef CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H */
292
 
293
/* EOF test_net_realtime.h */

powered by: WebSVN 2.1.0

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