📄 testintr.cxx
字号:
//===========================================================================
//
// testintr.c
//
// uITRON "C" test program for ixxx_yyy interrupt safe operators
//
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//===========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): hmt
// Contributors:hmt
// Date: 1998-08-20
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
#include <pkgconf/system.h>
#include <pkgconf/uitron.h> // uITRON setup CYGNUM_UITRON_SEMAS
// CYGPKG_UITRON et al
#include <cyg/infra/testcase.h> // testing infrastructure
#ifdef CYGPKG_UITRON // we DO want the uITRON package
#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE // we DO want prioritized threads
#ifdef CYGFUN_KERNEL_THREADS_TIMER // we DO want timout-able calls
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK // we DO want the realtime clock
// we're OK if it's C++ or neither of those two is defined:
#if defined( __cplusplus ) || \ (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \ !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
// =================== TEST CONFIGURATION ===================
#if \ /* test configuration for enough tasks */ \ (CYGNUM_UITRON_TASKS >= 4) && \ (CYGNUM_UITRON_TASKS < 90) && \ (CYGNUM_UITRON_START_TASKS == 1) && \ ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) || \ CYGNUM_UITRON_TASKS_INITIALLY >= 4 ) && \ \ /* the end of the large #if statement */ \ 1
// ============================ END ============================
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/infra/diag.h>
#include <cyg/compat/uitron/uit_func.h> // uITRON
#include <cyg/compat/uitron/uit_ifnc.h> // uITRON interrupt funcs
void set_interrupt_number( void );
unsigned int clock_interrupt = 0;
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
set_interrupt_number();
cyg_uitron_start();
}
extern "C" {
void task1( unsigned int arg );
void task2( unsigned int arg );
void task3( unsigned int arg );
void task4( unsigned int arg );
}
volatile int intercom = 0;
INT scratch = 0;
// Plan: replace (by direct intervention) the ISR and DSR of the regular
// timer interrupt; be sure to ack the clock intr using the appropriate hal
// macros.
//
// The new ISR(s) will simply use the interrupt-safe signalling functions
// to control a 2nd task. Main task will check on the state thereof.
//
// We must test the ixxx_yyy() funcs with the scheduler already locked
// also, by direct sched calls on the KAPI. This must verify that the
// signal only happens when the scheduler unlocks.
//
// The 4 producer ops are:
// iwup_tsk ( ID tskid );
// isig_sem ( ID semid );
// iset_flg ( ID flgid, UINT setptn );
// isnd_msg ( ID mbxid, T_MSG *pk_msg );
//
// and return macros are:
// ret_wup( ID tskid );
// ret_int();
//
// These ISRs perform the producer ops on all available objects in turn.
// Tasks 2-4
// Semas 1-4
// Flags 1-4 with marching bit data; they'll all be set to 0x1ff eventually
// Mboxes 1-4 with an arbitrary pointer
enum {
NOTHING = 0,
SLP,
SEM,
FLG,
MBX,
EXIT
};
#define ACK_CLOCK() CYG_MACRO_START \ HAL_CLOCK_RESET( CYGNUM_HAL_INTERRUPT_RTC, \ CYGNUM_KERNEL_COUNTERS_RTC_PERIOD ); \ HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_RTC ); \CYG_MACRO_END
#define CHECK_TID() CYG_MACRO_START \ int my_tid; \ ER ercd; \ ercd = get_tid( &my_tid ); \ CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" ); \ CYG_TEST_CHECK( 0 == my_tid, "tid not 0 in ISR" ); \CYG_MACRO_END
unsigned int
isr_wup_tsk( unsigned int vector, unsigned int data )
{
// Hit TASKS in range 2..4
static int wtid = 2;
ACK_CLOCK();
CHECK_TID();
iwup_tsk( wtid );
wtid++;
if ( 5 == wtid ) wtid = 2;
ret_int();
}
unsigned int
isr_ret_wup( unsigned int vector, unsigned int data )
{
// Hit TASKS in range 2..4
static int rwid = 2;
ACK_CLOCK();
CHECK_TID();
rwid++;
if ( 6 == rwid ) rwid = 3;
ret_wup( rwid - 1 );
}
unsigned int
isr_sig_sem( unsigned int vector, unsigned int data )
{
// Hit SEMAS in range 1..3
static int ssid = 1;
ACK_CLOCK();
CHECK_TID();
isig_sem( ssid );
ssid++;
if ( ssid == 4 ) ssid = 1;
ret_int();
}
unsigned int
isr_set_flg( unsigned int vector, unsigned int data )
{
// Hit FLAGS in range 1..4
static int sfid = 1;
static int sfdata = 0xff;
ACK_CLOCK();
CHECK_TID();
iset_flg( sfid, sfdata );
sfid++;
if ( sfid == 5 ) sfid = 1;
// sfdata <<= 1;
// if ( sfdata == 0x20 ) sfdata = 1; // so that eventually all 0x1f set
ret_int();
}
unsigned int
isr_snd_msg( unsigned int vector, unsigned int data )
{
// Hit MBOXES in range 1..4
static int smid = 1;
ACK_CLOCK();
CHECK_TID();
isnd_msg( smid, (T_MSG *)&smid );
smid++;
if ( smid == 5 ) smid = 1;
ret_int();
}
void attach_isr( unsigned int (*isr)(unsigned int, unsigned int) );
void detach_isr( unsigned int (*isr)(unsigned int, unsigned int) );
void lock_sched( void );
void unlock_sched( void );
volatile int count = -1;
/*
#define BIGDELAY 50000000
#define SMALLDELAY (BIGDELAY/SMALLLOOPS)
#define SMALLLOOPS 3
#define xxxLONGDELAY() \do { \ int i; \ for ( i = 0; i < BIGDELAY; i++ ) \ if ( wakeups[ 4 ] > prewups[ 4 ] + 99 ) break; \} while ( 0 )
#define xxxDELAYLOCKSCHED() \do { \ int i,j; \ for ( j = 0; j < SMALLLOOPS; j++ ) { \ lock_sched(); \ for ( i = 0; i < SMALLDELAY; i++ ) \ if ( wakeups[ 4 ] > prewups[ 4 ] + 99 ) break; \ unlock_sched(); \ if ( wakeups[ 4 ] > prewups[ 4 ] + 99 ) break; \ } \} while ( 0 )
*/
#define SMALLDELAYHW (5000000)
#define EVENTSHW ( 20)
#define SMALLDELAYSIM ( 100000)
#define EVENTSSIM ( 4)
#define SMALLDELAY (smalldelay)
#define EVENTS (events)
static int smalldelay = SMALLDELAYHW;
static int events = EVENTSHW;
#define LONGDELAY() do { \ count = 0; \ do count++; while ( wakeups[ 4 ] < prewups[ 4 ] + EVENTS ); \} while ( 0 )
#define DELAYLOCKSCHED() \do { \ count = 0; \ int i; \ do { \ lock_sched(); \ for ( i = 0; i < SMALLDELAY; i++ ) { \ count++; \ if ( wakeups[ 4 ] >= prewups[ 4 ] + EVENTS ) \ break; \ } \ unlock_sched(); \ CYG_TEST_INFO(" [Still iterating, please wait....] "); \ } while ( wakeups[ 4 ] < prewups[ 4 ] + EVENTS ); \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -