OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/rtos/ecos-2.0/packages/compat/uitron
    from Rev 27 to Rev 174
    Reverse comparison

Rev 27 → Rev 174

/v2_0/cdl/uitron.cdl
0,0 → 1,437
# ====================================================================
#
# uitron.cdl
#
# uITRON configuration data
#
# ====================================================================
#####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): bartv
# Original data: hmt
# Contributors:
# Date: 1999-06-13
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_package CYGPKG_UITRON {
display "uITRON compatibility layer"
include_dir cyg/compat/uitron
doc ref/compat-uitron.html
requires CYGPKG_KERNEL
description "
eCos supports a uITRON Compatibility Layer, providing
full Level S (Standard) compliance with Version 3.02 of
the uITRON Standard, plus many Level E (Extended) features.
uITRON is the premier Japanese embedded RTOS standard."
 
compile uit_func.cxx uit_ifnc.cxx uit_objs.cxx
 
# ------------------------------------------------------------------------
# Conformance check
# ------------------------------------------------------------------------
cdl_interface CYGINT_UITRON_CONFORMANCE {
requires 1 == CYGINT_UITRON_CONFORMANCE
}
 
cdl_option CYGIMP_UITRON_STRICT_CONFORMANCE {
display "Check strict uITRON standards conformance"
default_value 0
requires CYGVAR_KERNEL_COUNTERS_CLOCK
requires CYGSEM_KERNEL_SCHED_MLQUEUE
requires !CYGSEM_KERNEL_SCHED_TIMESLICE
requires CYGFUN_KERNEL_THREADS_TIMER
implements CYGINT_UITRON_CONFORMANCE
description "
Require the rest of the system configuration
to match the needs of strict uITRON standards conformance.
This option can only be set if the rest of the system is
configured correctly for uITRON semantics, for example
there must be a realtime clock, a suitable scheduler, and no
timeslicing.
Of course a system without this selected can be completely
conformant; this is here to help you check."
}
cdl_option CYGIMP_UITRON_LOOSE_CONFORMANCE {
display "System configuration overrides uITRON"
default_value 1
implements CYGINT_UITRON_CONFORMANCE
description "
Do not require the rest of the system configuration
to match the needs of strict uITRON standards conformance.
For example a bitmap scheduler, or timeslicing, can be used
with the uITRON functions, but such an environment is not
strictly conformant with the uITRON specification.
Of course a system with this selected can be completely
conformant; but it is up to you to configure it correctly."
}
 
# ------------------------------------------------------------------------
# uITRON FUNCTION CALLS
# ------------------------------------------------------------------------
cdl_option CYGIMP_UITRON_INLINE_FUNCS {
display "Inline functions"
default_value 0
description "
If compiling your application with a C++ compiler,
uITRON functions can be inline: set this to make it so.
Inlining functions often increases execution speed,
though possibly at the cost of a larger executable,
depending on what functions are used.
Do NOT set this if compiling your application
in plain C."
}
 
cdl_option CYGIMP_UITRON_CPP_OUTLINE_FUNCS {
display "C++ function names"
default_value 0
description "
If compiling your application with a C++ compiler,
uITRON functions can be given C++ style mangled names:
set this to make it so.
This option may make debugging your program easier,
depending on your development environment.
Do NOT set this if compiling your application
in plain C."
}
 
cdl_option CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS {
display "Return error codes for bad params"
default_value 1
description "
When an application is fully debugged there is no need
to check for bad parameters on every system call, for those
parameters which are typically pointers or constants.
Removing the checking code saves space
and improves performance: set this to make it so.
When this option is set, the correctness of parameters
is asserted using CYG_ASSERT() which compiles to
nothing in a non-debug configuration."
}
 
cdl_option CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR {
display "NULL is a good pointer"
default_value 0
description "
uITRON deliberately defines the constant NADR (-1) for
use as an invalid memory address.
The value -1 is chosen to allow working in microcontrollers
which have real memory at address zero, the traditional 'C'
NULL pointer.
By default, uITRON functions check for both NULL and NADR as
bad addresses: set this option to prevent checking for
NULL and allow pointers to address zero to be used."
}
 
# ------------------------------------------------------------------------
# uITRON KERNEL OBJECTS
# ------------------------------------------------------------------------
cdl_component CYGPKG_UITRON_SEMAS {
display "Semaphores"
flavor bool
default_value 1
description "
uITRON Semaphore objects are used with functions
named xxx_sem(); they support traditional semaphore
semantics."
 
script semas.cdl
}
 
cdl_component CYGPKG_UITRON_MBOXES {
display "Mailboxes"
flavor bool
default_value 1
description "
uITRON Mailbox objects are used with functions
named xxx_msg() and xxx_mbx(); they support
passing addresses (of 'messages') between tasks
in a safe manner."
 
script mboxes.cdl
}
 
cdl_component CYGPKG_UITRON_FLAGS {
display "Eventflags"
flavor bool
default_value 1
description "
uITRON Eventflag objects are used with functions
named xxx_flg(); they support communication between
tasks by means of setting and clearing bits in a word
or flag value.
Waiting for all or any of a set of bits is supported."
 
script flags.cdl
}
 
# ------------------------------------------------------------------------
# uITRON TASKS
# ------------------------------------------------------------------------
cdl_component CYGPKG_UITRON_TASKS {
display "Tasks"
flavor none
description "
uITRON Tasks are the basic blocks of multi-tasking
in the uITRON world; they are threads or lightweight
processes, sharing the address space and the CPU.
They communicate using the primitives outlined above.
Each has a stack, an entry point (a C or C++ function),
and (where appropriate) a scheduling priority."
 
script tasks.cdl
}
 
# ------------------------------------------------------------------------
# Memory Pools, both fixed and variable block
# ------------------------------------------------------------------------
cdl_component CYGPKG_UITRON_MEMPOOLFIXED {
display "Fixed-size memorypools"
flavor bool
default_value 1
requires CYGPKG_MEMALLOC
description "
uITRON supports memory pools for dynamic, task-safe
memory allocation.
Two kinds are supported, fixed-size and variable-size.
There may be multiple of each
type of pool, each with differing characteristics.
This option controls whether there are any fixed-size
memorypools in the system.
A fixed-size memorypool allocates blocks of memory of
its preset fixed size and none other."
 
script mempoolfixed.cdl
}
 
cdl_component CYGPKG_UITRON_MEMPOOLVAR {
display "Variable-size memorypools"
flavor bool
default_value 1
requires CYGPKG_MEMALLOC
description "
uITRON supports memory pools for dynamic, task-safe
memory allocation.
Two kinds are supported, fixed-size and variable-size.
There may be multiple of each
type of pool, each with differing characteristics.
This option controls whether there are any variable-size
memorypools in the system.
A variable-size memorypool allocates blocks of memory of
any size requested, resources permitting."
 
script mempoolvar.cdl
}
 
# ------------------------------------------------------------------------
# One-shot Alarm and Cyclic Alarm handlers:
# ------------------------------------------------------------------------
 
cdl_option CYGSEM_UITRON_TIME_IS_MILLISECONDS {
display "uITRON time unit is mS"
flavor bool
default_value 0
active_if CYGVAR_KERNEL_COUNTERS_CLOCK
description "
Setting this option enables a conversion feature so that
time parameters to uITRON APIs are converted from milliSeconds
to whatever the eCos kernel real-time clock's units are,
or vice versa.
If this option is not set, time parameters are expressed in
kernel clock ticks."
}
 
cdl_component CYGPKG_UITRON_ALARMS {
display "Alarm handlers"
flavor bool
default_value 1
requires CYGVAR_KERNEL_COUNTERS_CLOCK
description "
uITRON Alarm Handlers are used with functions
named def_alm() and ref_alm(); they support
simple timing, with a function callback
at the end of the timed period."
 
 
cdl_option CYGNUM_UITRON_ALARMS {
display "Number of alarm handlers"
flavor data
legal_values 1 to 65535
default_value 3
description "
The number of uITRON alarm
handlers present in the system.
Valid alarm handler numbers will range
from 1 to this value."
}
}
 
cdl_component CYGPKG_UITRON_CYCLICS {
display "Cyclic handlers"
flavor bool
default_value 1
requires CYGVAR_KERNEL_COUNTERS_CLOCK
description "
uITRON Cyclic Handlers are used with functions
named xxx_cyc(); they support timing
with a periodic function callback that
can be dynamically turned on or off, and
resynchronized with external events."
 
cdl_option CYGNUM_UITRON_CYCLICS {
display "Number cyclic handlers"
flavor data
legal_values 1 to 65535
default_value 3
description "
The number of uITRON cyclics
handlers present in the system.
Valid cyclic handler numbers will range
from 1 to this value."
}
}
 
# ------------------------------------------------------------------------
# Interrupt-safe functions [ixxx_yyy()]:
# ------------------------------------------------------------------------
cdl_component CYGPKG_UITRON_INTERRUPT_FUNCTIONS {
display "Interrupt-safe functions"
flavor none
description "The uITRON system provides some functions which may
safely be used within interrupt handlers. In eCos, this
means within ISRs, providing that the corresponding DSR is
associated with that interrupt. These functions are
typically named ixxx_yyy(), according to the uITRON
specification, for example isig_sem() corresponds to normal
function sig_sem()."
 
cdl_option CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION {
display "Execute in ISR if safe"
parent CYGPKG_UITRON_INTERRUPT_FUNCTIONS
flavor bool
default_value 1
description "
These functions of necessity maintain a queue of
operations requested for deferred execution. However,
during an interrupt, it may be safe to perform scheduling
operations. If this option is set, the interrupt-safe
functions will have effect there and then if it is indeed
safe, rather than queueing a request to perform the
operation in the DSR."
}
cdl_option CYGNUM_UITRON_ISR_ACTION_QUEUESIZE {
display "Deferred operation queue size"
parent CYGPKG_UITRON_INTERRUPT_FUNCTIONS
flavor data
legal_values 4 8 16 32 64 128 256
default_value 32
description "These functions of necessity maintain a queue of
operations requested for deferred execution. This option
controls the queue size. It must be a power of two for
implementation reasons."
}
}
 
# ------------------------------------------------------------------------
# uITRON VERSION INFORMATION
# ------------------------------------------------------------------------
cdl_component CYGPKG_UITRON_VERSION {
display "Version information"
flavor none
description "
The get_ver() uITRON system call returns
several version related values describing
the vendor, product and CPU in question
as well as the version of the uITRON
standard supported.
These values may be specified here."
 
script version.cdl
}
 
define_proc {
puts $::cdl_header "/***** proc output start *****/"
puts $::cdl_header "#include <pkgconf/system.h>"
puts $::cdl_header "#include <pkgconf/kernel.h>"
puts $::cdl_header "/***** proc output end *****/"
}
 
cdl_component CYGPKG_UITRON_OPTIONS {
display "uITRON build options"
flavor none
description "
Package specific build options including control over
compiler flags used only in building this package,
and details of which tests are built."
 
cdl_option CYGPKG_UITRON_CFLAGS_ADD {
display "Additional compiler flags"
flavor data
no_define
default_value { "" }
description "
This option modifies the set of compiler flags for
building the uITRON compatibility layer. These flags are used in addition
to the set of global flags."
}
 
cdl_option CYGPKG_UITRON_CFLAGS_REMOVE {
display "Suppressed compiler flags"
flavor data
no_define
default_value { "" }
description "
This option modifies the set of compiler flags for
building the uITRON compatibility layer. These flags are removed from
the set of global flags if present."
}
 
cdl_option CYGPKG_UITRON_TESTS {
display "uITRON tests"
flavor data
no_define
calculated {
"tests/testcxx tests/testcx2 tests/testcx3 tests/testcx4 tests/testcx5 tests/testcx6 tests/testcx7 tests/testcx8 tests/testcx9"
. ((!CYGIMP_UITRON_INLINE_FUNCS && !CYGIMP_UITRON_CPP_OUTLINE_FUNCS) ?
" tests/test1 tests/test2 tests/test3 tests/test4 tests/test5 tests/test6 tests/test7 tests/test8 tests/test9 tests/testintr" : "")
}
description "
This option specifies the set of tests for the uITRON compatibility layer."
}
}
}
/v2_0/cdl/mempoolvar.cdl
0,0 → 1,129
# ====================================================================
#
# mempoolvar.cdl
#
# uITRON variable memory pool related configuration data
#
# ====================================================================
#####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): jskov
# Original data: hmt
# Contributors:
# Date: 1999-07-07
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_option CYGNUM_UITRON_MEMPOOLVAR {
display "Number of variable-size memory pools"
flavor data
legal_values 1 to 65535
default_value 3
description "
The number of uITRON Variable-Size Memorypools present in the system.
Valid Variable-Size Memorypool IDs will range from 1 to this value."
}
cdl_component CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE {
display "Support create and delete"
flavor bool
default_value 1
active_if (0 < CYGNUM_UITRON_MEMPOOLVAR)
description "
Support variable-size memory pool create and delete operations
(cre_mpl, del_mpl). Otherwise all variable-size mempools are created,
up to the number specified above."
 
cdl_option CYGNUM_UITRON_MEMPOOLVAR_INITIALLY {
display "Number of variable-size mempools created initially"
flavor data
legal_values 0 to 65535
default_value 3
description "
The number of variable-size mempools initially created.
This number should not be more than the number
of variable mempools in the system, though setting
it to a large value to mean 'all' is acceptable.
Initially, only variable mempools numbered from
1 to this number exist;
higher numbered ones must be created before use.
All mempools must be initialized to tell
the system what memory to use for each pool."
}
}
cdl_option CYGDAT_UITRON_MEMPOOLVAR_EXTERNS {
display "Externs for initialization"
flavor data
default_value {"static char vpool1[ 2000 ], \\\n\
vpool2[ 2000 ], \\\n\
vpool3[ 2000 ];"}
description "
Variable mempool initializers may refer to external
objects such as memory for the pool to manage.
Use this option to define or declare any external
objects needed by the pool's static initializer below.
Example: create some memory for a mempool using
'static char vpool1\[2000\];'
to set up a chunk of memory of 2000 bytes.
Note: this option is invoked in the 'outermost' context
of C++ source, where global/static objects are created;
it should contain valid, self-contained, C++ source."
}
cdl_option CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS {
display "Static initializers"
flavor data
default_value {"CYG_UIT_MEMPOOLVAR( vpool1, 2000 ), \\\n\
CYG_UIT_MEMPOOLVAR( vpool2, 2000 ), \\\n\
CYG_UIT_MEMPOOLVAR( vpool3, 2000 ),"}
description "
Variable block memory pools should be statically
initialized: enter a list of initializers
separated by commas, one per line.
An initializer is
'CYG_UIT_MEMPOOLVAR(ADDR,SIZE)'
where addr is the address of memory to manage, and
size is the total size of that memory.
If create and delete operations are supported,
initializers of the form
'CYG_UIT_MEMPOOLVAR_NOEXS(ADDR,SIZE)' should be
used for pools which are not initially created, to tell
the system what memory to use for each pool.
Note: this option is invoked in the context of a
C++ array initializer, between curly brackets.
Ensure that the number of initializers here exactly
matches the total number of variable pools specified."
}
/v2_0/cdl/tasks.cdl
0,0 → 1,164
# ====================================================================
#
# tasks.cdl
#
# uITRON task related configuration data
#
# ====================================================================
#####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): jskov
# Original data: hmt
# Contributors:
# Date: 1999-07-07
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_option CYGNUM_UITRON_TASKS {
display "Number of tasks"
flavor data
legal_values 1 to 65535
default_value 4
description "
The number of uITRON tasks present in the system.
Valid task object IDs will range from 1 to this value."
}
cdl_option CYGNUM_UITRON_START_TASKS {
display "Start tasks"
flavor data
legal_values 0 to 65535
default_value 1
description "
The number of uITRON tasks to start automatically.
Tasks from 1 to this value will be started
at the beginning of application execution.
A value of zero here means to start them all.
Tasks started in this way have a start code of
zero, as if they were started by sta_tsk(i,0).
If create and delete operations are supported,
this number should be no greater than the number
of tasks created initially."
}
cdl_component CYGPKG_UITRON_TASKS_CREATE_DELETE {
display "Support create and delete"
flavor bool
default_value 1
description "
Support task create and delete operations (cre_tsk, del_tsk).
Otherwise all tasks are created, up to the number specified above."
 
cdl_option CYGNUM_UITRON_TASKS_INITIALLY {
display "Number of tasks created initially"
flavor data
legal_values 1 to 65535
default_value 4
description "
The number of uITRON tasks initially created.
This number should not be more than the number
of tasks in the system, though setting it to a large
value to mean 'all' is acceptable.
Initially, only tasks numbered 1 to this number exist;
higher numbered ones must be created before use."
}
}
cdl_option CYGNUM_UITRON_STACK_SIZE {
display "Default stack size"
flavor data
legal_values 128 to 0x7FFFFFFF
default_value 2048
description "
Define a default stack size for uITRON tasks,
for use in the initialization options below.
This will be overridden where it is used if the
architectural HAL requires a minimum stack size
to handle interrupts correctly."
}
cdl_option CYGDAT_UITRON_TASK_EXTERNS {
display "Externs for initialization"
flavor data
default_value {"extern \"C\" void task1( unsigned int ); \\\n\
extern \"C\" void task2( unsigned int ); \\\n\
extern \"C\" void task3( unsigned int ); \\\n\
extern \"C\" void task4( unsigned int ); \\\n\
static char stack1[ MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ], \\\n\
stack2[ MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ], \\\n\
stack3[ MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ], \\\n\
stack4[ MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ];"}
description "
Task initializers may refer to external objects
such as memory for stack or functions to call.
Use this option to define or declare any external
objects needed by the task static initializer below.
Example: create some memory for a stack using
'static char stack1\[CYGNUM_UITRON_STACK_SIZE\];'
to set up a chunk of memory of the default stack size.
Note: this option is invoked in the 'outermost' context
of C++ source, where global/static objects are created;
it should contain valid, self-contained, C++ source."
}
cdl_option CYGDAT_UITRON_TASK_INITIALIZERS {
display "Static initializers"
flavor data
default_value {"CYG_UIT_TASK( \"t1\", 1, task1, &stack1, MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ), \\\n\
CYG_UIT_TASK( \"t2\", 2, task2, &stack2, MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ), \\\n\
CYG_UIT_TASK( \"t3\", 3, task3, &stack3, MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ), \\\n\
CYG_UIT_TASK( \"t4\", 4, task4, &stack4, MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ),"}
description "
Tasks must be statically
initialized: enter a list of initializers
separated by commas, one per line.
An initializer is
'CYG_UIT_TASK(NAME,PRIO,FUNC,STACK,SIZE)'
where name is a quoted string to name the task,
prio is the initial priority of the task,
func is the name of the entry point,
stack is the address of the task's stack,
and size is the size of the task's stack.
When create and delete operations are supported,
'CYG_UIT_TASK_NOEXS(NAME,STACK,SIZE)' should be
used for tasks which are not initially created,
in order to tell the system what memory to use
for stacks when these tasks are created later on.
Using 'CYGNUM_UITRON_STACK_SIZE' for size
is recommended, to use the option defined above,
so long as that truly is the size of your stack(s).
Note: this option is invoked in the context of a
C++ array initializer, between curly brackets.
Ensure that the number of initializers here exactly
matches the number of tasks specified."
}
/v2_0/cdl/version.cdl
0,0 → 1,167
# ====================================================================
#
# verion.cdl
#
# uITRON version related configuration data
#
# ====================================================================
#####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): jskov
# Original data: hmt
# Contributors:
# Date: 1999-07-07
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_option CYGNUM_UITRON_VER_MAKER {
display "OS maker"
flavor data
legal_values 0 to 0xFFFF
default_value 0
description "
This value is returned in the 'maker'
field of the T_VER structure in
response to a get_ver() system call."
}
cdl_option CYGNUM_UITRON_VER_ID {
display "OS identification"
flavor data
legal_values 0 to 0xFFFF
default_value 0
description "
This value is returned in the 'id'
field of the T_VER structure in
response to a get_ver() system call."
}
cdl_option CYGNUM_UITRON_VER_SPVER {
display "ITRON specification"
flavor data
legal_values 0 to 0xFFFF
default_value 0x5302
description "
This value is returned in the 'spver'
field of the T_VER structure in
response to a get_ver() system call.
Do NOT change this value."
}
cdl_option CYGNUM_UITRON_VER_PRVER {
display "OS product version"
flavor data
legal_values 0 to 0xFFFF
default_value 0x0100
description "
This value is returned in the 'prver'
field of the T_VER structure in
response to a get_ver() system call."
}
# PRNO fields in own folder
cdl_component CYGPKG_UITRON_VERSION_PRNO {
display "Product info"
flavor none
description "
The get_ver() uITRON system call returns
several version related values describing
the vendor, product and CPU in question
as well as the version of the uITRON
standard supported.
These values may be specified here."
 
cdl_option CYGNUM_UITRON_VER_PRNO_0 {
display "Field 0"
flavor data
legal_values 0 to 0xFFFF
default_value 0
description "
This value is returned in the 'prno\[0\]'
field of the T_VER structure in
response to a get_ver() system call."
}
cdl_option CYGNUM_UITRON_VER_PRNO_1 {
display "Field 1"
flavor data
legal_values 0 to 0xFFFF
default_value 0
description "
This value is returned in the 'prno\[1\]'
field of the T_VER structure in
response to a get_ver() system call."
}
cdl_option CYGNUM_UITRON_VER_PRNO_2 {
display "Field 2"
flavor data
legal_values 0 to 0xFFFF
default_value 0
description "
This value is returned in the 'prno\[2\]'
field of the T_VER structure in
response to a get_ver() system call."
}
cdl_option CYGNUM_UITRON_VER_PRNO_3 {
display "Field 3"
flavor data
legal_values 0 to 0xFFFF
default_value 0
description "
This value is returned in the 'prno\[3\]'
field of the T_VER structure in
response to a get_ver() system call."
}
}
 
cdl_option CYGNUM_UITRON_VER_CPU {
display "CPU information"
flavor data
legal_values 0 to 0xFFFF
default_value 0
description "
This value is returned in the 'cpu'
field of the T_VER structure in
response to a get_ver() system call."
}
cdl_option CYGNUM_UITRON_VER_VAR {
display "System variant"
flavor data
legal_values 0 to 0xFFFF
default_value 0x8000
description "
This value is returned in the 'var'
field of the T_VER structure in
response to a get_ver() system call.
Do NOT change this value."
}
/v2_0/cdl/mempoolfixed.cdl
0,0 → 1,138
# ====================================================================
#
# mempoolfixed.cdl
#
# uITRON fixed memory pool related configuration data
#
# ====================================================================
#####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): jskov
# Original data: hmt
# Contributors:
# Date: 1999-07-07
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_option CYGNUM_UITRON_MEMPOOLFIXED {
display "Number of fixed-size memorypools"
flavor data
legal_values 1 to 65535
default_value 3
description "
The number of uITRON Fixed-Size
Memorypools present in the system.
Valid Fixed-Size Memorypool IDs will range
from 1 to this value."
}
cdl_component CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE {
display "Support create and delete"
flavor bool
default_value 1
active_if (0 < CYGNUM_UITRON_MEMPOOLFIXED)
description "
Support fixed-size memory pool
create and delete operations
(cre_mpf, del_mpf).
Otherwise all fixed mempools are created,
up to the number specified above."
 
cdl_option CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY {
display "Number of fixed mempools created initially"
flavor data
legal_values 0 to 65535
default_value 3
description "
The number of fixed mempools initially created.
This number should not be more than the number
of fixed mempools in the system, though setting
it to a large value to mean 'all' is acceptable.
Initially, only fixed mempools numbered from
1 to this number exist;
higher numbered ones must be created before use.
Whilst all mempools must be initialized to tell
the system what memory to use for each pool,
it is only useful to initialize the blocksize of
fixed mempools up to this number;
the blocksize for higher numbered ones
will be defined when they are created."
}
}
cdl_option CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS {
display "Externs for initialization"
flavor data
default_value {"static char fpool1[ 2000 ], \\\n\
fpool2[ 2000 ], \\\n\
fpool3[ 2000 ];"}
description "
Fixed mempool initializers may refer to external
objects such as memory for the pool to manage.
Use this option to define or declare any external
objects needed by the pool's static initializer below.
Example: create some memory for a mempool using
'static char fpool1\[2000\];'
to set up a chunk of memory of 2000 bytes.
Note: this option is invoked in the 'outermost' context
of C++ source, where global/static objects are created;
it should contain valid, self-contained, C++ source."
}
cdl_option CYGDAT_UITRON_MEMPOOLFIXED_INITIALIZERS {
display "Static initializers"
flavor data
default_value {"CYG_UIT_MEMPOOLFIXED( fpool1, 2000, 20 ), \\\n\
CYG_UIT_MEMPOOLFIXED( fpool2, 2000, 100 ), \\\n\
CYG_UIT_MEMPOOLFIXED( fpool3, 2000, 500 ),"}
description "
Fixed block memory pools should be statically
initialized: enter a list of initializers
separated by commas, one per line.
An initializer is
'CYG_UIT_MEMPOOLFIXED(ADDR,SIZE,BLOCK)'
where addr is the address of memory to manage,
size is the total size of that memory, and
block is the block size for allocation by the pool.
If create and delete operations are supported,
initializers of the form
'CYG_UIT_MEMPOOLFIXED_NOEXS(ADDR,SIZE)' should be
used for pools which are not initially created, to tell
the system what memory to use for each pool.
Note: this option is invoked in the context of a
C++ array initializer, between curly brackets.
Ensure that the number of initializers here exactly
matches the total number of fixed pools specified."
}
/v2_0/cdl/semas.cdl
0,0 → 1,115
# ====================================================================
#
# semas.cdl
#
# uITRON semaphore related configuration data
#
# ====================================================================
#####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): jskov
# Original data: hmt
# Contributors:
# Date: 1999-07-07
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_option CYGNUM_UITRON_SEMAS {
display "Number of semaphores"
flavor data
legal_values 1 to 65535
default_value 3
description "
The number of uITRON semaphores present in the system.
Valid semaphore object IDs will range from 1 to this value."
}
cdl_component CYGPKG_UITRON_SEMAS_CREATE_DELETE {
display "Support create and delete"
flavor bool
default_value 1
description "
Support semaphore create and delete operations (cre_sem, del_sem).
Otherwise all semaphores are created, up to the number specified
above."
 
cdl_option CYGNUM_UITRON_SEMAS_INITIALLY {
display "Number of semaphores created initially"
flavor data
legal_values 0 to 65535
default_value 3
description "
The number of uITRON semaphores initially created.
This number should not be more than the number
of semaphores in the system, though setting it to a large
value to mean 'all' is acceptable.
Initially, only semaphores numbered 1 to this number exist;
higher numbered ones must be created before use.
It is only useful to initialize semaphores up to this number;
higher numbered ones must be created in order to use them,
and so they will be re-initialized."
}
}
cdl_component CYGPKG_UITRON_SEMAS_ARE_INITIALIZED {
display "Initialize semaphore counts"
flavor bool
default_value 0
description "
Initialize semaphores to specific count values.
Otherwise semaphores are initialized with the count
set to zero."
 
cdl_option CYGDAT_UITRON_SEMA_INITIALIZERS {
display "Static initializers"
parent CYGPKG_UITRON_SEMAS_ARE_INITIALIZED
flavor data
default_value {"CYG_UIT_SEMA( 0 ),\
CYG_UIT_SEMA( 0 ),\
CYG_UIT_SEMA( 0 )"}
description "
A list of initializers separated by commas,
one per line.
An initializer is 'CYG_UIT_SEMA(INITIAL-COUNT)'
or 'CYG_UIT_SEMA_NOEXS' for slots above the number
initially to be created, when create and delete
operations are supported.
Note: this option is invoked in the context of a
C++ array initializer, between curly brackets.
Ensure that the number of initializers here exactly
matches the total number of semaphores specified."
}
}
/v2_0/cdl/flags.cdl
0,0 → 1,82
# ====================================================================
#
# flags.cdl
#
# uITRON flags related configuration data
#
# ====================================================================
#####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): jskov
# Original data: hmt
# Contributors:
# Date: 1999-07-07
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_option CYGNUM_UITRON_FLAGS {
display "Number of eventflags"
flavor data
legal_values 1 to 65535
default_value 5
description "
The number of uITRON eventflag objects present in the system.
Valid eventflag object IDs will range from 1 to this value."
}
cdl_component CYGPKG_UITRON_FLAGS_CREATE_DELETE {
display "Support create and delete"
flavor bool
default_value 1
description "
Support eventflag create and delete operations (cre_flg, del_flg).
Otherwise all eventflags are created, up to the number specified above."
 
cdl_option CYGNUM_UITRON_FLAGS_INITIALLY {
display "Number of eventflags created initially"
flavor data
legal_values 0 to 65535
default_value 5
description "
The number of uITRON eventflags initially created.
This number should not be more than the number
of eventflags in the system, though setting it to a large
value to mean 'all' is acceptable.
Initially, only eventflags numbered 1 to this number exist;
higher numbered ones must be created before use."
}
}
/v2_0/cdl/mboxes.cdl
0,0 → 1,82
# ====================================================================
#
# mboxes.cdl
#
# uITRON mbox related configuration data
#
# ====================================================================
#####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): jskov
# Original data: hmt
# Contributors:
# Date: 1999-07-07
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_option CYGNUM_UITRON_MBOXES {
display "Number of mailboxes"
flavor data
legal_values 1 to 65535
default_value 4
description "
The number of uITRON mailboxes present in the system.
Valid mailbox object IDs will range from 1 to this value."
}
cdl_component CYGPKG_UITRON_MBOXES_CREATE_DELETE {
display "Support create and delete"
flavor bool
default_value 1
description "
Support mailbox create and delete operations (cre_mbx, del_mbx).
Otherwise all mailboxes are created, up to the number specified above."
 
cdl_option CYGNUM_UITRON_MBOXES_INITIALLY {
display "Number of mailboxes created initially"
flavor data
legal_values 0 to 65535
default_value 4
description "
The number of uITRON mailboxes initially created.
This number should not be more than the number
of mailboxes in the system, though setting it to a large
value to mean 'all' is acceptable.
Initially, only mailboxes numbered 1 to this number exist;
higher numbered ones must be created before use."
}
}
/v2_0/tests/test1.c
0,0 → 1,815
//===========================================================================
//
// test1.c
//
// uITRON "C" test program one
//
//===========================================================================
//####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-03-13
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
volatile int intercom = 0;
volatile int intercount = 0;
INT scratch = 0;
 
#ifndef CYGSEM_KERNEL_SCHED_TIMESLICE
#define TIMESLICEMSG "Assuming no kernel timeslicing"
#define TSGO() (1)
#define TSRELEASE() CYG_EMPTY_STATEMENT
#define TSSTOP() CYG_EMPTY_STATEMENT
#define TSLOCK() CYG_EMPTY_STATEMENT
#define TSUNLOCK() CYG_EMPTY_STATEMENT
#define ICWAIT( _i_ ) CYG_EMPTY_STATEMENT
 
#else
// Now follow some nasty bodges to control the scheduling when basically it
// isn't controlled ie. timeslicing is on. It's bodgy because we're
// testing normal synchronization methods, so we shouldn't rely on them for
// comms between threads here. Instead there's a mixture of communicating
// via a flag (ts_interlock) which stops the "controlled" thread running
// away, and waiting for the controlled thread to run enough for us.
//
// Tasks 3 and 4 are waited for by the control task: task 3 locks the
// scheduler so is immediately descheduled when it unlocks it, task 4 does
// waiting-type operations, so we must give it chance to run by yielding a
// few times ourselves. Note the plain constant in ICWAIT() below.
 
#define TIMESLICEMSG "Assuming kernel timeslicing ENABLED"
volatile int ts_interlock = 0;
#define TSGO() (ts_interlock)
#define TSRELEASE() ts_interlock = 1
#define TSSTOP() ts_interlock = 0
 
#define TSLOCK() CYG_MACRO_START \
ER ercd2 = dis_dsp(); \
CYG_TEST_CHECK( E_OK == ercd2, "dis_dsp (TSLOCK) bad ercd2" ); \
CYG_MACRO_END
 
#define TSUNLOCK() CYG_MACRO_START \
ER ercd3 = ena_dsp(); \
CYG_TEST_CHECK( E_OK == ercd3, "ena_dsp (TSUNLOCK) bad ercd3" ); \
CYG_MACRO_END
 
#define ICWAIT( _i_ ) CYG_MACRO_START \
int loops; \
for ( loops = 3; (0 < loops) || ((_i_) > intercount); loops-- ) { \
ER ercd4 = rot_rdq( 0 ); /* yield */ \
CYG_TEST_CHECK( E_OK == ercd4, "rot_rdq (ICWAIT) bad ercd4" ); \
} \
CYG_MACRO_END
#endif // CYGSEM_KERNEL_SCHED_TIMESLICE
 
/*
#define IC() \
CYG_MACRO_START \
static char *msgs[] = { "ZERO", "ONE", "TWO", "THREE", "FOUR", "LOTS" }; \
CYG_TEST_INFO( msgs[ intercount > 5 ? 5 : intercount ] ); \
CYG_MACRO_END
*/
 
// #define CYG_TEST_UITRON_TEST1_LOOPING 1
 
void task1( unsigned int arg )
{
ER ercd;
T_RTSK ref_tskd;
 
#ifdef CYG_TEST_UITRON_TEST1_LOOPING
while ( 1 ) {
#endif // CYG_TEST_UITRON_TEST1_LOOPING
 
CYG_TEST_INFO( "Task 1 running" );
CYG_TEST_INFO( TIMESLICEMSG );
 
intercom = 0;
intercount = 0;
 
CYG_TEST_INFO( "Testing get_tid and ref_tsk" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = get_tid( NULL );
CYG_TEST_CHECK( E_PAR == ercd, "get_tid bad ercd !E_PAR" );
#endif
ercd = get_tid( NADR );
CYG_TEST_CHECK( E_PAR == ercd, "get_tid bad ercd !E_PAR" );
ercd = ref_tsk( &ref_tskd, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_tsk bad ercd !E_ID" );
ercd = ref_tsk( &ref_tskd, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_tsk bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_tsk( NULL, 1 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_tsk bad ercd !E_PAR" );
#endif
ercd = ref_tsk( NADR, 1 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_tsk bad ercd !E_PAR" );
#endif // we can test bad param error returns
ercd = ref_tsk( &ref_tskd, 1 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_RUN == ref_tskd.tskstat, "Bad task status 1" );
ercd = ref_tsk( &ref_tskd, 0 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_RUN == ref_tskd.tskstat, "Bad task status 0" );
ercd = ref_tsk( &ref_tskd, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_DMT == ref_tskd.tskstat, "Bad task status 2" );
CYG_TEST_CHECK( 2 == ref_tskd.tskpri, "Bad task prio 2" );
 
ercd = rsm_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk DMT bad ercd !E_OBJ" );
ercd = frsm_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk DMT bad ercd !E_OBJ" );
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai DMT bad ercd !E_OBJ" );
ercd = sus_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "sus_tsk DMT bad ercd !E_OBJ" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk DMT bad ercd !E_OBJ" );
ercd = can_wup( &scratch, 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "can_wup DMT bad ercd !E_OBJ" );
 
CYG_TEST_PASS( "get_tid, ref_tsk" );
 
CYG_TEST_INFO( "Testing prio change and start task" );
ercd = sta_tsk( 2, 99 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
 
// drop pri of task 2
ercd = chg_pri( 2, 4 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ref_tsk( &ref_tskd, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_RDY == ref_tskd.tskstat, "Bad task status 2" );
CYG_TEST_CHECK( 4 == ref_tskd.tskpri, "Bad task prio 2" );
 
// drop our pri below task 2
ercd = chg_pri( 0, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
 
ercd = ref_tsk( &ref_tskd, 1 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( 5 == ref_tskd.tskpri, "Bad task prio 1" );
ercd = ref_tsk( &ref_tskd, 0 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( 5 == ref_tskd.tskpri, "Bad task prio 0" );
ercd = ref_tsk( &ref_tskd, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
// it will have run to completion and regained its original prio
CYG_TEST_CHECK( 2 == ref_tskd.tskpri, "Bad task prio 2" );
CYG_TEST_CHECK( TTS_DMT == ref_tskd.tskstat, "Bad task status 2" );
 
// retest these now that the task has executed once
ercd = rsm_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk DMT bad ercd !E_OBJ" );
ercd = frsm_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk DMT bad ercd !E_OBJ" );
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai DMT bad ercd !E_OBJ" );
ercd = sus_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "sus_tsk DMT bad ercd !E_OBJ" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk DMT bad ercd !E_OBJ" );
ercd = can_wup( &scratch, 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "can_wup DMT bad ercd !E_OBJ" );
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = chg_pri( -6, 9 );
CYG_TEST_CHECK( E_ID == ercd, "chg_pri bad ercd !E_ID" );
ercd = chg_pri( 99, 9 );
CYG_TEST_CHECK( E_ID == ercd, "chg_pri bad ercd !E_ID" );
ercd = sta_tsk( -6, 99 );
CYG_TEST_CHECK( E_ID == ercd, "sta_tsk bad ercd !E_ID" );
ercd = sta_tsk( 99, 99 );
CYG_TEST_CHECK( E_ID == ercd, "sta_tsk bad ercd !E_ID" );
#endif // we can test bad param error returns
 
CYG_TEST_PASS( "sta_tsk, chg_pri" );
 
CYG_TEST_INFO( "Testing delay and dispatch disabling" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
CYG_TEST_PASS( "dly_tsk, ena_dsp, dis_dsp" );
CYG_TEST_INFO( "Testing ready queue manipulation" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ercd = rot_rdq( 4 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ercd = rot_rdq( 5 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rot_rdq( -6 );
CYG_TEST_CHECK( E_PAR == ercd, "rot_rdq bad ercd !E_PAR" );
ercd = rot_rdq( 99 );
CYG_TEST_CHECK( E_PAR == ercd, "rot_rdq bad ercd !E_PAR" );
#endif // we can test bad param error returns
CYG_TEST_PASS( "rot_rdq" );
 
CYG_TEST_INFO( "Testing suspend/resume" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = sus_tsk( -6 );
CYG_TEST_CHECK( E_ID == ercd, "sus_tsk bad ercd !E_ID" );
ercd = sus_tsk( 99 );
CYG_TEST_CHECK( E_ID == ercd, "sus_tsk bad ercd !E_ID" );
ercd = rsm_tsk( -6 );
CYG_TEST_CHECK( E_ID == ercd, "rsm_tsk bad ercd !E_ID" );
ercd = rsm_tsk( 99 );
CYG_TEST_CHECK( E_ID == ercd, "rsm_tsk bad ercd !E_ID" );
ercd = frsm_tsk( -6 );
CYG_TEST_CHECK( E_ID == ercd, "frsm_tsk bad ercd !E_ID" );
ercd = frsm_tsk( 99 );
CYG_TEST_CHECK( E_ID == ercd, "frsm_tsk bad ercd !E_ID" );
#endif // we can test bad param error returns
// drop task 3 pri to same as us
CYG_TEST_CHECK( 0 == intercount, "intercount != 0" );
 
intercom = 3; // tell T3 to loop
TSRELEASE();
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 3, 66 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 3, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
 
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 1 );
CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
ercd = sus_tsk( 3 );
TSRELEASE();
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
intercom = 0; // bad data to T3
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
intercom = 3; // tell T3 to loop
TSRELEASE();
ercd = rsm_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 2 );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
 
CYG_TEST_INFO( "Command task 3 inner loop stop" );
intercom = 2 + 4;
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
ercd = sus_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
intercom = 0; // bad data to T3
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ercd = sus_tsk( 3 ); // suspend AGAIN
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
ercd = sus_tsk( 3 ); // AND AGAIN
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
ercd = rsm_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
ercd = rsm_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
intercom = 3; // tell T3 to loop
TSRELEASE();
ercd = rsm_tsk( 3 ); // expect restart this time
CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 3 );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
 
CYG_TEST_INFO( "Command task 3 inner loop stop 2" );
intercom = 2 + 4;
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
ercd = sus_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
intercom = 0; // bad data to T3
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
ercd = sus_tsk( 3 ); // suspend AGAIN
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
ercd = sus_tsk( 3 ); // AND AGAIN
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
intercom = 3; // tell T3 to loop
TSRELEASE();
ercd = frsm_tsk( 3 ); // expect restart this time
CYG_TEST_CHECK( E_OK == ercd, "frsm_tsk bad ercd" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 4 );
CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
 
TSRELEASE();
ercd = rsm_tsk( 3 ); // try it again
CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk bad ercd !E_OBJ" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 5 );
CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
 
TSRELEASE();
ercd = frsm_tsk( 3 ); // try it again
CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk bad ercd !E_OBJ" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 6 );
CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
 
CYG_TEST_INFO( "Command task 3 all loops stop" );
intercom = 4 + 8;
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
intercom = intercount = 0;
 
CYG_TEST_PASS( "sus_tsk, rsm_tsk, frsm_tsk" );
 
CYG_TEST_INFO( "Testing sleep/wakeup stuff" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = wup_tsk( -6 );
CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
ercd = wup_tsk( 99 );
CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
ercd = can_wup( &scratch, -6 );
CYG_TEST_CHECK( E_ID == ercd, "can_wup bad ercd !E_ID" );
ercd = can_wup( &scratch, 99 );
CYG_TEST_CHECK( E_ID == ercd, "can_wup bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = can_wup( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "can_wup bad ercd !E_PAR" );
#endif
ercd = can_wup( NADR, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "can_wup bad ercd !E_PAR" );
ercd = wup_tsk( 0 ); // not ourself
CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
ercd = wup_tsk( 1 ); // ourself
CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk bad ercd !E_OBJ" );
#endif // we can test bad param error returns
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = tslp_tsk( -6 );
CYG_TEST_CHECK( E_PAR == ercd, "tslp_tsk bad ercd !E_PAR" );
#endif // we can test bad param error returns
ercd = tslp_tsk( TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
ercd = tslp_tsk( 5 );
CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = tslp_tsk( TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
ercd = tslp_tsk( TMO_POL );
CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
ercd = tslp_tsk( 5 );
CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = tslp_tsk( -6 );
CYG_TEST_CHECK( E_PAR == ercd, "tslp_tsk bad ercd !E_PAR" );
#endif // we can test bad param error returns
ercd = tslp_tsk( TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
ercd = tslp_tsk( 5 );
CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
 
// drop task 4 pri to same as us
intercount = 0;
intercom = 1; // test plain slp_tsk
TSRELEASE();
ercd = chg_pri( 4, 5 );
CYG_TEST_CHECK( E_OBJ == ercd, "chg_pri bad ercd" );
 
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 4, 77 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 4, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
 
ercd = wup_tsk( 4 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 1 );
CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
intercom = 2; // test tslp_tsk
TSRELEASE();
ercd = wup_tsk( 4 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 2 );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
intercom = 3; // test tslp_tsk
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
intercom = 1; // test slp_tsk next...
ercd = dly_tsk( 20 ); // without a wup
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ICWAIT( 3 );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
 
intercom = 1; // ...test slp_tsk
TSRELEASE();
ercd = dly_tsk( 20 ); // without a wup (yet)
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
TSRELEASE();
ercd = tslp_tsk( 20 ); // yield again
CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
TSRELEASE();
ercd = rot_rdq( 0 ); // and again
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
TSRELEASE();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rot_rdq( 0 ); // and yield
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 4 );
CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
 
intercom = 1; // test slp_tsk
TSRELEASE();
ercd = dly_tsk( 20 ); // without a wup (yet)
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
 
// this wup will restart it when we yield:
TSLOCK();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
// these will count up:
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
scratch = -1;
ercd = can_wup( &scratch, 4 );
CYG_TEST_CHECK( E_OK == ercd, "can_wup bad ercd" );
CYG_TEST_CHECK( 2 == scratch, "Cancelled wups not 2" );
CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
TSUNLOCK();
 
intercom = 4; // do nothing
TSRELEASE();
ercd = rot_rdq( 0 ); // and yield
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 5 );
CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
TSRELEASE();
ercd = dly_tsk( 20 ); // let it do nothing
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
TSRELEASE();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
TSRELEASE();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
TSRELEASE();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
TSRELEASE();
ercd = dly_tsk( 20 ); // lots of wups but no sleep
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
scratch = -1;
ercd = can_wup( &scratch, 4 );
CYG_TEST_CHECK( E_OK == ercd, "can_wup bad ercd" );
CYG_TEST_CHECK( 3 == scratch, "Cancelled wups not 3" );
// now check that they are cancelled by doing a wait again
intercom = 1; // test slp_tsk
TSRELEASE();
ercd = rot_rdq( 0 ); // still without a wup
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 ); // still without a wup
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
intercom = 4; // do nothing next
TSRELEASE();
ICWAIT( 6 );
CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
ercd = rot_rdq( 0 ); // still without a wup
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
TSRELEASE();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rot_rdq( 0 ); // it will run now
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 ); // it will run now
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 7 );
CYG_TEST_CHECK( 7 == intercount, "intercount != 7" );
 
TSRELEASE();
intercom = 99; // exit, all done
ercd = rot_rdq( 0 ); // let it run
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 8 );
CYG_TEST_CHECK( 8 == intercount, "intercount != 8" );
 
TSRELEASE();
ercd = rot_rdq( 0 ); // let it run
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 8 == intercount, "intercount != 8" );
CYG_TEST_PASS( "wup_tsk, can_wup, slp_tsk, tslp_tsk" );
 
#ifdef CYG_TEST_UITRON_TEST1_LOOPING
chg_pri( 1, 1 );
rot_rdq( 0 );
ter_tsk( 2 );
rot_rdq( 0 );
ter_tsk( 3 );
rot_rdq( 0 );
ter_tsk( 4 );
rot_rdq( 0 );
}
#endif // CYG_TEST_UITRON_TEST1_LOOPING
 
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
CYG_TEST_PASS( "Task 2 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
if ( 99 != arg )
CYG_TEST_FAIL( "Task 2 arg not 99" );
ext_tsk();
CYG_TEST_FAIL( "Task 2 failed to exit" );
}
 
void task3( unsigned int arg )
{
ER ercd;
TSLOCK();
CYG_TEST_PASS("Task3 running");
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 3 == scratch, "tid not 3" );
if ( 66 != arg )
CYG_TEST_FAIL( "Task 3 arg not 66" );
 
while ( 2 & intercom ) {
while ( 1 & intercom ) {
intercount++;
TSSTOP();
do {
TSUNLOCK();
ercd = rot_rdq( 0 ); // yield()
TSLOCK();
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq 1 (task3) bad ercd" );
} while ( !TSGO() );
}
CYG_TEST_CHECK( 4 & intercom, "should not have got here yet 1" );
TSSTOP();
do {
TSUNLOCK();
ercd = rot_rdq( 0 ); // yield()
TSLOCK();
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq 2 (task3) bad ercd" );
} while ( !TSGO() );
}
CYG_TEST_CHECK( 8 & intercom, "should not have got here yet 2" );
TSUNLOCK();
ext_tsk();
CYG_TEST_FAIL( "Task 3 failed to exit" );
}
 
void task4( unsigned int arg )
{
ER ercd;
CYG_TEST_PASS("Task4 running");
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 4 == scratch, "tid not 4" );
if ( 77 != arg )
CYG_TEST_FAIL( "Task 4 arg not 77" );
while ( 1 ) {
switch ( intercom ) {
case 1:
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk (task4) bad ercd" );
break;
case 2:
ercd = tslp_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk (task4) bad ercd" );
break;
case 3:
ercd = tslp_tsk( 10 );
CYG_TEST_CHECK( E_TMOUT == ercd,
"slp_tsk (task4) bad ercd !E_TMOUT" );
break;
case 4:
// busily do nothing
while ( 4 == intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd,
"rot_rdq (task4 idle) bad ercd" );
}
break;
case 99:
goto out;
default:
CYG_TEST_FAIL( "Task 4 bad intercom" );
goto out;
}
intercount++;
TSSTOP();
do {
ercd = rot_rdq( 0 ); // yield()
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq (task4) bad ercd" );
} while ( !TSGO() );
}
out:
ext_tsk();
CYG_TEST_FAIL( "Task 4 failed to exit" );
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF test1.c
/v2_0/tests/test2.c
0,0 → 1,970
//===========================================================================
//
// test2.c
//
// uITRON "C" test program two
//
//===========================================================================
//####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-03-13
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* test configuration for enough flag objects */ \
defined( CYGPKG_UITRON_FLAGS ) && \
(CYGNUM_UITRON_FLAGS >= 3) && \
(CYGNUM_UITRON_FLAGS < 90) && \
( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) || \
CYGNUM_UITRON_FLAGS_INITIALLY >= 3 ) && \
\
/* test configuration for enough message boxes */ \
defined( CYGPKG_UITRON_MBOXES ) && \
(CYGNUM_UITRON_MBOXES >= 3) && \
(CYGNUM_UITRON_MBOXES < 90) && \
( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) || \
CYGNUM_UITRON_MBOXES_INITIALLY >= 3 ) && \
\
/* test configuration for enough fixed memory pools */ \
defined( CYGPKG_UITRON_MEMPOOLFIXED ) && \
(CYGNUM_UITRON_MEMPOOLFIXED >= 3) && \
(CYGNUM_UITRON_MEMPOOLFIXED < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3 ) && \
\
/* test configuration for enough variable mempools */ \
defined( CYGPKG_UITRON_MEMPOOLVAR ) && \
(CYGNUM_UITRON_MEMPOOLVAR >= 3) && \
(CYGNUM_UITRON_MEMPOOLVAR < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
int intercom = 0;
int intercount = 0;
INT scratch = 0;
 
void task1( unsigned int arg )
{
ER ercd;
 
T_RSEM sem_info;
T_RFLG flg_info;
T_RMBX mbx_info;
T_RMPF mpf_info;
T_RMPL mpl_info;
UINT flagptn;
static char foo[] = "Test message";
T_MSG *msgptr = foo;
T_MSG *rxptr = NULL;
VP blfptr = (VP)foo;
VP blkptr = (VP)foo;
 
int delay = 10;
if (cyg_test_is_simulator)
delay = 3;
 
CYG_TEST_INFO( "Task 1 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
// start a lower prio task to interact with
intercom = 1;
ercd = sta_tsk( 2, 222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
// Semaphores; all the illegal argument combinations first
CYG_TEST_INFO( "Testing semaphore ops" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = sig_sem( -6 );
CYG_TEST_CHECK( E_ID == ercd, "sig_sem bad ercd !E_ID" );
ercd = sig_sem( 99 );
CYG_TEST_CHECK( E_ID == ercd, "sig_sem bad ercd !E_ID" );
ercd = wai_sem( -6 );
CYG_TEST_CHECK( E_ID == ercd, "wai_sem bad ercd !E_ID" );
ercd = wai_sem( 99 );
CYG_TEST_CHECK( E_ID == ercd, "wai_sem bad ercd !E_ID" );
ercd = preq_sem( -6 );
CYG_TEST_CHECK( E_ID == ercd, "preq_sem bad ercd !E_ID" );
ercd = preq_sem( 99 );
CYG_TEST_CHECK( E_ID == ercd, "preq_sem bad ercd !E_ID" );
ercd = twai_sem( -6, delay );
CYG_TEST_CHECK( E_ID == ercd, "twai_sem bad ercd !E_ID" );
ercd = twai_sem( 99, delay );
CYG_TEST_CHECK( E_ID == ercd, "twai_sem bad ercd !E_ID" );
ercd = twai_sem( 2, -999 );
CYG_TEST_CHECK( E_PAR == ercd, "twai_sem bad ercd !E_PAR" );
ercd = ref_sem( &sem_info, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_sem bad ercd !E_ID" );
ercd = ref_sem( &sem_info, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_sem bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_sem( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_sem bad ercd !E_PAR" );
#endif
ercd = ref_sem( NADR, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_sem bad ercd !E_PAR" );
CYG_TEST_PASS( "bad calls: sig_sem, [t]wai_sem, preq_sem, ref_sem" );
#endif // we can test bad param error returns
 
// check the waitable functions versus dispatch disable
ercd = preq_sem( 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
ercd = twai_sem( 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
ercd = twai_sem( 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = wai_sem( 2 );
CYG_TEST_CHECK( E_CTX == ercd, "wai_sem bad ercd !E_CTX" );
ercd = twai_sem( 2, delay );
CYG_TEST_CHECK( E_CTX == ercd, "twai_sem bad ercd !E_CTX" );
ercd = twai_sem( 2, TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "twai_sem(FEVR) bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = twai_sem( 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
ercd = preq_sem( 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = preq_sem( 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
ercd = twai_sem( 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
ercd = twai_sem( 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
CYG_TEST_PASS( "bad calls: wai_sem, twai_sem with dis_dsp" );
 
// check ref_sem with various states
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
ercd = preq_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 2 == sem_info.semcnt, "semcnt should be 2" );
ercd = wai_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
ercd = twai_sem( 2, delay );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
intercom = 0;
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
intercom = 1;
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 != sem_info.wtsk, "sem.wtsk should be non0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be non0" );
#if 1
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
#else // old, non-uITRON semantics
CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
#endif
ercd = dly_tsk( delay ); // let task 2 pick up the signal
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
CYG_TEST_PASS( "good calls: sig_sem, [t]wai,preq_sem with ref_sem" );
 
// Flags; all the illegal argument combinations first
CYG_TEST_INFO( "Testing flag ops" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = set_flg( -6, 1 );
CYG_TEST_CHECK( E_ID == ercd, "set_flg bad ercd !E_ID" );
ercd = set_flg( 99, 1 );
CYG_TEST_CHECK( E_ID == ercd, "set_flg bad ercd !E_ID" );
ercd = clr_flg( -6, 1 );
CYG_TEST_CHECK( E_ID == ercd, "clr_flg bad ercd !E_ID" );
ercd = clr_flg( 99, 1 );
CYG_TEST_CHECK( E_ID == ercd, "sig_flg bad ercd !E_ID" );
ercd = wai_flg( &flagptn, -6, 7, TWF_ANDW );
CYG_TEST_CHECK( E_ID == ercd, "wai_flg bad ercd !E_ID" );
ercd = wai_flg( &flagptn, 99, 7, TWF_ANDW );
CYG_TEST_CHECK( E_ID == ercd, "wai_flg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = wai_flg( NULL, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
#endif
ercd = wai_flg( NADR, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
ercd = wai_flg( &flagptn, 2, 7, 34657 );
CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
ercd = wai_flg( &flagptn, 2, 0, TWF_ANDW );
CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
ercd = pol_flg( &flagptn, -6, 7, TWF_ANDW );
CYG_TEST_CHECK( E_ID == ercd, "pol_flg bad ercd !E_ID" );
ercd = pol_flg( &flagptn, 99, 7, TWF_ANDW );
CYG_TEST_CHECK( E_ID == ercd, "pol_flg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = pol_flg( NULL, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
#endif
ercd = pol_flg( NADR, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
ercd = pol_flg( &flagptn, 2, 7, 34657 );
CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
ercd = pol_flg( &flagptn, 2, 0, TWF_ANDW );
CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
ercd = twai_flg( &flagptn, -6, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_ID == ercd, "twai_flg bad ercd !E_ID" );
ercd = twai_flg( &flagptn, 99, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_ID == ercd, "twai_flg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = twai_flg( NULL, 2, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
#endif
ercd = twai_flg( NADR, 2, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
ercd = twai_flg( &flagptn, 2, 7, 34657, delay );
CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, -999 );
CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
ercd = twai_flg( &flagptn, 2, 0, TWF_ANDW, delay );
CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
ercd = ref_flg( &flg_info, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_flg bad ercd !E_ID" );
ercd = ref_flg( &flg_info, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_flg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_flg( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_flg bad ercd !E_PAR" );
#endif
ercd = ref_flg( NADR, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_flg bad ercd !E_PAR" );
CYG_TEST_PASS( "bad calls: set_flg, clr_flg, [t]wai,pol_flg, ref_flg" );
#endif // we can test bad param error returns
 
// check the waitable functions versus dispatch disable
ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = wai_flg( &flagptn, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_CTX == ercd, "wai_flg bad ercd !E_CTX" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_CTX == ercd, "twai_flg bad ercd !E_CTX" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "twai_flg(FEVR) bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
CYG_TEST_PASS( "bad calls: wai_flg, twai_flg with dis_dsp" );
 
// check ref_flg with various states
ercd = ref_flg( &flg_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 == flg_info.wtsk, "flg.wtsk should be non0" );
CYG_TEST_CHECK( 0 == flg_info.flgptn, "flgptn should be 0" );
intercom = 0;
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
intercom = 1;
ercd = ref_flg( &flg_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
CYG_TEST_CHECK( 0 == flg_info.flgptn, "flgptn should be 0" );
ercd = set_flg( 2, 0x5555 );
CYG_TEST_CHECK( E_OK == ercd, "sig_flg bad ercd" );
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_flg( &flg_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
CYG_TEST_CHECK( 0x5555 == flg_info.flgptn, "flgptn should be 0x5555" );
ercd = clr_flg( 2, 0xF0F0 );
CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd" );
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_flg( &flg_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
CYG_TEST_CHECK( 0x5050 == flg_info.flgptn, "flgptn should be 0x5050" );
ercd = set_flg( 2, 0xFFFF );
CYG_TEST_CHECK( E_OK == ercd, "sig_flg bad ercd" );
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_flg( &flg_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 == flg_info.wtsk, "flg.wtsk should be 0" );
CYG_TEST_CHECK( 0xFFFF == flg_info.flgptn, "flgptn should be 0xFFFF" );
CYG_TEST_PASS( "good calls: clr_flg, set_flg, wai_flg with ref_flg" );
 
// Mailboxes; all the illegal argument combinations first
CYG_TEST_INFO( "Testing mailbox ops" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = snd_msg( -6, msgptr );
CYG_TEST_CHECK( E_ID == ercd, "snd_msg bad ercd !E_ID" );
ercd = snd_msg( 99, msgptr );
CYG_TEST_CHECK( E_ID == ercd, "snd_msg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = snd_msg( 2, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "snd_msg bad ercd !E_PAR" );
#endif
ercd = snd_msg( 2, NADR );
CYG_TEST_CHECK( E_PAR == ercd, "snd_msg bad ercd !E_PAR" );
ercd = rcv_msg( &rxptr, -6 );
CYG_TEST_CHECK( E_ID == ercd, "rcv_msg bad ercd !E_ID" );
ercd = rcv_msg( &rxptr, 99 );
CYG_TEST_CHECK( E_ID == ercd, "rcv_msg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = rcv_msg( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "rcv_msg bad ercd !E_PAR" );
#endif
ercd = rcv_msg( NADR, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "rcv_msg bad ercd !E_PAR" );
ercd = prcv_msg( &rxptr, -6 );
CYG_TEST_CHECK( E_ID == ercd, "prcv_msg bad ercd !E_ID" );
ercd = prcv_msg( &rxptr, 99 );
CYG_TEST_CHECK( E_ID == ercd, "prcv_msg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = prcv_msg( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "prcv_msg bad ercd !E_PAR" );
#endif
ercd = prcv_msg( NADR, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "prcv_msg bad ercd !E_PAR" );
ercd = trcv_msg( &rxptr, -6, delay );
CYG_TEST_CHECK( E_ID == ercd, "trcv_msg bad ercd !E_ID" );
ercd = trcv_msg( &rxptr, 99, delay );
CYG_TEST_CHECK( E_ID == ercd, "trcv_msg bad ercd !E_ID" );
ercd = trcv_msg( &rxptr, 2, -999 );
CYG_TEST_CHECK( E_PAR == ercd, "trcv_msg bad ercd !E_PAR" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = trcv_msg( NULL, 2, delay );
CYG_TEST_CHECK( E_PAR == ercd, "trcv_msg bad ercd !E_PAR" );
#endif
ercd = trcv_msg( NADR, 2, delay );
CYG_TEST_CHECK( E_PAR == ercd, "trcv_msg bad ercd !E_PAR" );
ercd = ref_mbx( &mbx_info, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mbx bad ercd !E_ID" );
ercd = ref_mbx( &mbx_info, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mbx bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_mbx( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_mbx bad ercd !E_PAR" );
#endif
ercd = ref_mbx( NADR, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_mbx bad ercd !E_PAR" );
CYG_TEST_PASS( "bad calls: snd_msg, [pt]rcv_msg, ref_mbx" );
#endif // we can test bad param error returns
 
// check the waitable functions versus dispatch disable
ercd = prcv_msg( &rxptr, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
ercd = trcv_msg( &rxptr, 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
ercd = trcv_msg( &rxptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rcv_msg( &rxptr, 2 );
CYG_TEST_CHECK( E_CTX == ercd, "rcv_msg bad ercd !E_CTX" );
ercd = trcv_msg( &rxptr, 2, delay );
CYG_TEST_CHECK( E_CTX == ercd, "trcv_msg bad ercd !E_CTX" );
ercd = trcv_msg( &rxptr, 2, TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "trcv_msg(FEVR) bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = trcv_msg( &rxptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
ercd = prcv_msg( &rxptr, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = prcv_msg( &rxptr, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
ercd = trcv_msg( &rxptr, 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
ercd = trcv_msg( &rxptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
CYG_TEST_PASS( "bad calls: rcv_msg, trcv_msg with dis_dsp" );
 
// check ref_mbx with various states
ercd = ref_mbx( &mbx_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
intercom = 0;
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
intercom = 1;
ercd = ref_mbx( &mbx_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
CYG_TEST_CHECK( 0 != mbx_info.wtsk, "mbx.wtsk should be non0" );
CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
ercd = snd_msg( 2, msgptr );
CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
ercd = ref_mbx( &mbx_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
#if 1
CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
#else // old, non-uITRON semantics
CYG_TEST_CHECK( msgptr == mbx_info.pk_msg, "mbx peek should be msgptr" );
#endif
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_mbx( &mbx_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
// fill the message box, expect E_QOVR
for ( scratch = 0 ; scratch < 100 ; scratch++ ) {
if ( E_OK != ( ercd = snd_msg( 2, msgptr ) ) )
break;
}
CYG_TEST_CHECK( (100 == scratch) || (E_QOVR == ercd),
"snd_msg bad ercd !E_QOVR/E_OK" );
// empty the message box, expect the right number and E_TMOUT
for ( ; 1 ; scratch-- ) {
if ( E_OK != ( ercd = prcv_msg( &rxptr, 2 ) ) )
break;
}
CYG_TEST_CHECK( 0 == scratch, "rcv_msg count bad scratch!=0" );
CYG_TEST_CHECK( E_TMOUT == ercd, "rcv_msg bad ercd !E_TMOUT" );
 
CYG_TEST_PASS( "good calls: rcv_msg, snd_msg with ref_msg" );
 
// Fixed block memory pools: all the illegal argument combinations first
CYG_TEST_INFO( "Testing fixed block memory ops" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rel_blf( -6, blfptr );
CYG_TEST_CHECK( E_ID == ercd, "rel_blf bad ercd !E_ID" );
ercd = rel_blf( 99, blfptr );
CYG_TEST_CHECK( E_ID == ercd, "rel_blf bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = rel_blf( 2, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
#endif
ercd = rel_blf( 2, NADR );
CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
#endif // we can test bad param error returns
ercd = rel_blf( 2, blfptr ); // it did not come from a mpf
CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blf( &blfptr, -6 );
CYG_TEST_CHECK( E_ID == ercd, "get_blf bad ercd !E_ID" );
ercd = get_blf( &blfptr, 99 );
CYG_TEST_CHECK( E_ID == ercd, "get_blf bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = get_blf( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "get_blf bad ercd !E_PAR" );
#endif
ercd = get_blf( NADR, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "get_blf bad ercd !E_PAR" );
ercd = pget_blf( &blfptr, -6 );
CYG_TEST_CHECK( E_ID == ercd, "pget_blf bad ercd !E_ID" );
ercd = pget_blf( &blfptr, 99 );
CYG_TEST_CHECK( E_ID == ercd, "pget_blf bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = pget_blf( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "pget_blf bad ercd !E_PAR" );
#endif
ercd = pget_blf( NADR, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "pget_blf bad ercd !E_PAR" );
ercd = tget_blf( &blfptr, -6, delay );
CYG_TEST_CHECK( E_ID == ercd, "tget_blf bad ercd !E_ID" );
ercd = tget_blf( &blfptr, 99, delay );
CYG_TEST_CHECK( E_ID == ercd, "tget_blf bad ercd !E_ID" );
ercd = tget_blf( &blfptr, 2, -999 );
CYG_TEST_CHECK( E_PAR == ercd, "tget_blf bad ercd !E_PAR" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = tget_blf( NULL, 2, delay );
CYG_TEST_CHECK( E_PAR == ercd, "tget_blf bad ercd !E_PAR" );
#endif
ercd = tget_blf( NADR, 2, delay );
CYG_TEST_CHECK( E_PAR == ercd, "tget_blf bad ercd !E_PAR" );
ercd = ref_mpf( &mpf_info, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mpf bad ercd !E_ID" );
ercd = ref_mpf( &mpf_info, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mpf bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_mpf( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_mpf bad ercd !E_PAR" );
#endif
ercd = ref_mpf( NADR, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_mpf bad ercd !E_PAR" );
CYG_TEST_PASS( "bad calls: rel_blf, [pt]get_blf, ref_mpf " );
#endif // we can test bad param error returns
 
// check the waitable functions versus dispatch disable
ercd = pget_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
ercd = rel_blf( 2, blfptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = rel_blf( 2, blfptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_CTX == ercd, "get_blf bad ercd !E_CTX" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blf bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = pget_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
ercd = rel_blf( 2, blfptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
ercd = rel_blf( 2, blfptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
// consume the whole thing then do it again, expecting E_TMOUT
while ( E_OK == (ercd = pget_blf( &blfptr, 2 ) ) )
continue;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
ercd = pget_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
ercd = tget_blf( &blfptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_CTX == ercd, "get_blf bad ercd !E_CTX" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blf bad ercd !E_CTX" );
ercd = tget_blf( &blfptr, 2, TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blf(FEVR) bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = tget_blf( &blfptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = pget_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
ercd = tget_blf( &blfptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
CYG_TEST_PASS( "bad calls: rel_blf, [pt]get_blf with ena_dsp" );
 
// check ref_mpf with various states
ercd = ref_mpf( &mpf_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
intercom = 0;
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
intercom = 1;
ercd = ref_mpf( &mpf_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
CYG_TEST_CHECK( 0 != mpf_info.wtsk, "mpf.wtsk should be non0" );
CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
ercd = rel_blf( 2, blfptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
ercd = ref_mpf( &mpf_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
#if 1
CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
#else // old, non-uITRON semantics
CYG_TEST_CHECK( 0 != mpf_info.frbcnt, "mpf.frbcnt should be non0" );
#endif
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_mpf( &mpf_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
CYG_TEST_PASS( "good calls: rel_blf, get_blf with ref_mpf" );
 
// Variable block memory pools; illegal arguments
CYG_TEST_INFO( "Testing variable block memory ops" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rel_blk( -6, blkptr );
CYG_TEST_CHECK( E_ID == ercd, "rel_blk bad ercd !E_ID" );
ercd = rel_blk( 99, blkptr );
CYG_TEST_CHECK( E_ID == ercd, "rel_blk bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = rel_blk( 2, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
#endif
ercd = rel_blk( 2, NADR );
CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
#endif // we can test bad param error returns
ercd = rel_blk( 2, blkptr ); // it did not come from a mpl
CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blk( &blkptr, -6, 100 );
CYG_TEST_CHECK( E_ID == ercd, "get_blk bad ercd !E_ID" );
ercd = get_blk( &blkptr, 99, 100 );
CYG_TEST_CHECK( E_ID == ercd, "get_blk bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = get_blk( NULL, 2, 100 );
CYG_TEST_CHECK( E_PAR == ercd, "get_blk bad ercd !E_PAR" );
#endif
ercd = get_blk( NADR, 2, 100 );
CYG_TEST_CHECK( E_PAR == ercd, "get_blk bad ercd !E_PAR" );
ercd = pget_blk( &blkptr, -6, 100 );
CYG_TEST_CHECK( E_ID == ercd, "pget_blk bad ercd !E_ID" );
ercd = pget_blk( &blkptr, 99, 100 );
CYG_TEST_CHECK( E_ID == ercd, "pget_blk bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = pget_blk( NULL, 2, 100 );
CYG_TEST_CHECK( E_PAR == ercd, "pget_blk bad ercd !E_PAR" );
#endif
ercd = pget_blk( NADR, 2, 100 );
CYG_TEST_CHECK( E_PAR == ercd, "pget_blk bad ercd !E_PAR" );
ercd = tget_blk( &blkptr, -6, 100, delay );
CYG_TEST_CHECK( E_ID == ercd, "tget_blk bad ercd !E_ID" );
ercd = tget_blk( &blkptr, 99, 100, delay );
CYG_TEST_CHECK( E_ID == ercd, "tget_blk bad ercd !E_ID" );
ercd = tget_blk( &blkptr, 2, 100, -999 );
CYG_TEST_CHECK( E_PAR == ercd, "tget_blk bad ercd !E_PAR" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = tget_blk( NULL, 2, 100, delay );
CYG_TEST_CHECK( E_PAR == ercd, "tget_blk bad ercd !E_PAR" );
#endif
ercd = tget_blk( NADR, 2, 100, delay );
CYG_TEST_CHECK( E_PAR == ercd, "tget_blk bad ercd !E_PAR" );
ercd = ref_mpl( &mpl_info, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mpl bad ercd !E_ID" );
ercd = ref_mpl( &mpl_info, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mpl bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_mpl( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_mpl bad ercd !E_PAR" );
#endif
ercd = ref_mpl( NADR, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_mpl bad ercd !E_PAR" );
CYG_TEST_PASS( "bad calls: rel_blk, [pt]get_blk, ref_mpl " );
#endif // we can test bad param error returns
 
// check the waitable functions versus dispatch disable
ercd = pget_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
ercd = rel_blk( 2, blkptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = rel_blk( 2, blkptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_CTX == ercd, "get_blk bad ercd !E_CTX" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blk bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = pget_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
ercd = rel_blk( 2, blkptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
ercd = rel_blk( 2, blkptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
// consume the whole thing then do it again, expecting E_TMOUT
while ( E_OK == (ercd = pget_blk( &blkptr, 2, 100 ) ) )
continue;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
ercd = pget_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_CTX == ercd, "get_blk bad ercd !E_CTX" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blk bad ercd !E_CTX" );
ercd = tget_blk( &blkptr, 2, 100, TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blk(FEVR) bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = pget_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
CYG_TEST_PASS( "bad calls: rel_blk, [pt]get_blk with ena_dsp" );
 
// check ref_mpl with various states
ercd = ref_mpl( &mpl_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
CYG_TEST_CHECK( mpl_info.maxsz <= mpl_info.frsz,
"mpl.maxsz not < mpl.frsz" );
intercom = 0;
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
intercom = 1;
ercd = ref_mpl( &mpl_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
CYG_TEST_CHECK( 0 != mpl_info.wtsk, "mpl.wtsk should be non0" );
ercd = rel_blk( 2, blkptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
ercd = ref_mpl( &mpl_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_mpl( &mpl_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
CYG_TEST_PASS( "good calls: rel_blk, get_blk with ref_mpl" );
 
// all done
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
T_MSG *msgp = NULL;
UINT flgval = 0;
VP blfp = NULL;
VP blkp = NULL;
 
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
if ( 222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 222" );
 
while ( intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
}
ercd = wai_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
while ( intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
}
ercd = wai_flg( &flgval, 2, 99, TWF_ANDW );
CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
CYG_TEST_CHECK( 99 == (99 & flgval), "flg value no good" );
while ( intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
}
ercd = rcv_msg( &msgp, 2 );
CYG_TEST_CHECK( E_OK == ercd, "rcv_msg bad ercd" );
CYG_TEST_CHECK( NULL != msgp, "no msg received" );
CYG_TEST_CHECK( NADR != msgp, "no msg received" );
while ( intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
}
ercd = get_blf( &blfp, 2 );
CYG_TEST_CHECK( E_OK == ercd, "get_blf bad ercd" );
CYG_TEST_CHECK( NULL != blfp, "no blf allocated" );
CYG_TEST_CHECK( NADR != blfp, "no blf allocated" );
while ( intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
}
ercd = get_blk( &blkp, 2, 100 );
CYG_TEST_CHECK( E_OK == ercd, "get_blk bad ercd" );
CYG_TEST_CHECK( NULL != blkp, "no blk allocated" );
CYG_TEST_CHECK( NADR != blkp, "no blk allocated" );
 
ext_tsk();
CYG_TEST_FAIL( "Task 2 failed to exit" );
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF test2.c
/v2_0/tests/test3.c
0,0 → 1,255
//===========================================================================
//
// test3.c
//
// uITRON "C" test program three
//
//===========================================================================
//####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-03-13
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
int t2done = 0;
int t3done = 0;
int t4done = 0;
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
void task1( unsigned int arg )
{
ER ercd;
INT scratch;
 
CYG_TEST_INFO( "Task 1 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
// start lower prio tasks to interact with
ercd = sta_tsk( 2, 222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = sta_tsk( 3, 333 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = sta_tsk( 4, 444 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
 
// now start the test
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
CYG_TEST_INFO( "T1 awoken" );
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
CYG_TEST_INFO( "T1 signalled" );
// let the others complete, so we get the status back
ercd = dly_tsk( 50 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( t2done, "t2 not done" );
CYG_TEST_CHECK( t3done, "t3 not done" );
CYG_TEST_CHECK( t4done, "t4 not done" );
 
CYG_TEST_PASS( "Immediate-dispatch producer/consumer test OK" );
 
// all done
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
INT scratch;
 
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
if ( 222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 222" );
 
// now start the test
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
CYG_TEST_INFO( "T2 awoken" );
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = wup_tsk( 1 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
 
CYG_TEST_INFO( "T2 completing" );
t2done++;
 
ercd = slp_tsk();
CYG_TEST_FAIL( "Task 2 sleep came back" );
}
 
void task3( unsigned int arg )
{
ER ercd;
INT scratch;
 
CYG_TEST_INFO( "Task 3 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 3 == scratch, "tid not 3" );
if ( 333 != arg )
CYG_TEST_FAIL( "Task 3 arg not 333" );
 
// now start the test
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
CYG_TEST_INFO( "T3 awoken" );
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
CYG_TEST_INFO( "T3 completing" );
t3done++;
 
ercd = slp_tsk();
CYG_TEST_FAIL( "Task 3 sleep came back" );
}
 
void task4( unsigned int arg )
{
ER ercd;
INT scratch;
 
CYG_TEST_INFO( "Task 4 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 4 == scratch, "tid not 4" );
if ( 444 != arg )
CYG_TEST_FAIL( "Task 4 arg not 444" );
 
// now start the test
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
 
CYG_TEST_INFO( "T4 completing" );
t4done++;
 
ercd = slp_tsk();
CYG_TEST_FAIL( "Task 4 sleep came back" );
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF test3.c
/v2_0/tests/test4.c
0,0 → 1,403
//===========================================================================
//
// test4.c
//
// uITRON "C" test program four
//
//===========================================================================
//####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): dsm
// Contributors: dsm
// Date: 1998-06-12
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough cyclic handlers */ \
defined( CYGPKG_UITRON_CYCLICS ) && \
(CYGNUM_UITRON_CYCLICS >= 3) && \
(CYGNUM_UITRON_CYCLICS < 90) && \
\
/* test configuration for enough alarm handlers */ \
defined( CYGPKG_UITRON_ALARMS ) && \
(CYGNUM_UITRON_ALARMS >= 3) && \
(CYGNUM_UITRON_ALARMS < 90) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
volatile int intercount = 0;
INT scratch;
 
void hand1(void)
{
CYG_TEST_INFO("Handler 1 called");
intercount++;
}
 
void hand2(void)
{
CYG_TEST_CHECK( 2 == intercount, "handler out of sync" );
CYG_TEST_INFO("Handler 2 called");
intercount++;
}
 
void task1( unsigned int arg )
{
ER ercd;
 
T_DCYC dcyc;
T_DALM dalm;
T_RCYC rcyc;
T_RALM ralm;
 
unsigned int tm;
 
static char foo[] = "Test message";
VP info = (VP)foo;
 
// Increase times when running on HW since overhead of GDB packet
// acknowledgements may cause tests of timing to fail.
if (cyg_test_is_simulator)
tm = 1;
else
tm = 4;
 
CYG_TEST_INFO( "Task 1 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
 
dcyc.exinf = (VP)info;
dcyc.cycatr = TA_HLNG;
dcyc.cychdr = (FP)&hand1;
dcyc.cycact = TCY_INI; // bad
dcyc.cyctim = 2;
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = def_cyc(3, &dcyc);
CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
#endif // we can test bad param error returns
 
dcyc.cycact = TCY_OFF; // make good
dcyc.cyctim = 0; // bad
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = def_cyc(3, &dcyc);
CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
#endif // we can test bad param error returns
 
dcyc.cyctim = 1; // make good
 
ercd = def_cyc(3, &dcyc);
CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = def_cyc(-6, &dcyc);
CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
ercd = def_cyc(99, &dcyc);
CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
 
ercd = act_cyc(-6, TCY_OFF);
CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
ercd = act_cyc(99, TCY_OFF);
CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
ercd = act_cyc( 3, ~0);
CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
ercd = ref_cyc(&rcyc, -6);
CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
ercd = ref_cyc(&rcyc, 99);
CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_cyc(NULL, 3);
CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
#endif
ercd = ref_cyc(NADR, 3);
CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
#endif // we can test bad param error returns
 
ercd = def_cyc(3, (T_DCYC *)NADR);
CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_cyc bad ercd !E_NOEXS" );
#endif // we can test bad param error returns
 
CYG_TEST_PASS( "bad calls: def_cyc, act_cyc, ref_cyc" );
 
dalm.exinf = (VP)info;
dalm.almatr = TA_HLNG;
dalm.almhdr = (FP)&hand2;
dalm.tmmode = ~0; // bad
dalm.almtim = 20;
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = def_alm(3, &dalm);
CYG_TEST_CHECK( E_PAR == ercd, "def_alm bad ercd !E_PAR" );
#endif // we can test bad param error returns
 
dalm.tmmode = TTM_REL; // make good
dalm.almtim = 0; // bad
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = def_alm(3, &dalm);
CYG_TEST_CHECK( E_PAR == ercd, "def_alm bad ercd !E_PAR" );
#endif // we can test bad param error returns
 
dalm.almtim = 1000; // make good
 
ercd = def_alm(3, &dalm);
CYG_TEST_CHECK( E_OK == ercd, "def_alm bad ercd" );
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = ref_alm(&ralm, -6);
CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
ercd = ref_alm(&ralm, 99);
CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_alm(NULL, 3);
CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
#endif
ercd = ref_alm(NADR, 3);
CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
 
#endif // we can test bad param error returns
ercd = def_alm(3, (T_DALM *)NADR);
CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = ref_alm(&ralm, 3);
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_cyc bad ercd !E_NOEXS" );
#endif // we can test bad param error returns
 
CYG_TEST_PASS( "bad calls: def_alm, act_alm, ref_alm" );
dcyc.exinf = (VP)info;
dcyc.cycatr = TA_HLNG;
dcyc.cychdr = (FP)&hand1;
dcyc.cycact = TCY_ON;
dcyc.cyctim = 50*tm;
ercd = def_cyc(3, &dcyc);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
ercd = act_cyc(3, TCY_OFF);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_OFF == rcyc.cycact, "rcyc.cycact should be TCY_OFF" );
ercd = act_cyc(3, TCY_ON);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc bad ercd" );
CYG_TEST_PASS("good calls: def_cyc, act_cyc, ref_cyc");
 
dalm.exinf = (VP)info;
dalm.almatr = TA_HLNG;
dalm.almhdr = (FP)&hand2;
dalm.tmmode = TTM_REL;
dalm.almtim = 120*tm;
 
ercd = def_alm(3, &dalm);
CYG_TEST_CHECK( E_OK == ercd, "def_alm bad ercd" );
ercd = ref_alm(&ralm, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_alm bad ercd" );
CYG_TEST_CHECK( info == ralm.exinf, "ralm.exinf should be info" );
CYG_TEST_CHECK( 115*tm < ralm.lfttim, "ralm.lfttim too small" );
CYG_TEST_CHECK( ralm.lfttim <= 120*tm, "ralm.lfttim too big" );
 
// Expect handlers to be called at approximate times
// time intercount
// tm*50 hand1 0
// tm*100 hand1 1
// tm*120 hand2 2
// tm*150 hand1 3
 
ercd = dly_tsk(160*tm);
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 4 == intercount, "handlers not both called" );
ercd = act_cyc(3, TCY_OFF);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc(off) bad ercd" );
 
ercd = dly_tsk(60*tm); // enough for at least one tick
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 4 == intercount, "cyclic not disabled" );
 
// approx time now 220, so we expect a cycle in about 30 ticks
ercd = act_cyc(3, TCY_ON);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 25*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 35*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
 
// now resynchronize with right now:
ercd = act_cyc(3, TCY_ON|TCY_INI);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
 
// wait a bit and check that time marches on, or even down
ercd = dly_tsk(10*tm);
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 35*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 45*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
 
// now turn it off and re-synch with right now:
ercd = act_cyc(3, TCY_OFF|TCY_INI);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_OFF == rcyc.cycact, "rcyc.cycact should be TCY_OFF" );
 
ercd = act_cyc(3, TCY_OFF);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
 
CYG_TEST_PASS("good calls: def_cyc, act_cyc, ref_cyc, def_alm, ref_alm");
 
// all done
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF test4.c
/v2_0/tests/test5.c
0,0 → 1,353
//===========================================================================
//
// test5.c
//
// uITRON "C" test program five
//
//===========================================================================
//####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): dsm
// Contributors: dsm
// Date: 1998-06-12
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* test configuration for enough flag objects */ \
defined( CYGPKG_UITRON_FLAGS ) && \
(CYGNUM_UITRON_FLAGS >= 3) && \
(CYGNUM_UITRON_FLAGS < 90) && \
( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) || \
CYGNUM_UITRON_FLAGS_INITIALLY >= 3 ) && \
\
/* test configuration for enough message boxes */ \
defined( CYGPKG_UITRON_MBOXES ) && \
(CYGNUM_UITRON_MBOXES >= 3) && \
(CYGNUM_UITRON_MBOXES < 90) && \
( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) || \
CYGNUM_UITRON_MBOXES_INITIALLY >= 3 ) && \
\
/* test configuration for enough fixed memory pools */ \
defined( CYGPKG_UITRON_MEMPOOLFIXED ) && \
(CYGNUM_UITRON_MEMPOOLFIXED >= 3) && \
(CYGNUM_UITRON_MEMPOOLFIXED < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3 ) && \
\
/* test configuration for enough variable mempools */ \
defined( CYGPKG_UITRON_MEMPOOLVAR ) && \
(CYGNUM_UITRON_MEMPOOLVAR >= 3) && \
(CYGNUM_UITRON_MEMPOOLVAR < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
volatile int intercount = 0;
UINT scratch;
T_MSG *t_msg;
VP vp;
 
void task1( unsigned int arg )
{
ER ercd;
int i;
T_RSYS rsys;
 
CYG_TEST_INFO( "Task 1 running" );
 
// check initial state
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
// disable intrs and check state
ercd = loc_cpu();
CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// try an illegal op
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
#endif // CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// enable intrs and check state and a legal sleep
ercd = unl_cpu();
CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
ercd = dly_tsk( 1 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
// disable intrs and try scheduler illegal ops
ercd = loc_cpu();
CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = dis_dsp();
CYG_TEST_CHECK( E_CTX == ercd, "dis_dsp bad ercd !E_CTX" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_CTX == ercd, "ena_dsp bad ercd !E_CTX" );
#endif // CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// enable again and check state
ercd = unl_cpu();
CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
// disable the scheduler and check state
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_DDSP == rsys.sysstat, "system state not TSS_DDSP" );
// disable intrs and check state
ercd = loc_cpu();
CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
// then unlock and check state
ercd = unl_cpu();
CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
 
CYG_TEST_PASS( "Interrupt dis/enabling and interactions" );
 
// and now we can do the rest of the test
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai bad ercd !E_OBJ" );
ercd = rel_wai( 1 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai(me) bad ercd !E_OBJ" );
ercd = rel_wai( -6 );
CYG_TEST_CHECK( E_ID == ercd, "rel_wai bad ercd !E_ID" );
ercd = rel_wai( 99 );
CYG_TEST_CHECK( E_ID == ercd, "rel_wai bad ercd !E_ID" );
#endif // we can test bad param error returns
 
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 2, 22222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai bad ercd !E_OBJ" );
ercd = rel_wai( 1 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai(me) bad ercd !E_OBJ" );
#endif // we can test bad param error returns
 
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_RLWAI == ercd, "wai_sem bad ercd !E_RLWAI" );
 
ercd = twai_sem( 1, 20 );
CYG_TEST_CHECK( E_RLWAI == ercd, "twai_sem bad ercd !E_RLWAI" );
 
ercd = wai_flg( &scratch, 1, 9999, 0 );
CYG_TEST_CHECK( E_RLWAI == ercd, "wai_flg bad ercd !E_RLWAI" );
 
ercd = twai_flg( &scratch, 1, 9999, 0, 10 );
CYG_TEST_CHECK( E_RLWAI == ercd, "twai_flg bad ercd !E_RLWAI" );
 
ercd = rcv_msg( &t_msg, 1 );
CYG_TEST_CHECK( E_RLWAI == ercd, "rcv_msg bad ercd !E_RLWAI" );
 
ercd = trcv_msg( &t_msg, 1, 10 );
CYG_TEST_CHECK( E_RLWAI == ercd, "trcv_msg bad ercd !E_RLWAI" );
 
// these are loops so as to consume the whole of the mempool
// in order to wait at the end
for ( i = 0; i < 10; i++ )
if ( E_OK != (ercd = get_blf( &vp, 3 ) ) )
break;
CYG_TEST_CHECK( E_RLWAI == ercd, "get_blf bad ercd !E_RLWAI" );
 
for ( i = 0; i < 10; i++ )
if ( E_OK != (ercd = tget_blf( &vp, 3, 10 ) ) )
break;
CYG_TEST_CHECK( E_RLWAI == ercd, "tget_blf bad ercd !E_RLWAI" );
 
for ( i = 0; i < 10; i++ )
if ( E_OK != (ercd = get_blk( &vp, 1, 1000 ) ) )
break;
CYG_TEST_CHECK( E_RLWAI == ercd, "get_blk bad ercd !E_RLWAI" );
 
for ( i = 0; i < 10; i++ )
if ( E_OK != (ercd = tget_blk( &vp, 1, 1000, 10 ) ) )
break;
CYG_TEST_CHECK( E_RLWAI == ercd, "tget_blk bad ercd !E_RLWAI" );
 
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_RLWAI == ercd, "dly_tsk bad ercd !E_RLWAI" );
 
ercd = tslp_tsk( 10 );
CYG_TEST_CHECK( E_RLWAI == ercd, "tslp_tsk bad ercd !E_RLWAI" );
 
ercd = slp_tsk();
CYG_TEST_CHECK( E_RLWAI == ercd, "slp_tsk bad ercd !E_RLWAI" );
 
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
CYG_TEST_PASS("release wait: various waiting calls");
 
// all done
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
int i;
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &i );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == i, "tid not 2" );
if ( 22222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 22222" );
 
for ( i = 0 ; i < 100; i++ ) {
ercd = rel_wai( 1 );
CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
}
// we expect task2 to be killed here
CYG_TEST_FAIL( "Task 2 ran to completion!" );
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF test5.c
/v2_0/tests/test6.c
0,0 → 1,599
//===========================================================================
//
// test6.c
//
// uITRON "C" test program six
//
//===========================================================================
//####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-10-01
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* test configuration for enough flag objects */ \
defined( CYGPKG_UITRON_FLAGS ) && \
(CYGNUM_UITRON_FLAGS >= 3) && \
(CYGNUM_UITRON_FLAGS < 90) && \
( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) || \
CYGNUM_UITRON_FLAGS_INITIALLY >= 3 ) && \
\
/* test configuration for enough message boxes */ \
defined( CYGPKG_UITRON_MBOXES ) && \
(CYGNUM_UITRON_MBOXES >= 3) && \
(CYGNUM_UITRON_MBOXES < 90) && \
( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) || \
CYGNUM_UITRON_MBOXES_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
volatile int intercount = 0;
UINT scratch;
T_MSG *t_msg = (T_MSG *)&scratch;
T_MSG *msg;
VP vp;
 
T_CSEM t_csem = { NULL, 0, 0 };
T_CMBX t_cmbx = { NULL, 0 };
T_CFLG t_cflg = { NULL, 0, 0 };
T_RSEM t_rsem;
T_RMBX t_rmbx;
T_RFLG t_rflg;
 
 
void task1( unsigned int arg )
{
ER ercd;
int tests = 0;
 
CYG_TEST_INFO( "Task 1 running" );
 
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 2, 22222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
tests++;
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_sem( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_sem bad ercd !E_ID" );
ercd = del_sem( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_sem bad ercd !E_ID" );
ercd = cre_sem( -6, &t_csem );
CYG_TEST_CHECK( E_ID == ercd, "cre_sem bad ercd !E_ID" );
ercd = cre_sem( 99, &t_csem );
CYG_TEST_CHECK( E_ID == ercd, "cre_sem bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
ercd = cre_sem( 3, &t_csem );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_sem bad ercd !E_OBJ" );
// delete it so we can play
ercd = del_sem( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
// check it is deleted
ercd = sig_sem( 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
ercd = preq_sem( 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "preq_sem bad ercd !E_NOEXS" );
ercd = twai_sem( 3, 10 );
CYG_TEST_CHECK( E_NOEXS == ercd, "twai_sem bad ercd !E_NOEXS" );
ercd = wai_sem( 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "wai_sem bad ercd !E_NOEXS" );
ercd = ref_sem( &t_rsem, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_sem bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_sem( 3, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_sem bad ercd !E_PAR" );
#endif
ercd = cre_sem( 3, NADR );
CYG_TEST_CHECK( E_PAR == ercd, "cre_sem bad ercd !E_PAR" );
t_csem.sematr = 0xfff;
ercd = cre_sem( 3, &t_csem );
CYG_TEST_CHECK( E_RSATR == ercd, "cre_sem bad ercd !E_RSATR" );
t_csem.sematr = 0;
#endif // we can test bad param error returns
ercd = cre_sem( 3, &t_csem );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
// and check we can use it
ercd = sig_sem( 3 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = wai_sem( 3 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
ercd = preq_sem( 3 );
CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
ercd = twai_sem( 3, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
ercd = ref_sem( &t_rsem, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
 
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_DLT == ercd, "wai_sem bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = twai_sem( 2, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_sem bad ercd !E_DLT" );
 
// check they are deleted
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
// re-create and do it again
ercd = cre_sem( 1, &t_csem );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
ercd = cre_sem( 2, &t_csem );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
 
// now wait while task 2 deletes the wait objects again
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_DLT == ercd, "wai_sem bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = twai_sem( 2, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_sem bad ercd !E_DLT" );
 
// check they are deleted
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
 
CYG_TEST_PASS("create/delete semaphores");
#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
 
 
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
tests++;
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_flg( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_flg bad ercd !E_ID" );
ercd = del_flg( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_flg bad ercd !E_ID" );
ercd = cre_flg( -6, &t_cflg );
CYG_TEST_CHECK( E_ID == ercd, "cre_flg bad ercd !E_ID" );
ercd = cre_flg( 99, &t_cflg );
CYG_TEST_CHECK( E_ID == ercd, "cre_flg bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
ercd = cre_flg( 3, &t_cflg );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_flg bad ercd !E_OBJ" );
// delete it so we can play
ercd = del_flg( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
// check it is deleted
ercd = set_flg( 3, 0x6789 );
CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
ercd = clr_flg( 3, 0x9876 );
CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
ercd = pol_flg( &scratch, 3, 0xdddd, TWF_ANDW );
CYG_TEST_CHECK( E_NOEXS == ercd, "pol_flg bad ercd !E_NOEXS" );
ercd = twai_flg( &scratch, 3, 0x4444, TWF_ORW, 10 );
CYG_TEST_CHECK( E_NOEXS == ercd, "twai_flg bad ercd !E_NOEXS" );
ercd = wai_flg( &scratch, 3, 0xbbbb, TWF_ANDW | TWF_CLR );
CYG_TEST_CHECK( E_NOEXS == ercd, "wai_flg bad ercd !E_NOEXS" );
ercd = ref_flg( &t_rflg, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_flg bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_flg( 3, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_flg bad ercd !E_PAR" );
#endif
ercd = cre_flg( 3, NADR );
CYG_TEST_CHECK( E_PAR == ercd, "cre_flg bad ercd !E_PAR" );
t_cflg.flgatr = 0xfff;
ercd = cre_flg( 3, &t_cflg );
CYG_TEST_CHECK( E_RSATR == ercd, "cre_flg bad ercd !E_RSATR" );
#endif // we can test bad param error returns
// now create it well
t_cflg.flgatr = 0;
t_cflg.iflgptn = 0;
ercd = cre_flg( 3, &t_cflg );
CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
// and check we can use it
ercd = clr_flg( 3, 0x7256 );
CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd" );
ercd = set_flg( 3, 0xff );
CYG_TEST_CHECK( E_OK == ercd, "set_flg bad ercd" );
ercd = wai_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR );
CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
ercd = pol_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR );
CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
ercd = twai_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
ercd = ref_flg( &t_rflg, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 == t_rflg.flgptn, "ref_flg bad ercd" );
// now create it again with a preset pattern and check that we can
// detect that pattern:
ercd = del_flg( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
t_cflg.flgatr = 0;
t_cflg.iflgptn = 0x1234;
ercd = cre_flg( 3, &t_cflg );
CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
// and check we can use it
ercd = wai_flg( &scratch, 3, 0x1200, TWF_ANDW );
CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
ercd = pol_flg( &scratch, 3, 0x0034, TWF_ANDW );
CYG_TEST_CHECK( E_OK == ercd, "pol_flg bad ercd" );
ercd = twai_flg( &scratch, 3, 0x1004, TWF_ANDW, 10 );
CYG_TEST_CHECK( E_OK == ercd, "twai_flg bad ercd" );
ercd = pol_flg( &scratch, 3, 0xffedcb, TWF_ORW );
CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
ercd = ref_flg( &t_rflg, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0x1234 == t_rflg.flgptn, "ref_flg bad ercd" );
ercd = clr_flg( 3, 0 );
ercd = ref_flg( &t_rflg, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 == t_rflg.flgptn, "ref_flg bad ercd" );
 
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = wai_flg( &scratch, 1, 0xaa, TWF_ANDW );
CYG_TEST_CHECK( E_DLT == ercd, "wai_flg bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = twai_flg( &scratch, 2, 0x55, TWF_ANDW, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_flg bad ercd !E_DLT" );
 
// check they are deleted
ercd = set_flg( 1, 0x22 );
CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
ercd = clr_flg( 2, 0xdd );
CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
// re-create and do it again
t_cflg.iflgptn = 0x5555;
ercd = cre_flg( 1, &t_cflg );
CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
t_cflg.iflgptn = 0;
ercd = cre_flg( 2, &t_cflg );
CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
 
// now wait while task 2 deletes the wait objects again
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = wai_flg( &scratch, 1, 0xaaaa, TWF_ORW | TWF_CLR );
CYG_TEST_CHECK( E_DLT == ercd, "wai_flg bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = twai_flg( &scratch, 2, 0xffff, TWF_ORW, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_flg bad ercd !E_DLT" );
 
// check they are deleted
ercd = clr_flg( 1, 0xd00d );
CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
ercd = set_flg( 2, 0xfff00 );
CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
 
CYG_TEST_PASS("create/delete flags");
#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
 
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
tests++;
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_mbx( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_mbx bad ercd !E_ID" );
ercd = del_mbx( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_mbx bad ercd !E_ID" );
ercd = cre_mbx( -6, &t_cmbx );
CYG_TEST_CHECK( E_ID == ercd, "cre_mbx bad ercd !E_ID" );
ercd = cre_mbx( 99, &t_cmbx );
CYG_TEST_CHECK( E_ID == ercd, "cre_mbx bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
ercd = cre_mbx( 3, &t_cmbx );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_mbx bad ercd !E_OBJ" );
// delete it so we can play
ercd = del_mbx( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
// check it is deleted
ercd = snd_msg( 3, t_msg );
CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
ercd = rcv_msg( &msg, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "rcv_msg bad ercd !E_NOEXS" );
ercd = trcv_msg( &msg, 3, 10 );
CYG_TEST_CHECK( E_NOEXS == ercd, "trcv_msg bad ercd !E_NOEXS" );
ercd = prcv_msg( &msg, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "prcv_msg bad ercd !E_NOEXS" );
ercd = ref_mbx( &t_rmbx, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mbx bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_mbx( 3, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_mbx bad ercd !E_PAR" );
#endif
ercd = cre_mbx( 3, NADR );
CYG_TEST_CHECK( E_PAR == ercd, "cre_mbx bad ercd !E_PAR" );
t_cmbx.mbxatr = 0xfff;
ercd = cre_mbx( 3, &t_cmbx );
CYG_TEST_CHECK( E_RSATR == ercd, "cre_mbx bad ercd !E_RSATR" );
t_cmbx.mbxatr = 0;
#endif // we can test bad param error returns
ercd = cre_mbx( 3, &t_cmbx );
CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
// and check we can use it
ercd = snd_msg( 3, t_msg );
CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
ercd = rcv_msg( &msg, 3 );
CYG_TEST_CHECK( E_OK == ercd, "rcv_msg bad ercd" );
ercd = trcv_msg( &msg, 3, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
ercd = prcv_msg( &msg, 3 );
CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
ercd = ref_mbx( &t_rmbx, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
 
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rcv_msg( &msg, 1 );
CYG_TEST_CHECK( E_DLT == ercd, "wai_mbx bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = trcv_msg( &msg, 2, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_mbx bad ercd !E_DLT" );
 
// check they are deleted
ercd = snd_msg( 1, t_msg );
CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
ercd = snd_msg( 2, t_msg );
CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
// re-create and do it again
ercd = cre_mbx( 1, &t_cmbx );
CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
ercd = cre_mbx( 2, &t_cmbx );
CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
 
// now wait while task 2 deletes the wait objects again
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rcv_msg( &msg, 1 );
CYG_TEST_CHECK( E_DLT == ercd, "wai_mbx bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = trcv_msg( &msg, 2, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_mbx bad ercd !E_DLT" );
 
// check they are deleted
ercd = snd_msg( 1, t_msg );
CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
ercd = snd_msg( 2, t_msg );
CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
 
CYG_TEST_PASS("create/delete mboxes");
#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
 
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
ercd = dly_tsk( 5 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
// all done
if ( 0 == tests ) {
CYG_TEST_NA( "No objects have create/delete enabled" );
}
else {
CYG_TEST_EXIT( "All done" );
}
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
int i;
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &i );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == i, "tid not 2" );
if ( 22222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 22222" );
 
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
 
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
ercd = del_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
 
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
ercd = del_flg( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_flg( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_flg( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_flg( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
 
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
ercd = del_mbx( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mbx( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mbx( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mbx( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
 
// we expect task2 to be killed here
CYG_TEST_FAIL( "Task 2 ran to completion!" );
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF test6.c
/v2_0/tests/test7.c
0,0 → 1,1013
//===========================================================================
//
// test7.c
//
// uITRON "C" test program seven
//
//===========================================================================
//####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-10-01
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* test configuration for enough flag objects */ \
defined( CYGPKG_UITRON_FLAGS ) && \
(CYGNUM_UITRON_FLAGS >= 3) && \
(CYGNUM_UITRON_FLAGS < 90) && \
( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) || \
CYGNUM_UITRON_FLAGS_INITIALLY >= 3 ) && \
\
/* test configuration for enough message boxes */ \
defined( CYGPKG_UITRON_MBOXES ) && \
(CYGNUM_UITRON_MBOXES >= 3) && \
(CYGNUM_UITRON_MBOXES < 90) && \
( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) || \
CYGNUM_UITRON_MBOXES_INITIALLY >= 3 ) && \
\
/* test configuration for enough fixed memory pools */ \
defined( CYGPKG_UITRON_MEMPOOLFIXED ) && \
(CYGNUM_UITRON_MEMPOOLFIXED >= 3) && \
(CYGNUM_UITRON_MEMPOOLFIXED < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3 ) && \
\
/* test configuration for enough variable mempools */ \
defined( CYGPKG_UITRON_MEMPOOLVAR ) && \
(CYGNUM_UITRON_MEMPOOLVAR >= 3) && \
(CYGNUM_UITRON_MEMPOOLVAR < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
// ========================================================================
 
typedef enum {
START_WAITOP = 0,
SLEEP = 0,
DELAY,
SEMGET,
FLAGWAIT,
MSGGET,
MEMFIXEDGET,
MEMVARGET,
DONE_WAITOP
} WAITOP;
 
typedef enum {
START_TYPE = 0,
PLAIN = 0,
TIMED = 1,
DONE_TYPE
} WAITTYPE;
 
typedef enum {
START_KILLOP = 0,
 
// These are the 5 ways out of a wait that we perm
// with other circumstances:
SIGNAL = 0, // do the appropriate producer op
TIMEOUT, // wait for the timeout to fire
RELEASE, // do a rel_wai()
DELETE, // delete the object; del_xxx()
KILL, // do a ter_tsk() on the waiter
 
SUSPEND_SIGNAL_RESUME,
SUSPEND_TIMEOUT_RESUME,
SUSPEND_RELEASE_RESUME,
SUSPEND_DELETE_RESUME,
SUSPEND_KILL, // resume not applicable
 
SUSPEND_SIGNAL_KILL,
SUSPEND_TIMEOUT_KILL,
SUSPEND_RELEASE_KILL,
SUSPEND_DELETE_KILL,
// SUSPEND_KILL_KILL not applicable
 
#if 0
// support these later if _really_ keen.
SUSPEND_SIGNAL_DELETE_RESUME,
SUSPEND_TIMEOUT_DELETE_RESUME,
SUSPEND_RELEASE_DELETE_RESUME,
// SUSPEND_DELETE_DELETE_RESUME not applicable
// SUSPEND_KILL_DELETE_RESUME not applicable
 
SUSPEND_SIGNAL_DELETE_KILL,
SUSPEND_TIMEOUT_DELETE_KILL,
SUSPEND_RELEASE_DELETE_KILL,
// SUSPEND_DELETE_DELETE_KILL,
SUSPEND_KILL_DELETE // 2nd kill not applicable
#endif
DONE_KILLOP
} KILLOP;
// ========================================================================
 
char * waitstrings[] =
{ "Sleep ", "Delay ", "Sema ", "Flag ", "Mbox ", "MemFix", "MemVar" };
 
char * typestrings[] =
{ " (Plain) : ", " (Timed) : " };
 
char * killstrings[] =
{ "Signal",
"Wait-for-timeout",
"Release-wait",
"Delete-object",
"Kill-task",
 
"Suspend/Signal/Resume",
"Suspend/Wait-for-timeout/Resume",
"Suspend/Release-wait/Resume",
"Suspend/Delete-object/Resume",
"Suspend/Kill-task",
 
"Suspend/Signal/Kill-task",
"Suspend/Wait-for-timeout/Kill-task",
"Suspend/Release-wait/Kill-task",
"Suspend/Delete-object/Kill-task",
 
};
 
// ========================================================================
 
inline int task2arg( WAITOP wait, WAITTYPE waittype, KILLOP kill )
{
return waittype + (wait << 1) + (kill << 8);
}
 
inline void decodearg( int arg, WAITOP *pwait, WAITTYPE *pwaittype, KILLOP *pkill )
{
*pwaittype = (arg & 1) ? TIMED : PLAIN;
*pwait = (arg >> 1) & 0x7f;
*pkill = (arg >> 8);
}
 
static char *strdog( char *p, char *q )
{
while ( 0 != (*p++ = *q++) );
return p - 1;
}
 
static char *
makemsg( char *z, WAITOP wait, WAITTYPE waittype, KILLOP kill )
{
static char buf[ 1000 ];
char *p = buf;
p = strdog( p, z );
p = strdog( p, waitstrings[ wait ] );
p = strdog( p, typestrings[ waittype ] );
p = strdog( p, killstrings[ kill ] );
*p = 0;
return buf;
}
 
// ========================================================================
 
volatile int intercom = 0;
 
// ========================================================================
 
T_RTSK rtsk;
 
void
do_suspend( void )
{
ER ercd;
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_WAI == rtsk.tskstat, "bad tskstat !TTS_WAI" );
ercd = sus_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_WAS == rtsk.tskstat, "bad tskstat !TTS_WAS" );
}
 
void
do_resume( void )
{
ER ercd;
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_SUS == rtsk.tskstat, "bad tskstat !TTS_SUS" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = rsm_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_RDY == rtsk.tskstat, "bad tskstat !TTS_RDY" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
}
 
// ========================================================================
 
#define T1_WAIT (7)
#define T2_WAIT (5)
 
#define T1_MALLOC (110)
#ifdef CYGSEM_KERNEL_MEMORY_COALESCE
#define T2_MALLOC (100)
#else
#define T2_MALLOC T1_MALLOC
#endif
 
VP vptmp;
VP vp = NULL;
VP vp1 = NULL;
VP t2vp = NULL;
VP t2vp_backup = NULL;
 
UINT scratch;
 
T_MSG *msg = (T_MSG *)&scratch;
T_MSG *msg1;
 
void
do_prep( WAITOP wait )
{
ER ercd;
switch ( wait ) {
case SLEEP:
case DELAY:
case SEMGET:
case FLAGWAIT:
case MSGGET:
// do nothing for all of those
break;
case MEMFIXEDGET:
// allocate all the memory in the pool; remember a couple
// for freeing as the signalling operation:
t2vp = NULL;
vp = vptmp = NULL;
do {
vp1 = vptmp;
vptmp = vp;
ercd = pget_blf( &vp, 1 );
} while ( E_OK == ercd );
CYG_TEST_CHECK( E_TMOUT == ercd, "get_blf bad ercd" );
CYG_TEST_CHECK( NULL != vp, "no allocated block to free" );
CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
break;
case MEMVARGET:
// allocate all the memory in the pool; remember a couple
// for freeing as the signalling operation:
t2vp = NULL;
vp = vptmp = NULL;
do {
vp1 = vptmp;
vptmp = vp;
ercd = pget_blk( &vp, 1, T1_MALLOC );
} while ( E_OK == ercd );
CYG_TEST_CHECK( E_TMOUT == ercd, "get_blk bad ercd" );
CYG_TEST_CHECK( NULL != vp, "no allocated block to free" );
CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
}
 
void
do_tidyup( WAITOP wait )
{
ER ercd;
switch ( wait ) {
case SLEEP:
case DELAY:
case SEMGET:
case MSGGET:
// do nothing for all of those
break;
case FLAGWAIT:
// clear the flag variable
ercd = clr_flg( 1, 0 );
CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd, tidy vp" );
break;
case MEMFIXEDGET:
if ( NULL != vp ) {
ercd = rel_blf( 1, vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy vp" );
}
if ( NULL != vp1 ) {
ercd = rel_blf( 1, vp1 );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy vp1" );
}
if ( NULL != t2vp ) {
ercd = rel_blf( 1, t2vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy t2vp" );
}
break;
case MEMVARGET:
if ( NULL != vp ) {
ercd = rel_blk( 1, vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy vp" );
}
if ( NULL != vp1 ) {
ercd = rel_blk( 1, vp1 );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy vp1" );
}
if ( NULL != t2vp ) {
ercd = rel_blk( 1, t2vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy t2vp" );
}
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
}
 
void
do_recreate( WAITOP wait )
{
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
static T_CSEM t_csem = { NULL, 0, 0 };
#endif
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
static T_CMBX t_cmbx = { NULL, 0 };
#endif
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
static T_CFLG t_cflg = { NULL, 0, 0 };
#endif
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
static T_CMPF t_cmpf = { NULL, 0, 20, 95 };
#endif
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
static T_CMPL t_cmpl = { NULL, 0, 2000 };
#endif
ER ercd = E_OK;
switch ( wait ) {
case SLEEP:
case DELAY:
// do nothing for all of those
break;
case SEMGET:
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
// create the semaphore
ercd = cre_sem( 1, &t_csem );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_recreate SEMGET" );
#endif
break;
case FLAGWAIT:
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
// create the flag
ercd = cre_flg( 1, &t_cflg );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_recreate FLAGWAIT" );
#endif
break;
case MSGGET:
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
// create the mbox
ercd = cre_mbx( 1, &t_cmbx );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_recreate MSGGET" );
#endif
break;
case MEMFIXEDGET:
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
// create the mempool
ercd = cre_mpf( 1, &t_cmpf );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_recreate MEMFIXEDGET" );
#endif
break;
case MEMVARGET:
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
// create the mempool
ercd = cre_mpl( 1, &t_cmpl );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_recreate MEMVARGET" );
#endif
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
// this is just to use ercd to prevent warnings
CYG_TEST_CHECK( E_OK == ercd, "<blank> bad ercd" );
}
 
 
 
void
do_signal( WAITOP wait )
{
ER ercd;
switch ( wait ) {
case SLEEP:
// send a wakeup
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
break;
case DELAY:
// simply wait for task 2's delay to complete
ercd = dly_tsk( T1_WAIT );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
break;
case SEMGET:
// signal the semaphore
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
break;
case FLAGWAIT:
// set the flag bits
ercd = set_flg( 1, 0xff );
CYG_TEST_CHECK( E_OK == ercd, "set_flg bad ercd" );
break;
case MSGGET:
// send a message
ercd = snd_msg( 1, msg );
CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
break;
case MEMFIXEDGET:
// release a couple of blocks we allocated earlier. I hope.
CYG_TEST_CHECK( NULL != vp, "no allocated block to free" );
CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
ercd = rel_blf( 1, vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
vp = NULL;
ercd = rel_blf( 1, vp1 );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd1" );
vp1 = NULL;
break;
case MEMVARGET:
// release a couple of blocks we allocated earlier. I hope.
CYG_TEST_CHECK( NULL != vp, "no allocated block to free" );
CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
ercd = rel_blk( 1, vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
vp = NULL;
ercd = rel_blk( 1, vp1 );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd1" );
vp1 = NULL;
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
}
 
void
do_delete( WAITOP wait )
{
ER ercd = E_OK;
switch ( wait ) {
case SLEEP:
case DELAY:
CYG_TEST_FAIL( "bad call to do_delete( SLEEP or DELAY )" );
break;
case SEMGET:
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
// delete the semaphore
ercd = del_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_delete( SEMGET )" );
#endif
break;
case FLAGWAIT:
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
// delete the flag
ercd = del_flg( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_delete( FLAGWAIT )" );
#endif
break;
case MSGGET:
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
// delete the mbox
ercd = del_mbx( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_delete( MSGGET )" );
#endif
break;
case MEMFIXEDGET:
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
// delete the mempool
ercd = del_mpf( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_delete( MEMFIXEDGET )" );
#endif
break;
case MEMVARGET:
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
// delete the mempool
ercd = del_mpl( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_delete( MEMVARGET )" );
#endif
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
// this is just to use ercd to prevent warnings
CYG_TEST_CHECK( E_OK == ercd, "<blank> bad ercd" );
}
 
 
ER
do_wait( WAITOP wait, WAITTYPE type )
{
switch ( wait ) {
case SLEEP:
return ( PLAIN == type ) ? slp_tsk() : tslp_tsk( T2_WAIT );
case DELAY:
return dly_tsk( T2_WAIT ); // forget the type
case SEMGET:
return ( PLAIN == type ) ? wai_sem( 1 ) : twai_sem( 1, T2_WAIT );
case FLAGWAIT:
return ( PLAIN == type ) ?
wai_flg( &scratch, 1, 0x55, TWF_ANDW ) :
twai_flg( &scratch, 1, 0xaa, TWF_ANDW, T2_WAIT );
case MSGGET:
return ( PLAIN == type ) ?
rcv_msg( &msg1, 1 ) :
trcv_msg( &msg1, 1, T2_WAIT );
case MEMFIXEDGET:
return ( PLAIN == type ) ?
get_blf( &t2vp, 1 ) :
tget_blf( &t2vp, 1, T2_WAIT );
case MEMVARGET:
return ( PLAIN == type ) ?
get_blk( &t2vp, 1, T2_MALLOC ) :
tget_blk( &t2vp, 1, T2_MALLOC, T2_WAIT );
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
CYG_TEST_FAIL( "Bad wait in do_wait" );
return E_SYS;
}
 
// ========================================================================
void task1( unsigned int arg )
{
ER ercd;
WAITOP wait;
WAITTYPE type;
KILLOP kill;
 
CYG_TEST_INFO( "Task 1 running" );
 
ercd = chg_pri( 1, 8 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
 
for ( wait = START_WAITOP; wait < DONE_WAITOP ; wait++) {
for ( type = START_TYPE; type < DONE_TYPE ; type++ ) {
for ( kill = START_KILLOP; kill < DONE_KILLOP ; kill++ ) {
// These clauses deal with a couple of special cases:
// [doing it this way helps keep the rest of the code
// nicely general and orthogonal]
//
// 1) DELAY: dly_tsk(): when this times out, the retcode is
// E_OK rather than E_TMOUT, and it always times out. The
// "signalling" method here is just to wait yourself. So we
// do not test DELAY with TIMED type.
//
// 2) PLAIN tests with TIMEOUT kill operations: a PLAIN test
// will not time out, it'll wait forever, so waiting for it
// so to do is pointless; further, we would check for the
// wrong error code. So we do not test PLAIN tests with
// TIMOUT kill operations.
//
// 3) SLEEP or DELAY tests with DELETE operations: there is
// no synchronization to delete in those cases.
// 3a) Individual object types are tested for delete support,
// and if there is none, the test is skipped.
 
if ( DELAY == wait && TIMED == type )
continue;
 
if ( PLAIN == type &&
( ( TIMEOUT == kill) ||
(SUSPEND_TIMEOUT_RESUME == kill) ||
(SUSPEND_TIMEOUT_KILL == kill) ) )
continue;
 
if ( (
#ifndef CYGPKG_UITRON_SEMAS_CREATE_DELETE
(SEMGET == wait) ||
#endif
#ifndef CYGPKG_UITRON_FLAGS_CREATE_DELETE
(FLAGWAIT == wait) ||
#endif
#ifndef CYGPKG_UITRON_MBOXES_CREATE_DELETE
(MSGGET == wait) ||
#endif
#ifndef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
(MEMFIXEDGET == wait) ||
#endif
#ifndef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
(MEMVARGET == wait) ||
#endif
(SLEEP == wait) ||
(DELAY == wait)
) &&
((DELETE == kill) ||
(SUSPEND_DELETE_RESUME == kill) ||
(SUSPEND_DELETE_KILL == kill)) )
continue;
 
 
CYG_TEST_INFO( makemsg( "T1: ", wait, type, kill ) );
 
intercom = 0;
 
// prepare the synchronization objects
// (actually, just empty the mempools)
do_prep( wait );
 
// start task 2 at a higher priority than myself
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 2, task2arg( wait, type, kill ) );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
// task 2 should run now, until it waits.
 
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_WAI == rtsk.tskstat, "bad tskstat" );
CYG_TEST_CHECK( 5 == rtsk.tskpri, "bad tskpri" );
 
switch ( kill ) {
case SIGNAL:
// signal the task appropriately
do_signal( wait );
// it should now have run to completion
break;
case TIMEOUT:
// wait for the timeout to occur
ercd = dly_tsk( T1_WAIT );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
// it should now have run to completion
break;
case RELEASE:
// hit the task with a release-wait
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
// it should now have run to completion
break;
case DELETE:
// delete the object appropriately
do_delete( wait );
// it should now have run to completion
break;
case KILL:
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
case SUSPEND_SIGNAL_RESUME:
// suspend the task
do_suspend();
// signal the task appropriately
do_signal( wait );
// resume the task
do_resume();
// it should now have run to completion
break;
case SUSPEND_TIMEOUT_RESUME:
// suspend the task
do_suspend();
// wait for the timeout to occur
ercd = dly_tsk( T1_WAIT );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
// resume the task
do_resume();
// it should now have run to completion
break;
case SUSPEND_RELEASE_RESUME:
// suspend the task
do_suspend();
// hit the task with a release-wait
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
// resume the task
do_resume();
// it should now have run to completion
break;
case SUSPEND_DELETE_RESUME:
// suspend the task
do_suspend();
// delete the object appropriately
do_delete( wait );
// resume the task
do_resume();
// it should now have run to completion
break;
case SUSPEND_KILL:
// suspend the task
do_suspend();
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
case SUSPEND_SIGNAL_KILL:
// suspend the task
do_suspend();
// signal the task appropriately
do_signal( wait );
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
case SUSPEND_TIMEOUT_KILL:
// suspend the task
do_suspend();
// wait for the timeout to occur
ercd = dly_tsk( T1_WAIT );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
case SUSPEND_RELEASE_KILL:
// suspend the task
do_suspend();
// hit the task with a release-wait
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
case SUSPEND_DELETE_KILL:
// suspend the task
do_suspend();
// delete the object appropriately
do_delete( wait );
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
// task 2 should be dormant now, however it got there
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_DMT == rtsk.tskstat, "bad tskstat" );
 
if ( (SUSPEND_SIGNAL_KILL == kill) &&
((MEMFIXEDGET == wait) || (MEMVARGET == wait)) ) {
// it was a killed successful memory alloc, so we have
// lost the pointer to memory allocated; there is an
// implicit storeleak problem when the task trying
// to allocate is signalled then killed.
// Recreate the pointer from an old version:
CYG_TEST_CHECK( NULL == t2vp, "t2vp WAS allocated!" );
t2vp = t2vp_backup;
}
 
switch ( kill ) {
case KILL:
case SUSPEND_KILL:
case SUSPEND_SIGNAL_KILL:
case SUSPEND_TIMEOUT_KILL:
case SUSPEND_RELEASE_KILL:
case SUSPEND_DELETE_KILL:
// if task 2 was killed, expect only one increment
CYG_TEST_CHECK( 1 == intercom, "intercom bad value !1" );
break;
default:
// otherwise expect two increments
CYG_TEST_CHECK( 2 == intercom, "intercom bad value !2" );
break;
}
// tidy up or recreate the synchronization objects
if ( (DELETE == kill) ||
(SUSPEND_DELETE_RESUME == kill) ||
(SUSPEND_DELETE_KILL == kill) )
do_recreate( wait );
else
do_tidyup( wait );
}
}
}
CYG_TEST_PASS("synchronization interaction tests");
 
// all done
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
WAITOP wait;
WAITTYPE waittype;
KILLOP kill;
 
decodearg( arg, &wait, &waittype, &kill );
 
// CYG_TEST_INFO( makemsg( " 2: ", wait, waittype, kill ) );
 
intercom++;
ercd = do_wait( wait, waittype );
intercom++;
 
switch ( kill ) {
case SIGNAL:
case SUSPEND_SIGNAL_RESUME:
// we expect to have been signalled correctly
CYG_TEST_CHECK( E_OK == ercd, "T2 wait bad ercd" );
// here we know that the op completed OK
if ( (MEMFIXEDGET == wait) || (MEMVARGET == wait) ) {
// it was a successful memory alloc of whichever type,
// so we can save away a copy of t2vp for working round an
// implicit storeleak problem when the task trying to allocate
// is signalled then killed:
CYG_TEST_CHECK( NULL != t2vp, "No t2vp allocated!" );
t2vp_backup = t2vp;
}
break;
case TIMEOUT:
case SUSPEND_TIMEOUT_RESUME:
// we expect to have timed out - if it's a timeout op.
CYG_TEST_CHECK( E_TMOUT == ercd, "T2 timeout bad ercd, !E_TMOUT" );
break;
case RELEASE:
case SUSPEND_RELEASE_RESUME:
// we expect to have suffered a release wait.
CYG_TEST_CHECK( E_RLWAI == ercd, "T2 release bad ercd, !E_RLWAI" );
break;
case DELETE:
case SUSPEND_DELETE_RESUME:
// we expect to be told the object is gone
CYG_TEST_CHECK( E_DLT == ercd, "T2 release bad ercd, !E_DLT" );
break;
case KILL:
case SUSPEND_KILL:
case SUSPEND_SIGNAL_KILL:
case SUSPEND_TIMEOUT_KILL:
case SUSPEND_RELEASE_KILL:
case SUSPEND_DELETE_KILL:
// we expect to have been killed here, ie. this won't execute!
CYG_TEST_FAIL( "Task 2 ran to completion!" );
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF test7.c
/v2_0/tests/test8.c
0,0 → 1,393
//===========================================================================
//
// test8.c
//
// uITRON "C" test program eight
//
//===========================================================================
//####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-10-12
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
volatile int intercount = 0;
INT scratch;
 
void newtask( unsigned int arg );
void task2( unsigned int arg );
void task3( unsigned int arg );
void task4( unsigned int arg );
 
T_CTSK t_ctsk = { NULL, 0, (FP)&newtask, 1, CYGNUM_UITRON_STACK_SIZE };
T_RTSK t_rtsk;
 
void task1( unsigned int arg )
{
ER ercd;
 
CYG_TEST_INFO( "Task 1 running" );
 
// change us to prio 3 for flexibility
ercd = chg_pri( 0, 3 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
 
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
// first, check that we can delete a task:
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_tsk( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
ercd = del_tsk( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
ercd = cre_tsk( -6, &t_ctsk );
CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
ercd = cre_tsk( 99, &t_ctsk );
CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
ercd = cre_tsk( 2, &t_ctsk );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
// try a pre-existing object - ourselves!
ercd = cre_tsk( 1, &t_ctsk );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
// try deleting an active task
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 2, 22222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
// Task 2 is now ready-to-run, lower prio than us
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
// Task 2 is now sleeping
CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
// try deleting a running task - ourselves!
ercd = del_tsk( 1 );
CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
// terminate task 2; should then be OK to delete it
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
// and check it is deleted
ercd = sta_tsk( 2, 99 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
ercd = chg_pri( 2, 6 );
CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
ercd = sus_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
ercd = rsm_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
ercd = frsm_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
ercd = can_wup( &scratch, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
ercd = ref_tsk( &t_rtsk, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
// recreate task2, with the same function
t_ctsk.task = (FP)&task2;
t_ctsk.itskpri = 7;
ercd = cre_tsk( 2, &t_ctsk );
CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
ercd = ref_tsk( &t_rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
CYG_TEST_CHECK( TTS_DMT == t_rtsk.tskstat,
"Bad tskstat in new task2 !TTS_DMT" );
CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
// now start the task and do the same lot again...
ercd = cre_tsk( 2, &t_ctsk );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
// try deleting an active task
ercd = sta_tsk( 2, 22222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
// Task 2 is now ready-to-run, lower prio than us
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
// Task 2 is now sleeping
ercd = ref_tsk( &t_rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
CYG_TEST_CHECK( TTS_WAI == t_rtsk.tskstat,
"Bad tskstat in new task2 !TTS_WAI" );
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
// up its priority
ercd = chg_pri( 2, 1 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
// awaken task 2; it will then exit-and-delete itself:
CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
// and check it is deleted
ercd = sta_tsk( 2, 99 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
ercd = chg_pri( 2, 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
ercd = sus_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
ercd = rsm_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
ercd = frsm_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
ercd = can_wup( &scratch, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
ercd = ref_tsk( &t_rtsk, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_tsk( 2, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_tsk bad ercd !E_PAR" );
#endif
ercd = cre_tsk( 2, NADR );
CYG_TEST_CHECK( E_PAR == ercd, "cre_tsk bad ercd !E_PAR" );
t_ctsk.stksz = 0x40000000;
ercd = cre_tsk( 2, &t_ctsk );
CYG_TEST_CHECK( E_NOMEM == ercd, "cre_tsk bad ercd !E_NOMEM" );
t_ctsk.stksz = CYGNUM_UITRON_STACK_SIZE;
CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
#endif // we can test bad param error returns
 
ercd = del_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
t_ctsk.task = (FP)&task4;
t_ctsk.itskpri = 9;
ercd = cre_tsk( 3, &t_ctsk );
CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
// check we can delete it again immediately
ercd = del_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
ercd = ref_tsk( &t_rtsk, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
t_ctsk.task = (FP)&newtask;
t_ctsk.itskpri = 1;
ercd = cre_tsk( 3, &t_ctsk );
CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
ercd = sta_tsk( 3, 999 );
CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
// it should have run now, and exited
CYG_TEST_CHECK( 5 == intercount, "bad intercount !5" );
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
// and check that it will just run again...
ercd = sta_tsk( 3, 999 );
CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
// it should have run now, and exited
CYG_TEST_CHECK( 7 == intercount, "bad intercount !7" );
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
// all done.
 
CYG_TEST_PASS("create/delete tasks");
 
// all done
CYG_TEST_EXIT( "All done" );
#else // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
CYG_TEST_NA( "Tasks do not have create/delete enabled" );
#endif // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
ext_tsk();
}
 
 
 
void newtask( unsigned int arg )
{
ER ercd;
int i;
CYG_TEST_INFO( "Newtask running" );
CYG_TEST_CHECK( 999 == arg, "Bad arg to newtask() !999" );
ercd = get_tid( &i );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 3 == i, "tid not 3" );
intercount++;
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
intercount++;
// and just return
}
 
void task2( unsigned int arg )
{
ER ercd;
int i;
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &i );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == i, "tid not 2" );
if ( 22222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 22222" );
 
intercount++;
 
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
 
intercount++;
 
exd_tsk(); // if we are not killed first
 
intercount++; // shouldn't happen
}
 
void task3( unsigned int arg )
{
CYG_TEST_FAIL( "How come I'm being run?" );
}
 
void task4( unsigned int arg )
{
CYG_TEST_FAIL( "How come I'm being run?" );
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF test8.c
/v2_0/tests/test9.c
0,0 → 1,489
//===========================================================================
//
// test9.c
//
// uITRON "C" test program nine
//
//===========================================================================
//####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-10-16
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough fixed memory pools */ \
defined( CYGPKG_UITRON_MEMPOOLFIXED ) && \
(CYGNUM_UITRON_MEMPOOLFIXED >= 3) && \
(CYGNUM_UITRON_MEMPOOLFIXED < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3 ) && \
\
/* test configuration for enough variable mempools */ \
defined( CYGPKG_UITRON_MEMPOOLVAR ) && \
(CYGNUM_UITRON_MEMPOOLVAR >= 3) && \
(CYGNUM_UITRON_MEMPOOLVAR < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
VP vp;
 
T_CMPL t_cmpl = { NULL, 0, 1000 };
T_RMPL t_rmpl;
T_CMPF t_cmpf = { NULL, 0, 10, 100 };
T_RMPF t_rmpf;
 
 
void task1( unsigned int arg )
{
ER ercd;
int tests = 0;
 
CYG_TEST_INFO( "Task 1 running" );
 
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 2, 22222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
tests++;
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_mpf( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_mpf bad ercd !E_ID" );
ercd = del_mpf( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_mpf bad ercd !E_ID" );
ercd = cre_mpf( -6, &t_cmpf );
CYG_TEST_CHECK( E_ID == ercd, "cre_mpf bad ercd !E_ID" );
ercd = cre_mpf( 99, &t_cmpf );
CYG_TEST_CHECK( E_ID == ercd, "cre_mpf bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
// [first get a valid block from it for the freeing test later]
ercd = pget_blf( &vp, 3 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
ercd = cre_mpf( 3, &t_cmpf );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_mpf bad ercd !E_OBJ" );
// delete it so we can play
ercd = del_mpf( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
// check it is deleted
ercd = rel_blf( 3, vp ); // vp did come from this pool
CYG_TEST_CHECK( E_NOEXS == ercd, "rel_blf bad ercd !E_NOEXS" );
ercd = pget_blf( &vp, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
ercd = tget_blf( &vp, 3, 10 );
CYG_TEST_CHECK( E_NOEXS == ercd, "tget_blf bad ercd !E_NOEXS" );
ercd = get_blf( &vp, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
ercd = ref_mpf( &t_rmpf, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mpf bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_mpf( 3, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_mpf bad ercd !E_PAR" );
#endif
ercd = cre_mpf( 3, NADR );
CYG_TEST_CHECK( E_PAR == ercd, "cre_mpf bad ercd !E_PAR" );
t_cmpf.mpfatr = 0xfff;
ercd = cre_mpf( 3, &t_cmpf );
CYG_TEST_CHECK( E_RSATR == ercd, "cre_mpf bad ercd !E_RSATR" );
#endif // we can test bad param error returns
t_cmpf.mpfatr = 0;
t_cmpf.mpfcnt = 10000;
t_cmpf.blfsz = 100;
ercd = cre_mpf( 3, &t_cmpf );
CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpf bad ercd" );
t_cmpf.mpfcnt = 100;
t_cmpf.blfsz = 100000;
ercd = cre_mpf( 3, &t_cmpf );
CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpf bad ercd" );
// now create it well
t_cmpf.mpfatr = 0;
t_cmpf.mpfcnt = 10;
t_cmpf.blfsz = 100;
ercd = cre_mpf( 3, &t_cmpf );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
// and check we can use it
ercd = pget_blf( &vp, 3 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
ercd = tget_blf( &vp, 3, 10 );
CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
ercd = get_blf( &vp, 3 );
CYG_TEST_CHECK( E_OK == ercd, "get_blf bad ercd" );
ercd = rel_blf( 3, vp ); // vp did come from new pool
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
ercd = rel_blf( 3, vp ); // vp already freed
CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
ercd = ref_mpf( &t_rmpf, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
 
// In order to wait on the pools, we must first consume all they have:
while ( E_OK == (ercd = pget_blf( &vp, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
while ( E_OK == (ercd = tget_blf( &vp, 2, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = get_blf( &vp, 1 );
CYG_TEST_CHECK( E_DLT == ercd, "get_blf bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = tget_blf( &vp, 2, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "tget_blf bad ercd !E_DLT" );
// check they are deleted
ercd = get_blf( &vp, 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
ercd = pget_blf( &vp, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
 
// re-create and do it again
t_cmpf.mpfcnt = 90;
t_cmpf.blfsz = 20;
ercd = cre_mpf( 1, &t_cmpf );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
t_cmpf.mpfcnt = 5;
t_cmpf.blfsz = 200;
ercd = cre_mpf( 2, &t_cmpf );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
 
// In order to wait on the pools, we must first consume all they have:
while ( E_OK == (ercd = pget_blf( &vp, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
while ( E_OK == (ercd = tget_blf( &vp, 2, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = get_blf( &vp, 1 );
CYG_TEST_CHECK( E_DLT == ercd, "get_blf bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = tget_blf( &vp, 2, 10 );
CYG_TEST_CHECK( E_DLT == ercd, "tget_blf bad ercd !E_DLT" );
// check they are deleted
ercd = tget_blf( &vp, 1, 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
ercd = get_blf( &vp, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
 
CYG_TEST_PASS("create/delete fixed mempools");
#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
 
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
tests++;
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_mpl( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_mpl bad ercd !E_ID" );
ercd = del_mpl( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_mpl bad ercd !E_ID" );
ercd = cre_mpl( -6, &t_cmpl );
CYG_TEST_CHECK( E_ID == ercd, "cre_mpl bad ercd !E_ID" );
ercd = cre_mpl( 99, &t_cmpl );
CYG_TEST_CHECK( E_ID == ercd, "cre_mpl bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
// [first get a valid block from it for the freeing test later]
ercd = pget_blk( &vp, 3, 100 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
ercd = cre_mpl( 3, &t_cmpl );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_mpl bad ercd !E_OBJ" );
// delete it so we can play
ercd = del_mpl( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
// check it is deleted
ercd = rel_blk( 3, vp ); // vp did come from this pool
CYG_TEST_CHECK( E_NOEXS == ercd, "rel_blk bad ercd !E_NOEXS" );
ercd = pget_blk( &vp, 3, 100 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
ercd = tget_blk( &vp, 3, 100, 10 );
CYG_TEST_CHECK( E_NOEXS == ercd, "tget_blk bad ercd !E_NOEXS" );
ercd = get_blk( &vp, 3, 100 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
ercd = ref_mpl( &t_rmpl, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mpl bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_mpl( 3, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_mpl bad ercd !E_PAR" );
#endif
ercd = cre_mpl( 3, NADR );
CYG_TEST_CHECK( E_PAR == ercd, "cre_mpl bad ercd !E_PAR" );
t_cmpl.mplatr = 0xfff;
ercd = cre_mpl( 3, &t_cmpl );
CYG_TEST_CHECK( E_RSATR == ercd, "cre_mpl bad ercd !E_RSATR" );
#endif // we can test bad param error returns
t_cmpl.mplatr = 0;
t_cmpl.mplsz = 100000000;
ercd = cre_mpl( 3, &t_cmpl );
CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpl bad ercd" );
// now create it well
t_cmpl.mplatr = 0;
t_cmpl.mplsz = 1000;
ercd = cre_mpl( 3, &t_cmpl );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
// and check we can use it
ercd = pget_blk( &vp, 3, 100 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
ercd = pget_blk( &vp, 3, 100000000 ); // way too large
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
ercd = tget_blk( &vp, 3, 100, 10 );
CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
ercd = get_blk( &vp, 3, 100 );
CYG_TEST_CHECK( E_OK == ercd, "get_blk bad ercd" );
ercd = rel_blk( 3, vp ); // vp did come from new pool
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
ercd = rel_blk( 3, vp ); // vp already freed
CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
ercd = ref_mpl( &t_rmpl, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
 
// In order to wait on the pools, we must first consume all they have:
while ( E_OK == (ercd = pget_blk( &vp, 1, 100 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
while ( E_OK == (ercd = tget_blk( &vp, 2, 100, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = get_blk( &vp, 1, 200 );
CYG_TEST_CHECK( E_DLT == ercd, "get_blk bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = tget_blk( &vp, 2, 100, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "tget_blk bad ercd !E_DLT" );
// check they are deleted
ercd = get_blk( &vp, 1, 200 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
ercd = pget_blk( &vp, 2, 20 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
 
// re-create and do it again
ercd = cre_mpl( 1, &t_cmpl );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
ercd = cre_mpl( 2, &t_cmpl );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
 
// In order to wait on the pools, we must first consume all they have:
while ( E_OK == (ercd = pget_blk( &vp, 1, 20 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
while ( E_OK == (ercd = tget_blk( &vp, 2, 400, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = get_blk( &vp, 1, 200 );
CYG_TEST_CHECK( E_DLT == ercd, "get_blk bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = tget_blk( &vp, 2, 500, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "tget_blk bad ercd !E_DLT" );
// check they are deleted
ercd = tget_blk( &vp, 1, 200, 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
ercd = get_blk( &vp, 2, 20 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
 
CYG_TEST_PASS("create/delete variable mempools");
#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
 
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
ercd = dly_tsk( 5 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
// all done
if ( 0 == tests ) {
CYG_TEST_NA( "No objects have create/delete enabled" );
}
else {
CYG_TEST_EXIT( "All done" );
}
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
int i;
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &i );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == i, "tid not 2" );
if ( 22222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 22222" );
 
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
 
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
ercd = del_mpf( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpf( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpf( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpf( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
 
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
ercd = del_mpl( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpl( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpl( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpl( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
 
// we expect task2 to be killed here
CYG_TEST_FAIL( "Task 2 ran to completion!" );
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF test9.c
/v2_0/tests/testcx2.cxx
0,0 → 1,937
//===========================================================================
//
// testcx2.cxx
//
// uITRON "C++" test program two
//
//===========================================================================
//####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-03-13
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* test configuration for enough flag objects */ \
defined( CYGPKG_UITRON_FLAGS ) && \
(CYGNUM_UITRON_FLAGS >= 3) && \
(CYGNUM_UITRON_FLAGS < 90) && \
( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) || \
CYGNUM_UITRON_FLAGS_INITIALLY >= 3 ) && \
\
/* test configuration for enough message boxes */ \
defined( CYGPKG_UITRON_MBOXES ) && \
(CYGNUM_UITRON_MBOXES >= 3) && \
(CYGNUM_UITRON_MBOXES < 90) && \
( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) || \
CYGNUM_UITRON_MBOXES_INITIALLY >= 3 ) && \
\
/* test configuration for enough fixed memory pools */ \
defined( CYGPKG_UITRON_MEMPOOLFIXED ) && \
(CYGNUM_UITRON_MEMPOOLFIXED >= 3) && \
(CYGNUM_UITRON_MEMPOOLFIXED < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3 ) && \
\
/* test configuration for enough variable mempools */ \
defined( CYGPKG_UITRON_MEMPOOLVAR ) && \
(CYGNUM_UITRON_MEMPOOLVAR >= 3) && \
(CYGNUM_UITRON_MEMPOOLVAR < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
int intercom = 0;
int intercount = 0;
INT scratch = 0;
 
extern "C" {
void task1( unsigned int arg );
void task2( unsigned int arg );
void task3( unsigned int arg );
void task4( unsigned int arg );
}
 
void task1( unsigned int arg )
{
ER ercd;
 
T_RSEM sem_info;
T_RFLG flg_info;
T_RMBX mbx_info;
T_RMPF mpf_info;
T_RMPL mpl_info;
UINT flagptn;
static char foo[] = "Test message";
T_MSG *msgptr = (T_MSG *)foo;
T_MSG *rxptr = NULL;
VP blfptr = (VP)foo;
VP blkptr = (VP)foo;
 
int delay = 10;
if (cyg_test_is_simulator)
delay = 3;
 
CYG_TEST_INFO( "Task 1 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
// start a lower prio task to interact with
intercom = 1;
ercd = sta_tsk( 2, 222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
// Semaphores; all the illegal argument combinations first
CYG_TEST_INFO( "Testing semaphore ops" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = sig_sem( -6 );
CYG_TEST_CHECK( E_ID == ercd, "sig_sem bad ercd !E_ID" );
ercd = sig_sem( 99 );
CYG_TEST_CHECK( E_ID == ercd, "sig_sem bad ercd !E_ID" );
ercd = wai_sem( -6 );
CYG_TEST_CHECK( E_ID == ercd, "wai_sem bad ercd !E_ID" );
ercd = wai_sem( 99 );
CYG_TEST_CHECK( E_ID == ercd, "wai_sem bad ercd !E_ID" );
ercd = preq_sem( -6 );
CYG_TEST_CHECK( E_ID == ercd, "preq_sem bad ercd !E_ID" );
ercd = preq_sem( 99 );
CYG_TEST_CHECK( E_ID == ercd, "preq_sem bad ercd !E_ID" );
ercd = twai_sem( -6, delay );
CYG_TEST_CHECK( E_ID == ercd, "twai_sem bad ercd !E_ID" );
ercd = twai_sem( 99, delay );
CYG_TEST_CHECK( E_ID == ercd, "twai_sem bad ercd !E_ID" );
ercd = twai_sem( 2, -999 );
CYG_TEST_CHECK( E_PAR == ercd, "twai_sem bad ercd !E_PAR" );
ercd = ref_sem( &sem_info, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_sem bad ercd !E_ID" );
ercd = ref_sem( &sem_info, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_sem bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_sem( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_sem bad ercd !E_PAR" );
#endif
CYG_TEST_PASS( "bad calls: sig_sem, [t]wai_sem, preq_sem, ref_sem" );
#endif // we can test bad param error returns
 
// check the waitable functions versus dispatch disable
ercd = preq_sem( 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
ercd = twai_sem( 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
ercd = twai_sem( 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = wai_sem( 2 );
CYG_TEST_CHECK( E_CTX == ercd, "wai_sem bad ercd !E_CTX" );
ercd = twai_sem( 2, delay );
CYG_TEST_CHECK( E_CTX == ercd, "twai_sem bad ercd !E_CTX" );
ercd = twai_sem( 2, TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "twai_sem(FEVR) bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = twai_sem( 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
ercd = preq_sem( 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = preq_sem( 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
ercd = twai_sem( 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
ercd = twai_sem( 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
CYG_TEST_PASS( "bad calls: wai_sem, twai_sem with dis_dsp" );
 
// check ref_sem with various states
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
ercd = preq_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 2 == sem_info.semcnt, "semcnt should be 2" );
ercd = wai_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
ercd = twai_sem( 2, delay );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
intercom = 0;
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
intercom = 1;
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 != sem_info.wtsk, "sem.wtsk should be non0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be non0" );
#if 1
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
#else // old, non-uITRON semantics
CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
#endif
ercd = dly_tsk( delay ); // let task 2 pick up the signal
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_sem( &sem_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
CYG_TEST_PASS( "good calls: sig_sem, [t]wai,preq_sem with ref_sem" );
 
// Flags; all the illegal argument combinations first
CYG_TEST_INFO( "Testing flag ops" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = set_flg( -6, 1 );
CYG_TEST_CHECK( E_ID == ercd, "set_flg bad ercd !E_ID" );
ercd = set_flg( 99, 1 );
CYG_TEST_CHECK( E_ID == ercd, "set_flg bad ercd !E_ID" );
ercd = clr_flg( -6, 1 );
CYG_TEST_CHECK( E_ID == ercd, "clr_flg bad ercd !E_ID" );
ercd = clr_flg( 99, 1 );
CYG_TEST_CHECK( E_ID == ercd, "sig_flg bad ercd !E_ID" );
ercd = wai_flg( &flagptn, -6, 7, TWF_ANDW );
CYG_TEST_CHECK( E_ID == ercd, "wai_flg bad ercd !E_ID" );
ercd = wai_flg( &flagptn, 99, 7, TWF_ANDW );
CYG_TEST_CHECK( E_ID == ercd, "wai_flg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = wai_flg( NULL, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
#endif
ercd = wai_flg( &flagptn, 2, 7, 34657 );
CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
ercd = wai_flg( &flagptn, 2, 0, TWF_ANDW );
CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
ercd = pol_flg( &flagptn, -6, 7, TWF_ANDW );
CYG_TEST_CHECK( E_ID == ercd, "pol_flg bad ercd !E_ID" );
ercd = pol_flg( &flagptn, 99, 7, TWF_ANDW );
CYG_TEST_CHECK( E_ID == ercd, "pol_flg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = pol_flg( NULL, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
#endif
ercd = pol_flg( &flagptn, 2, 7, 34657 );
CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
ercd = pol_flg( &flagptn, 2, 0, TWF_ANDW );
CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
ercd = twai_flg( &flagptn, -6, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_ID == ercd, "twai_flg bad ercd !E_ID" );
ercd = twai_flg( &flagptn, 99, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_ID == ercd, "twai_flg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = twai_flg( NULL, 2, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
#endif
ercd = twai_flg( &flagptn, 2, 7, 34657, delay );
CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, -999 );
CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
ercd = twai_flg( &flagptn, 2, 0, TWF_ANDW, delay );
CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
ercd = ref_flg( &flg_info, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_flg bad ercd !E_ID" );
ercd = ref_flg( &flg_info, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_flg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_flg( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_flg bad ercd !E_PAR" );
#endif
CYG_TEST_PASS( "bad calls: set_flg, clr_flg, [t]wai,pol_flg, ref_flg" );
#endif // we can test bad param error returns
 
// check the waitable functions versus dispatch disable
ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = wai_flg( &flagptn, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_CTX == ercd, "wai_flg bad ercd !E_CTX" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_CTX == ercd, "twai_flg bad ercd !E_CTX" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "twai_flg(FEVR) bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
CYG_TEST_PASS( "bad calls: wai_flg, twai_flg with dis_dsp" );
 
// check ref_flg with various states
ercd = ref_flg( &flg_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 == flg_info.wtsk, "flg.wtsk should be non0" );
CYG_TEST_CHECK( 0 == flg_info.flgptn, "flgptn should be 0" );
intercom = 0;
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
intercom = 1;
ercd = ref_flg( &flg_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
CYG_TEST_CHECK( 0 == flg_info.flgptn, "flgptn should be 0" );
ercd = set_flg( 2, 0x5555 );
CYG_TEST_CHECK( E_OK == ercd, "sig_flg bad ercd" );
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_flg( &flg_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
CYG_TEST_CHECK( 0x5555 == flg_info.flgptn, "flgptn should be 0x5555" );
ercd = clr_flg( 2, 0xF0F0 );
CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd" );
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_flg( &flg_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
CYG_TEST_CHECK( 0x5050 == flg_info.flgptn, "flgptn should be 0x5050" );
ercd = set_flg( 2, 0xFFFF );
CYG_TEST_CHECK( E_OK == ercd, "sig_flg bad ercd" );
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_flg( &flg_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 == flg_info.wtsk, "flg.wtsk should be 0" );
CYG_TEST_CHECK( 0xFFFF == flg_info.flgptn, "flgptn should be 0xFFFF" );
CYG_TEST_PASS( "good calls: clr_flg, set_flg, wai_flg with ref_flg" );
 
// Mailboxes; all the illegal argument combinations first
CYG_TEST_INFO( "Testing mailbox ops" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = snd_msg( -6, msgptr );
CYG_TEST_CHECK( E_ID == ercd, "snd_msg bad ercd !E_ID" );
ercd = snd_msg( 99, msgptr );
CYG_TEST_CHECK( E_ID == ercd, "snd_msg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = snd_msg( 2, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "snd_msg bad ercd !E_PAR" );
#endif
ercd = rcv_msg( &rxptr, -6 );
CYG_TEST_CHECK( E_ID == ercd, "rcv_msg bad ercd !E_ID" );
ercd = rcv_msg( &rxptr, 99 );
CYG_TEST_CHECK( E_ID == ercd, "rcv_msg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = rcv_msg( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "rcv_msg bad ercd !E_PAR" );
#endif
ercd = prcv_msg( &rxptr, -6 );
CYG_TEST_CHECK( E_ID == ercd, "prcv_msg bad ercd !E_ID" );
ercd = prcv_msg( &rxptr, 99 );
CYG_TEST_CHECK( E_ID == ercd, "prcv_msg bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = prcv_msg( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "prcv_msg bad ercd !E_PAR" );
#endif
ercd = trcv_msg( &rxptr, -6, delay );
CYG_TEST_CHECK( E_ID == ercd, "trcv_msg bad ercd !E_ID" );
ercd = trcv_msg( &rxptr, 99, delay );
CYG_TEST_CHECK( E_ID == ercd, "trcv_msg bad ercd !E_ID" );
ercd = trcv_msg( &rxptr, 2, -999 );
CYG_TEST_CHECK( E_PAR == ercd, "trcv_msg bad ercd !E_PAR" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = trcv_msg( NULL, 2, delay );
CYG_TEST_CHECK( E_PAR == ercd, "trcv_msg bad ercd !E_PAR" );
#endif
ercd = ref_mbx( &mbx_info, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mbx bad ercd !E_ID" );
ercd = ref_mbx( &mbx_info, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mbx bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_mbx( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_mbx bad ercd !E_PAR" );
#endif
CYG_TEST_PASS( "bad calls: snd_msg, [pt]rcv_msg, ref_mbx" );
#endif // we can test bad param error returns
 
// check the waitable functions versus dispatch disable
ercd = prcv_msg( &rxptr, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
ercd = trcv_msg( &rxptr, 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
ercd = trcv_msg( &rxptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rcv_msg( &rxptr, 2 );
CYG_TEST_CHECK( E_CTX == ercd, "rcv_msg bad ercd !E_CTX" );
ercd = trcv_msg( &rxptr, 2, delay );
CYG_TEST_CHECK( E_CTX == ercd, "trcv_msg bad ercd !E_CTX" );
ercd = trcv_msg( &rxptr, 2, TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "trcv_msg(FEVR) bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = trcv_msg( &rxptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
ercd = prcv_msg( &rxptr, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = prcv_msg( &rxptr, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
ercd = trcv_msg( &rxptr, 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
ercd = trcv_msg( &rxptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
CYG_TEST_PASS( "bad calls: rcv_msg, trcv_msg with dis_dsp" );
 
// check ref_mbx with various states
ercd = ref_mbx( &mbx_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
intercom = 0;
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
intercom = 1;
ercd = ref_mbx( &mbx_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
CYG_TEST_CHECK( 0 != mbx_info.wtsk, "mbx.wtsk should be non0" );
CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
ercd = snd_msg( 2, msgptr );
CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
ercd = ref_mbx( &mbx_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
#if 1
CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
#else // old, non-uITRON semantics
CYG_TEST_CHECK( msgptr == mbx_info.pk_msg, "mbx peek should be msgptr" );
#endif
ercd = dly_tsk( delay );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_mbx( &mbx_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
// fill the message box, expect E_QOVR
for ( scratch = 0 ; scratch < 100 ; scratch++ ) {
if ( E_OK != ( ercd = snd_msg( 2, msgptr ) ) )
break;
}
CYG_TEST_CHECK( (100 == scratch) || (E_QOVR == ercd),
"snd_msg bad ercd !E_QOVR/E_OK" );
// empty the message box, expect the right number and E_TMOUT
for ( ; 1 ; scratch-- ) {
if ( E_OK != ( ercd = prcv_msg( &rxptr, 2 ) ) )
break;
}
CYG_TEST_CHECK( 0 == scratch, "rcv_msg count bad scratch!=0" );
CYG_TEST_CHECK( E_TMOUT == ercd, "rcv_msg bad ercd !E_TMOUT" );
 
CYG_TEST_PASS( "good calls: rcv_msg, snd_msg with ref_msg" );
 
// Fixed block memory pools: all the illegal argument combinations first
CYG_TEST_INFO( "Testing fixed block memory ops" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rel_blf( -6, blfptr );
CYG_TEST_CHECK( E_ID == ercd, "rel_blf bad ercd !E_ID" );
ercd = rel_blf( 99, blfptr );
CYG_TEST_CHECK( E_ID == ercd, "rel_blf bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = rel_blf( 2, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
#endif
#endif // we can test bad param error returns
ercd = rel_blf( 2, blfptr ); // it did not come from a mpf
CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blf( &blfptr, -6 );
CYG_TEST_CHECK( E_ID == ercd, "get_blf bad ercd !E_ID" );
ercd = get_blf( &blfptr, 99 );
CYG_TEST_CHECK( E_ID == ercd, "get_blf bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = get_blf( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "get_blf bad ercd !E_PAR" );
#endif
ercd = pget_blf( &blfptr, -6 );
CYG_TEST_CHECK( E_ID == ercd, "pget_blf bad ercd !E_ID" );
ercd = pget_blf( &blfptr, 99 );
CYG_TEST_CHECK( E_ID == ercd, "pget_blf bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = pget_blf( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "pget_blf bad ercd !E_PAR" );
#endif
ercd = tget_blf( &blfptr, -6, delay );
CYG_TEST_CHECK( E_ID == ercd, "tget_blf bad ercd !E_ID" );
ercd = tget_blf( &blfptr, 99, delay );
CYG_TEST_CHECK( E_ID == ercd, "tget_blf bad ercd !E_ID" );
ercd = tget_blf( &blfptr, 2, -999 );
CYG_TEST_CHECK( E_PAR == ercd, "tget_blf bad ercd !E_PAR" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = tget_blf( NULL, 2, delay );
CYG_TEST_CHECK( E_PAR == ercd, "tget_blf bad ercd !E_PAR" );
#endif
ercd = ref_mpf( &mpf_info, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mpf bad ercd !E_ID" );
ercd = ref_mpf( &mpf_info, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mpf bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_mpf( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_mpf bad ercd !E_PAR" );
#endif
CYG_TEST_PASS( "bad calls: rel_blf, [pt]get_blf, ref_mpf " );
#endif // we can test bad param error returns
 
// check the waitable functions versus dispatch disable
ercd = pget_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
ercd = rel_blf( 2, blfptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = rel_blf( 2, blfptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_CTX == ercd, "get_blf bad ercd !E_CTX" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blf bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = pget_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
ercd = rel_blf( 2, blfptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
ercd = rel_blf( 2, blfptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
// consume the whole thing then do it again, expecting E_TMOUT
while ( E_OK == (ercd = pget_blf( &blfptr, 2 ) ) )
continue;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
ercd = pget_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
ercd = tget_blf( &blfptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_CTX == ercd, "get_blf bad ercd !E_CTX" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blf bad ercd !E_CTX" );
ercd = tget_blf( &blfptr, 2, TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blf(FEVR) bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = tget_blf( &blfptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = pget_blf( &blfptr, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
ercd = tget_blf( &blfptr, 2, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
ercd = tget_blf( &blfptr, 2, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
CYG_TEST_PASS( "bad calls: rel_blf, [pt]get_blf with ena_dsp" );
 
// check ref_mpf with various states
ercd = ref_mpf( &mpf_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
intercom = 0;
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
intercom = 1;
ercd = ref_mpf( &mpf_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
CYG_TEST_CHECK( 0 != mpf_info.wtsk, "mpf.wtsk should be non0" );
CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
ercd = rel_blf( 2, blfptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
ercd = ref_mpf( &mpf_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
#if 1
CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
#else // old, non-uITRON semantics
CYG_TEST_CHECK( 0 != mpf_info.frbcnt, "mpf.frbcnt should be non0" );
#endif
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_mpf( &mpf_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
CYG_TEST_PASS( "good calls: rel_blf, get_blf with ref_mpf" );
 
// Variable block memory pools; illegal arguments
CYG_TEST_INFO( "Testing variable block memory ops" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rel_blk( -6, blkptr );
CYG_TEST_CHECK( E_ID == ercd, "rel_blk bad ercd !E_ID" );
ercd = rel_blk( 99, blkptr );
CYG_TEST_CHECK( E_ID == ercd, "rel_blk bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = rel_blk( 2, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
#endif
#endif // we can test bad param error returns
ercd = rel_blk( 2, blkptr ); // it did not come from a mpl
CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blk( &blkptr, -6, 100 );
CYG_TEST_CHECK( E_ID == ercd, "get_blk bad ercd !E_ID" );
ercd = get_blk( &blkptr, 99, 100 );
CYG_TEST_CHECK( E_ID == ercd, "get_blk bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = get_blk( NULL, 2, 100 );
CYG_TEST_CHECK( E_PAR == ercd, "get_blk bad ercd !E_PAR" );
#endif
ercd = pget_blk( &blkptr, -6, 100 );
CYG_TEST_CHECK( E_ID == ercd, "pget_blk bad ercd !E_ID" );
ercd = pget_blk( &blkptr, 99, 100 );
CYG_TEST_CHECK( E_ID == ercd, "pget_blk bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = pget_blk( NULL, 2, 100 );
CYG_TEST_CHECK( E_PAR == ercd, "pget_blk bad ercd !E_PAR" );
#endif
ercd = tget_blk( &blkptr, -6, 100, delay );
CYG_TEST_CHECK( E_ID == ercd, "tget_blk bad ercd !E_ID" );
ercd = tget_blk( &blkptr, 99, 100, delay );
CYG_TEST_CHECK( E_ID == ercd, "tget_blk bad ercd !E_ID" );
ercd = tget_blk( &blkptr, 2, 100, -999 );
CYG_TEST_CHECK( E_PAR == ercd, "tget_blk bad ercd !E_PAR" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = tget_blk( NULL, 2, 100, delay );
CYG_TEST_CHECK( E_PAR == ercd, "tget_blk bad ercd !E_PAR" );
#endif
ercd = ref_mpl( &mpl_info, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mpl bad ercd !E_ID" );
ercd = ref_mpl( &mpl_info, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_mpl bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_mpl( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_mpl bad ercd !E_PAR" );
#endif
CYG_TEST_PASS( "bad calls: rel_blk, [pt]get_blk, ref_mpl " );
#endif // we can test bad param error returns
 
// check the waitable functions versus dispatch disable
ercd = pget_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
ercd = rel_blk( 2, blkptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = rel_blk( 2, blkptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_CTX == ercd, "get_blk bad ercd !E_CTX" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blk bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = pget_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
ercd = rel_blk( 2, blkptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
ercd = rel_blk( 2, blkptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
// consume the whole thing then do it again, expecting E_TMOUT
while ( E_OK == (ercd = pget_blk( &blkptr, 2, 100 ) ) )
continue;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
ercd = pget_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = get_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_CTX == ercd, "get_blk bad ercd !E_CTX" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blk bad ercd !E_CTX" );
ercd = tget_blk( &blkptr, 2, 100, TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "tget_blk(FEVR) bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = pget_blk( &blkptr, 2, 100 );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
ercd = tget_blk( &blkptr, 2, 100, delay );
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
CYG_TEST_PASS( "bad calls: rel_blk, [pt]get_blk with ena_dsp" );
 
// check ref_mpl with various states
ercd = ref_mpl( &mpl_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
CYG_TEST_CHECK( mpl_info.maxsz <= mpl_info.frsz,
"mpl.maxsz not < mpl.frsz" );
intercom = 0;
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
intercom = 1;
ercd = ref_mpl( &mpl_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
CYG_TEST_CHECK( 0 != mpl_info.wtsk, "mpl.wtsk should be non0" );
ercd = rel_blk( 2, blkptr );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
ercd = ref_mpl( &mpl_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
ercd = dly_tsk( delay ); // let task 2 start waiting
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_mpl( &mpl_info, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
CYG_TEST_PASS( "good calls: rel_blk, get_blk with ref_mpl" );
 
// all done
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
T_MSG *msgp = NULL;
UINT flgval = 0;
VP blfp = NULL;
VP blkp = NULL;
 
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
if ( 222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 222" );
 
while ( intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
}
ercd = wai_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
while ( intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
}
ercd = wai_flg( &flgval, 2, 99, TWF_ANDW );
CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
CYG_TEST_CHECK( 99 == (99 & flgval), "flg value no good" );
while ( intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
}
ercd = rcv_msg( &msgp, 2 );
CYG_TEST_CHECK( E_OK == ercd, "rcv_msg bad ercd" );
CYG_TEST_CHECK( NULL != msgp, "no msg received" );
CYG_TEST_CHECK( NADR != msgp, "no msg received" );
while ( intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
}
ercd = get_blf( &blfp, 2 );
CYG_TEST_CHECK( E_OK == ercd, "get_blf bad ercd" );
CYG_TEST_CHECK( NULL != blfp, "no blf allocated" );
CYG_TEST_CHECK( NADR != blfp, "no blf allocated" );
while ( intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
}
ercd = get_blk( &blkp, 2, 100 );
CYG_TEST_CHECK( E_OK == ercd, "get_blk bad ercd" );
CYG_TEST_CHECK( NULL != blkp, "no blk allocated" );
CYG_TEST_CHECK( NADR != blkp, "no blk allocated" );
 
ext_tsk();
CYG_TEST_FAIL( "Task 2 failed to exit" );
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK "
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF testcx2.cxx
/v2_0/tests/testcx3.cxx
0,0 → 1,262
//===========================================================================
//
// testcx3.cxx
//
// uITRON "C++" test program three
//
//===========================================================================
//####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-03-13
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
int t2done = 0;
int t3done = 0;
int t4done = 0;
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
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 );
}
 
void task1( unsigned int arg )
{
ER ercd;
INT scratch;
 
CYG_TEST_INFO( "Task 1 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
// start lower prio tasks to interact with
ercd = sta_tsk( 2, 222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = sta_tsk( 3, 333 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = sta_tsk( 4, 444 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
 
// now start the test
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
CYG_TEST_INFO( "T1 awoken" );
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
CYG_TEST_INFO( "T1 signalled" );
// let the others complete, so we get the status back
ercd = dly_tsk( 50 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( t2done, "t2 not done" );
CYG_TEST_CHECK( t3done, "t3 not done" );
CYG_TEST_CHECK( t4done, "t4 not done" );
 
CYG_TEST_PASS( "Immediate-dispatch producer/consumer test OK" );
 
// all done
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
INT scratch;
 
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
if ( 222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 222" );
 
// now start the test
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
CYG_TEST_INFO( "T2 awoken" );
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = wup_tsk( 1 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
 
CYG_TEST_INFO( "T2 completing" );
t2done++;
 
ercd = slp_tsk();
CYG_TEST_FAIL( "Task 2 sleep came back" );
}
 
void task3( unsigned int arg )
{
ER ercd;
INT scratch;
 
CYG_TEST_INFO( "Task 3 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 3 == scratch, "tid not 3" );
if ( 333 != arg )
CYG_TEST_FAIL( "Task 3 arg not 333" );
 
// now start the test
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
CYG_TEST_INFO( "T3 awoken" );
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
CYG_TEST_INFO( "T3 completing" );
t3done++;
 
ercd = slp_tsk();
CYG_TEST_FAIL( "Task 3 sleep came back" );
}
 
void task4( unsigned int arg )
{
ER ercd;
INT scratch;
 
CYG_TEST_INFO( "Task 4 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 4 == scratch, "tid not 4" );
if ( 444 != arg )
CYG_TEST_FAIL( "Task 4 arg not 444" );
 
// now start the test
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
 
CYG_TEST_INFO( "T4 completing" );
t4done++;
 
ercd = slp_tsk();
CYG_TEST_FAIL( "Task 4 sleep came back" );
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF testcx3.cxx
/v2_0/tests/testcx4.cxx
0,0 → 1,406
//===========================================================================
//
// testcx4.cxx
//
// uITRON "C++" test program four
//
//===========================================================================
//####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): dsm
// Contributors: dsm
// Date: 1998-06-12
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough cyclic handlers */ \
defined( CYGPKG_UITRON_CYCLICS ) && \
(CYGNUM_UITRON_CYCLICS >= 3) && \
(CYGNUM_UITRON_CYCLICS < 90) && \
\
/* test configuration for enough alarm handlers */ \
defined( CYGPKG_UITRON_ALARMS ) && \
(CYGNUM_UITRON_ALARMS >= 3) && \
(CYGNUM_UITRON_ALARMS < 90) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
volatile int intercount = 0;
INT scratch;
 
void hand1(void)
{
CYG_TEST_INFO("Handler 1 called");
intercount++;
}
 
void hand2(void)
{
CYG_TEST_CHECK( 2 == intercount, "handler out of sync" );
CYG_TEST_INFO("Handler 2 called");
intercount++;
}
 
extern "C" {
void task1( unsigned int arg );
void task2( unsigned int arg );
void task3( unsigned int arg );
void task4( unsigned int arg );
}
 
void task1( unsigned int arg )
{
ER ercd;
 
T_DCYC dcyc;
T_DALM dalm;
T_RCYC rcyc;
T_RALM ralm;
 
unsigned int tm;
 
static char foo[] = "Test message";
VP info = (VP)foo;
 
// Increase times when running on HW since overhead of GDB packet
// acknowledgements may cause tests of timing to fail.
if (cyg_test_is_simulator)
tm = 1;
else
tm = 4;
 
CYG_TEST_INFO( "Task 1 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
 
dcyc.exinf = (VP)info;
dcyc.cycatr = TA_HLNG;
dcyc.cychdr = (FP)&hand1;
dcyc.cycact = TCY_INI; // bad
dcyc.cyctim = 2;
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = def_cyc(3, &dcyc);
CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
#endif // we can test bad param error returns
 
dcyc.cycact = TCY_OFF; // make good
dcyc.cyctim = 0; // bad
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = def_cyc(3, &dcyc);
CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
#endif // we can test bad param error returns
 
dcyc.cyctim = 1; // make good
 
ercd = def_cyc(3, &dcyc);
CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = def_cyc(-6, &dcyc);
CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
ercd = def_cyc(99, &dcyc);
CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
 
ercd = act_cyc(-6, TCY_OFF);
CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
ercd = act_cyc(99, TCY_OFF);
CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
ercd = act_cyc( 3, ~0);
CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
ercd = ref_cyc(&rcyc, -6);
CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
ercd = ref_cyc(&rcyc, 99);
CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_cyc(NULL, 3);
CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
#endif
#endif // we can test bad param error returns
 
ercd = def_cyc(3, (T_DCYC *)NADR);
CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_cyc bad ercd !E_NOEXS" );
#endif // we can test bad param error returns
 
CYG_TEST_PASS( "bad calls: def_cyc, act_cyc, ref_cyc" );
 
dalm.exinf = (VP)info;
dalm.almatr = TA_HLNG;
dalm.almhdr = (FP)&hand2;
dalm.tmmode = ~0; // bad
dalm.almtim = 20;
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = def_alm(3, &dalm);
CYG_TEST_CHECK( E_PAR == ercd, "def_alm bad ercd !E_PAR" );
#endif // we can test bad param error returns
 
dalm.tmmode = TTM_REL; // make good
dalm.almtim = 0; // bad
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = def_alm(3, &dalm);
CYG_TEST_CHECK( E_PAR == ercd, "def_alm bad ercd !E_PAR" );
#endif // we can test bad param error returns
 
dalm.almtim = 1000; // make good
 
ercd = def_alm(3, &dalm);
CYG_TEST_CHECK( E_OK == ercd, "def_alm bad ercd" );
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = ref_alm(&ralm, -6);
CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
ercd = ref_alm(&ralm, 99);
CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_alm(NULL, 3);
CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
#endif
 
#endif // we can test bad param error returns
ercd = def_alm(3, (T_DALM *)NADR);
CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = ref_alm(&ralm, 3);
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_cyc bad ercd !E_NOEXS" );
#endif // we can test bad param error returns
 
CYG_TEST_PASS( "bad calls: def_alm, act_alm, ref_alm" );
dcyc.exinf = (VP)info;
dcyc.cycatr = TA_HLNG;
dcyc.cychdr = (FP)&hand1;
dcyc.cycact = TCY_ON;
dcyc.cyctim = 50*tm;
ercd = def_cyc(3, &dcyc);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
ercd = act_cyc(3, TCY_OFF);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_OFF == rcyc.cycact, "rcyc.cycact should be TCY_OFF" );
ercd = act_cyc(3, TCY_ON);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc bad ercd" );
CYG_TEST_PASS("good calls: def_cyc, act_cyc, ref_cyc");
 
dalm.exinf = (VP)info;
dalm.almatr = TA_HLNG;
dalm.almhdr = (FP)&hand2;
dalm.tmmode = TTM_REL;
dalm.almtim = 120*tm;
 
ercd = def_alm(3, &dalm);
CYG_TEST_CHECK( E_OK == ercd, "def_alm bad ercd" );
ercd = ref_alm(&ralm, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_alm bad ercd" );
CYG_TEST_CHECK( info == ralm.exinf, "ralm.exinf should be info" );
CYG_TEST_CHECK( 115*tm < ralm.lfttim, "ralm.lfttim too small" );
CYG_TEST_CHECK( ralm.lfttim <= 120*tm, "ralm.lfttim too big" );
 
// Expect handlers to be called at approximate times
// time intercount
// tm*50 hand1 0
// tm*100 hand1 1
// tm*120 hand2 2
// tm*150 hand1 3
 
ercd = dly_tsk(160*tm);
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 4 == intercount, "handlers not both called" );
ercd = act_cyc(3, TCY_OFF);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc(off) bad ercd" );
 
ercd = dly_tsk(60*tm); // enough for at least one tick
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 4 == intercount, "cyclic not disabled" );
 
// approx time now 220, so we expect a cycle in about 30 ticks
ercd = act_cyc(3, TCY_ON);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 25*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 35*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
 
// now resynchronize with right now:
ercd = act_cyc(3, TCY_ON|TCY_INI);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
 
// wait a bit and check that time marches on, or even down
ercd = dly_tsk(10*tm);
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 35*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 45*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
 
// now turn it off and re-synch with right now:
ercd = act_cyc(3, TCY_OFF|TCY_INI);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
ercd = ref_cyc(&rcyc, 3);
CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
CYG_TEST_CHECK( TCY_OFF == rcyc.cycact, "rcyc.cycact should be TCY_OFF" );
 
ercd = act_cyc(3, TCY_OFF);
CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
 
CYG_TEST_PASS("good calls: def_cyc, act_cyc, ref_cyc, def_alm, ref_alm");
 
// all done
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF testcx4.cxx
/v2_0/tests/testcx5.cxx
0,0 → 1,363
//===========================================================================
//
// testcx5.cxx
//
// uITRON "C++" test program five
//
//===========================================================================
//####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): dsm
// Contributors: dsm
// Date: 1998-06-12
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* test configuration for enough flag objects */ \
defined( CYGPKG_UITRON_FLAGS ) && \
(CYGNUM_UITRON_FLAGS >= 3) && \
(CYGNUM_UITRON_FLAGS < 90) && \
( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) || \
CYGNUM_UITRON_FLAGS_INITIALLY >= 3 ) && \
\
/* test configuration for enough message boxes */ \
defined( CYGPKG_UITRON_MBOXES ) && \
(CYGNUM_UITRON_MBOXES >= 3) && \
(CYGNUM_UITRON_MBOXES < 90) && \
( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) || \
CYGNUM_UITRON_MBOXES_INITIALLY >= 3 ) && \
\
/* test configuration for enough fixed memory pools */ \
defined( CYGPKG_UITRON_MEMPOOLFIXED ) && \
(CYGNUM_UITRON_MEMPOOLFIXED >= 3) && \
(CYGNUM_UITRON_MEMPOOLFIXED < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3 ) && \
\
/* test configuration for enough variable mempools */ \
defined( CYGPKG_UITRON_MEMPOOLVAR ) && \
(CYGNUM_UITRON_MEMPOOLVAR >= 3) && \
(CYGNUM_UITRON_MEMPOOLVAR < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
volatile int intercount = 0;
 
UINT scratch;
T_MSG *t_msg;
VP vp;
 
 
extern "C" {
void task1( unsigned int arg );
void task2( unsigned int arg );
void task3( unsigned int arg );
void task4( unsigned int arg );
}
 
 
void task1( unsigned int arg )
{
ER ercd;
int i;
T_RSYS rsys;
 
CYG_TEST_INFO( "Task 1 running" );
 
// check initial state
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
// disable intrs and check state
ercd = loc_cpu();
CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// try an illegal op
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
#endif // CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// enable intrs and check state and a legal sleep
ercd = unl_cpu();
CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
ercd = dly_tsk( 1 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
// disable intrs and try scheduler illegal ops
ercd = loc_cpu();
CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = dis_dsp();
CYG_TEST_CHECK( E_CTX == ercd, "dis_dsp bad ercd !E_CTX" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_CTX == ercd, "ena_dsp bad ercd !E_CTX" );
#endif // CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// enable again and check state
ercd = unl_cpu();
CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
// disable the scheduler and check state
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_DDSP == rsys.sysstat, "system state not TSS_DDSP" );
// disable intrs and check state
ercd = loc_cpu();
CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
// then unlock and check state
ercd = unl_cpu();
CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
ercd = ref_sys( &rsys );
CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
 
CYG_TEST_PASS( "Interrupt dis/enabling and interactions" );
 
// and now we can do the rest of the test
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai bad ercd !E_OBJ" );
ercd = rel_wai( 1 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai(me) bad ercd !E_OBJ" );
ercd = rel_wai( -6 );
CYG_TEST_CHECK( E_ID == ercd, "rel_wai bad ercd !E_ID" );
ercd = rel_wai( 99 );
CYG_TEST_CHECK( E_ID == ercd, "rel_wai bad ercd !E_ID" );
#endif // we can test bad param error returns
 
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 2, 22222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai bad ercd !E_OBJ" );
ercd = rel_wai( 1 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai(me) bad ercd !E_OBJ" );
#endif // we can test bad param error returns
 
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_RLWAI == ercd, "wai_sem bad ercd !E_RLWAI" );
 
ercd = twai_sem( 1, 20 );
CYG_TEST_CHECK( E_RLWAI == ercd, "twai_sem bad ercd !E_RLWAI" );
 
ercd = wai_flg( &scratch, 1, 9999, 0 );
CYG_TEST_CHECK( E_RLWAI == ercd, "wai_flg bad ercd !E_RLWAI" );
 
ercd = twai_flg( &scratch, 1, 9999, 0, 10 );
CYG_TEST_CHECK( E_RLWAI == ercd, "twai_flg bad ercd !E_RLWAI" );
 
ercd = rcv_msg( &t_msg, 1 );
CYG_TEST_CHECK( E_RLWAI == ercd, "rcv_msg bad ercd !E_RLWAI" );
 
ercd = trcv_msg( &t_msg, 1, 10 );
CYG_TEST_CHECK( E_RLWAI == ercd, "trcv_msg bad ercd !E_RLWAI" );
 
// these are loops so as to consume the whole of the mempool
// in order to wait at the end
for ( i = 0; i < 10; i++ )
if ( E_OK != (ercd = get_blf( &vp, 3 ) ) )
break;
CYG_TEST_CHECK( E_RLWAI == ercd, "get_blf bad ercd !E_RLWAI" );
 
for ( i = 0; i < 10; i++ )
if ( E_OK != (ercd = tget_blf( &vp, 3, 10 ) ) )
break;
CYG_TEST_CHECK( E_RLWAI == ercd, "tget_blf bad ercd !E_RLWAI" );
 
for ( i = 0; i < 10; i++ )
if ( E_OK != (ercd = get_blk( &vp, 1, 1000 ) ) )
break;
CYG_TEST_CHECK( E_RLWAI == ercd, "get_blk bad ercd !E_RLWAI" );
 
for ( i = 0; i < 10; i++ )
if ( E_OK != (ercd = tget_blk( &vp, 1, 1000, 10 ) ) )
break;
CYG_TEST_CHECK( E_RLWAI == ercd, "tget_blk bad ercd !E_RLWAI" );
 
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_RLWAI == ercd, "dly_tsk bad ercd !E_RLWAI" );
 
ercd = tslp_tsk( 10 );
CYG_TEST_CHECK( E_RLWAI == ercd, "tslp_tsk bad ercd !E_RLWAI" );
 
ercd = slp_tsk();
CYG_TEST_CHECK( E_RLWAI == ercd, "slp_tsk bad ercd !E_RLWAI" );
 
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
CYG_TEST_PASS("release wait: various waiting calls");
 
// all done
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
int i;
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &i );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == i, "tid not 2" );
if ( 22222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 22222" );
 
for ( i = 0 ; i < 100; i++ ) {
ercd = rel_wai( 1 );
CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
}
// we expect task2 to be killed here
CYG_TEST_FAIL( "Task 2 ran to completion!" );
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF testcx5.cxx
/v2_0/tests/testcx6.cxx
0,0 → 1,600
//===========================================================================
//
// testcx6.cxx
//
// uITRON "C++" test program six
//
//===========================================================================
//####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-10-14
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* test configuration for enough flag objects */ \
defined( CYGPKG_UITRON_FLAGS ) && \
(CYGNUM_UITRON_FLAGS >= 3) && \
(CYGNUM_UITRON_FLAGS < 90) && \
( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) || \
CYGNUM_UITRON_FLAGS_INITIALLY >= 3 ) && \
\
/* test configuration for enough message boxes */ \
defined( CYGPKG_UITRON_MBOXES ) && \
(CYGNUM_UITRON_MBOXES >= 3) && \
(CYGNUM_UITRON_MBOXES < 90) && \
( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) || \
CYGNUM_UITRON_MBOXES_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
volatile int intercount = 0;
UINT scratch;
T_MSG *t_msg = (T_MSG *)&scratch;
T_MSG *msg;
VP vp;
 
T_CSEM t_csem = { NULL, 0, 0 };
T_CMBX t_cmbx = { NULL, 0 };
T_CFLG t_cflg = { NULL, 0, 0 };
T_RSEM t_rsem;
T_RMBX t_rmbx;
T_RFLG t_rflg;
 
 
extern "C" {
void task1( unsigned int arg );
void task2( unsigned int arg );
void task3( unsigned int arg );
void task4( unsigned int arg );
}
 
void task1( unsigned int arg )
{
ER ercd;
int tests = 0;
 
CYG_TEST_INFO( "Task 1 running" );
 
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 2, 22222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
tests++;
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_sem( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_sem bad ercd !E_ID" );
ercd = del_sem( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_sem bad ercd !E_ID" );
ercd = cre_sem( -6, &t_csem );
CYG_TEST_CHECK( E_ID == ercd, "cre_sem bad ercd !E_ID" );
ercd = cre_sem( 99, &t_csem );
CYG_TEST_CHECK( E_ID == ercd, "cre_sem bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
ercd = cre_sem( 3, &t_csem );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_sem bad ercd !E_OBJ" );
// delete it so we can play
ercd = del_sem( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
// check it is deleted
ercd = sig_sem( 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
ercd = preq_sem( 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "preq_sem bad ercd !E_NOEXS" );
ercd = twai_sem( 3, 10 );
CYG_TEST_CHECK( E_NOEXS == ercd, "twai_sem bad ercd !E_NOEXS" );
ercd = wai_sem( 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "wai_sem bad ercd !E_NOEXS" );
ercd = ref_sem( &t_rsem, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_sem bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_sem( 3, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_sem bad ercd !E_PAR" );
#endif
t_csem.sematr = 0xfff;
ercd = cre_sem( 3, &t_csem );
CYG_TEST_CHECK( E_RSATR == ercd, "cre_sem bad ercd !E_RSATR" );
t_csem.sematr = 0;
#endif // we can test bad param error returns
ercd = cre_sem( 3, &t_csem );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
// and check we can use it
ercd = sig_sem( 3 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
ercd = wai_sem( 3 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
ercd = preq_sem( 3 );
CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
ercd = twai_sem( 3, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
ercd = ref_sem( &t_rsem, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
 
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_DLT == ercd, "wai_sem bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = twai_sem( 2, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_sem bad ercd !E_DLT" );
 
// check they are deleted
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
// re-create and do it again
ercd = cre_sem( 1, &t_csem );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
ercd = cre_sem( 2, &t_csem );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
 
// now wait while task 2 deletes the wait objects again
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_DLT == ercd, "wai_sem bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = twai_sem( 2, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_sem bad ercd !E_DLT" );
 
// check they are deleted
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
 
CYG_TEST_PASS("create/delete semaphores");
#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
 
 
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
tests++;
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_flg( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_flg bad ercd !E_ID" );
ercd = del_flg( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_flg bad ercd !E_ID" );
ercd = cre_flg( -6, &t_cflg );
CYG_TEST_CHECK( E_ID == ercd, "cre_flg bad ercd !E_ID" );
ercd = cre_flg( 99, &t_cflg );
CYG_TEST_CHECK( E_ID == ercd, "cre_flg bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
ercd = cre_flg( 3, &t_cflg );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_flg bad ercd !E_OBJ" );
// delete it so we can play
ercd = del_flg( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
// check it is deleted
ercd = set_flg( 3, 0x6789 );
CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
ercd = clr_flg( 3, 0x9876 );
CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
ercd = pol_flg( &scratch, 3, 0xdddd, TWF_ANDW );
CYG_TEST_CHECK( E_NOEXS == ercd, "pol_flg bad ercd !E_NOEXS" );
ercd = twai_flg( &scratch, 3, 0x4444, TWF_ORW, 10 );
CYG_TEST_CHECK( E_NOEXS == ercd, "twai_flg bad ercd !E_NOEXS" );
ercd = wai_flg( &scratch, 3, 0xbbbb, TWF_ANDW | TWF_CLR );
CYG_TEST_CHECK( E_NOEXS == ercd, "wai_flg bad ercd !E_NOEXS" );
ercd = ref_flg( &t_rflg, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_flg bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_flg( 3, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_flg bad ercd !E_PAR" );
#endif
t_cflg.flgatr = 0xfff;
ercd = cre_flg( 3, &t_cflg );
CYG_TEST_CHECK( E_RSATR == ercd, "cre_flg bad ercd !E_RSATR" );
#endif // we can test bad param error returns
// now create it well
t_cflg.flgatr = 0;
t_cflg.iflgptn = 0;
ercd = cre_flg( 3, &t_cflg );
CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
// and check we can use it
ercd = clr_flg( 3, 0x7256 );
CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd" );
ercd = set_flg( 3, 0xff );
CYG_TEST_CHECK( E_OK == ercd, "set_flg bad ercd" );
ercd = wai_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR );
CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
ercd = pol_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR );
CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
ercd = twai_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
ercd = ref_flg( &t_rflg, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 == t_rflg.flgptn, "ref_flg bad ercd" );
// now create it again with a preset pattern and check that we can
// detect that pattern:
ercd = del_flg( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
t_cflg.flgatr = 0;
t_cflg.iflgptn = 0x1234;
ercd = cre_flg( 3, &t_cflg );
CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
// and check we can use it
ercd = wai_flg( &scratch, 3, 0x1200, TWF_ANDW );
CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
ercd = pol_flg( &scratch, 3, 0x0034, TWF_ANDW );
CYG_TEST_CHECK( E_OK == ercd, "pol_flg bad ercd" );
ercd = twai_flg( &scratch, 3, 0x1004, TWF_ANDW, 10 );
CYG_TEST_CHECK( E_OK == ercd, "twai_flg bad ercd" );
ercd = pol_flg( &scratch, 3, 0xffedcb, TWF_ORW );
CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
ercd = ref_flg( &t_rflg, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0x1234 == t_rflg.flgptn, "ref_flg bad ercd" );
ercd = clr_flg( 3, 0 );
ercd = ref_flg( &t_rflg, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
CYG_TEST_CHECK( 0 == t_rflg.flgptn, "ref_flg bad ercd" );
 
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = wai_flg( &scratch, 1, 0xaa, TWF_ANDW );
CYG_TEST_CHECK( E_DLT == ercd, "wai_flg bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = twai_flg( &scratch, 2, 0x55, TWF_ANDW, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_flg bad ercd !E_DLT" );
 
// check they are deleted
ercd = set_flg( 1, 0x22 );
CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
ercd = clr_flg( 2, 0xdd );
CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
// re-create and do it again
t_cflg.iflgptn = 0x5555;
ercd = cre_flg( 1, &t_cflg );
CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
t_cflg.iflgptn = 0;
ercd = cre_flg( 2, &t_cflg );
CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
 
// now wait while task 2 deletes the wait objects again
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = wai_flg( &scratch, 1, 0xaaaa, TWF_ORW | TWF_CLR );
CYG_TEST_CHECK( E_DLT == ercd, "wai_flg bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = twai_flg( &scratch, 2, 0xffff, TWF_ORW, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_flg bad ercd !E_DLT" );
 
// check they are deleted
ercd = clr_flg( 1, 0xd00d );
CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
ercd = set_flg( 2, 0xfff00 );
CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
 
CYG_TEST_PASS("create/delete flags");
#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
 
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
tests++;
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_mbx( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_mbx bad ercd !E_ID" );
ercd = del_mbx( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_mbx bad ercd !E_ID" );
ercd = cre_mbx( -6, &t_cmbx );
CYG_TEST_CHECK( E_ID == ercd, "cre_mbx bad ercd !E_ID" );
ercd = cre_mbx( 99, &t_cmbx );
CYG_TEST_CHECK( E_ID == ercd, "cre_mbx bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
ercd = cre_mbx( 3, &t_cmbx );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_mbx bad ercd !E_OBJ" );
// delete it so we can play
ercd = del_mbx( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
// check it is deleted
ercd = snd_msg( 3, t_msg );
CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
ercd = rcv_msg( &msg, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "rcv_msg bad ercd !E_NOEXS" );
ercd = trcv_msg( &msg, 3, 10 );
CYG_TEST_CHECK( E_NOEXS == ercd, "trcv_msg bad ercd !E_NOEXS" );
ercd = prcv_msg( &msg, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "prcv_msg bad ercd !E_NOEXS" );
ercd = ref_mbx( &t_rmbx, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mbx bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_mbx( 3, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_mbx bad ercd !E_PAR" );
#endif
t_cmbx.mbxatr = 0xfff;
ercd = cre_mbx( 3, &t_cmbx );
CYG_TEST_CHECK( E_RSATR == ercd, "cre_mbx bad ercd !E_RSATR" );
t_cmbx.mbxatr = 0;
#endif // we can test bad param error returns
ercd = cre_mbx( 3, &t_cmbx );
CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
// and check we can use it
ercd = snd_msg( 3, t_msg );
CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
ercd = rcv_msg( &msg, 3 );
CYG_TEST_CHECK( E_OK == ercd, "rcv_msg bad ercd" );
ercd = trcv_msg( &msg, 3, 2 );
CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
ercd = prcv_msg( &msg, 3 );
CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
ercd = ref_mbx( &t_rmbx, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
 
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rcv_msg( &msg, 1 );
CYG_TEST_CHECK( E_DLT == ercd, "wai_mbx bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = trcv_msg( &msg, 2, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_mbx bad ercd !E_DLT" );
 
// check they are deleted
ercd = snd_msg( 1, t_msg );
CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
ercd = snd_msg( 2, t_msg );
CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
// re-create and do it again
ercd = cre_mbx( 1, &t_cmbx );
CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
ercd = cre_mbx( 2, &t_cmbx );
CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
 
// now wait while task 2 deletes the wait objects again
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rcv_msg( &msg, 1 );
CYG_TEST_CHECK( E_DLT == ercd, "wai_mbx bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = trcv_msg( &msg, 2, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "twai_mbx bad ercd !E_DLT" );
 
// check they are deleted
ercd = snd_msg( 1, t_msg );
CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
ercd = snd_msg( 2, t_msg );
CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
 
CYG_TEST_PASS("create/delete mboxes");
#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
 
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
ercd = dly_tsk( 5 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
// all done
if ( 0 == tests ) {
CYG_TEST_NA( "No objects have create/delete enabled" );
}
else {
CYG_TEST_EXIT( "All done" );
}
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
int i;
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &i );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == i, "tid not 2" );
if ( 22222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 22222" );
 
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
 
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
ercd = del_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
 
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
ercd = del_flg( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_flg( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_flg( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_flg( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
 
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
ercd = del_mbx( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mbx( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mbx( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mbx( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
 
// we expect task2 to be killed here
CYG_TEST_FAIL( "Task 2 ran to completion!" );
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF testcx6.cxx
/v2_0/tests/testcx7.cxx
0,0 → 1,1101
//===========================================================================
//
// testcx7.cxx
//
// uITRON "C++" test program seven
//
//===========================================================================
//####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-10-14
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* test configuration for enough flag objects */ \
defined( CYGPKG_UITRON_FLAGS ) && \
(CYGNUM_UITRON_FLAGS >= 3) && \
(CYGNUM_UITRON_FLAGS < 90) && \
( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) || \
CYGNUM_UITRON_FLAGS_INITIALLY >= 3 ) && \
\
/* test configuration for enough message boxes */ \
defined( CYGPKG_UITRON_MBOXES ) && \
(CYGNUM_UITRON_MBOXES >= 3) && \
(CYGNUM_UITRON_MBOXES < 90) && \
( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) || \
CYGNUM_UITRON_MBOXES_INITIALLY >= 3 ) && \
\
/* test configuration for enough fixed memory pools */ \
defined( CYGPKG_UITRON_MEMPOOLFIXED ) && \
(CYGNUM_UITRON_MEMPOOLFIXED >= 3) && \
(CYGNUM_UITRON_MEMPOOLFIXED < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3 ) && \
\
/* test configuration for enough variable mempools */ \
defined( CYGPKG_UITRON_MEMPOOLVAR ) && \
(CYGNUM_UITRON_MEMPOOLVAR >= 3) && \
(CYGNUM_UITRON_MEMPOOLVAR < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
#include <cyg/kernel/test/stackmon.h> // stack analysis tools
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
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 );
}
 
// ========================================================================
 
enum {
START_WAITOP = 0,
SLEEP = 0,
DELAY,
SEMGET,
FLAGWAIT,
MSGGET,
MEMFIXEDGET,
MEMVARGET,
DONE_WAITOP
};
typedef int WAITOP;
 
enum {
START_TYPE = 0,
PLAIN = 0,
TIMED = 1,
DONE_TYPE
};
typedef int WAITTYPE;
 
enum {
START_KILLOP = 0,
 
// These are the 5 ways out of a wait that we perm
// with other circumstances:
SIGNAL = 0, // do the appropriate producer op
TIMEOUT, // wait for the timeout to fire
RELEASE, // do a rel_wai()
DELETE, // delete the object; del_xxx()
KILL, // do a ter_tsk() on the waiter
 
SUSPEND_SIGNAL_RESUME,
SUSPEND_TIMEOUT_RESUME,
SUSPEND_RELEASE_RESUME,
SUSPEND_DELETE_RESUME,
SUSPEND_KILL, // resume not applicable
 
SUSPEND_SIGNAL_KILL,
SUSPEND_TIMEOUT_KILL,
SUSPEND_RELEASE_KILL,
SUSPEND_DELETE_KILL,
// SUSPEND_KILL_KILL not applicable
 
#if 0
// support these later if _really_ keen.
SUSPEND_SIGNAL_DELETE_RESUME,
SUSPEND_TIMEOUT_DELETE_RESUME,
SUSPEND_RELEASE_DELETE_RESUME,
// SUSPEND_DELETE_DELETE_RESUME not applicable
// SUSPEND_KILL_DELETE_RESUME not applicable
 
SUSPEND_SIGNAL_DELETE_KILL,
SUSPEND_TIMEOUT_DELETE_KILL,
SUSPEND_RELEASE_DELETE_KILL,
// SUSPEND_DELETE_DELETE_KILL,
SUSPEND_KILL_DELETE // 2nd kill not applicable
#endif
DONE_KILLOP
};
typedef int KILLOP;
// ========================================================================
 
char * waitstrings[] =
{ "Sleep ", "Delay ", "Sema ", "Flag ", "Mbox ", "MemFix", "MemVar" };
 
char * typestrings[] =
{ " (Plain) : ", " (Timed) : " };
 
char * killstrings[] =
{ "Signal",
"Wait-for-timeout",
"Release-wait",
"Delete-object",
"Kill-task",
 
"Suspend/Signal/Resume",
"Suspend/Wait-for-timeout/Resume",
"Suspend/Release-wait/Resume",
"Suspend/Delete-object/Resume",
"Suspend/Kill-task",
 
"Suspend/Signal/Kill-task",
"Suspend/Wait-for-timeout/Kill-task",
"Suspend/Release-wait/Kill-task",
"Suspend/Delete-object/Kill-task",
 
};
 
// ========================================================================
 
inline int task2arg( WAITOP wait, WAITTYPE waittype, KILLOP kill )
{
return waittype + (wait << 1) + (kill << 8);
}
 
inline void decodearg( int arg, WAITOP *pwait, WAITTYPE *pwaittype, KILLOP *pkill )
{
*pwaittype = (arg & 1) ? TIMED : PLAIN;
*pwait = (arg >> 1) & 0x7f;
*pkill = (arg >> 8);
}
 
static char *strdog( char *p, char *q )
{
while ( 0 != (*p++ = *q++) );
return p - 1;
}
 
static char *
makemsg( char *z, WAITOP wait, WAITTYPE waittype, KILLOP kill )
{
static char buf[ 1000 ];
char *p = buf;
p = strdog( p, z );
p = strdog( p, waitstrings[ wait ] );
p = strdog( p, typestrings[ waittype ] );
p = strdog( p, killstrings[ kill ] );
*p = 0;
return buf;
}
 
// ========================================================================
 
volatile int intercom = 0;
 
// ========================================================================
 
T_RTSK rtsk;
 
void
do_suspend( void )
{
ER ercd;
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_WAI == rtsk.tskstat, "bad tskstat !TTS_WAI" );
ercd = sus_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_WAS == rtsk.tskstat, "bad tskstat !TTS_WAS" );
}
 
void
do_resume( void )
{
ER ercd;
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_SUS == rtsk.tskstat, "bad tskstat !TTS_SUS" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = rsm_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_RDY == rtsk.tskstat, "bad tskstat !TTS_RDY" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
}
 
// ========================================================================
 
#define T1_WAIT (7)
#define T2_WAIT (5)
 
#define T1_MALLOC (110)
#ifdef CYGSEM_KERNEL_MEMORY_COALESCE
#define T2_MALLOC (100)
#else
#define T2_MALLOC T1_MALLOC
#endif
 
VP vptmp;
VP vp = NULL;
VP vp1 = NULL;
VP t2vp = NULL;
VP t2vp_backup = NULL;
 
UINT scratch;
 
T_MSG *msg = (T_MSG *)&scratch;
T_MSG *msg1;
 
void
do_prep( WAITOP wait )
{
ER ercd;
switch ( wait ) {
case SLEEP:
case DELAY:
case SEMGET:
case FLAGWAIT:
case MSGGET:
// do nothing for all of those
break;
case MEMFIXEDGET:
// allocate all the memory in the pool; remember a couple
// for freeing as the signalling operation:
t2vp = NULL;
vp = vptmp = NULL;
do {
vp1 = vptmp;
vptmp = vp;
ercd = pget_blf( &vp, 1 );
} while ( E_OK == ercd );
CYG_TEST_CHECK( E_TMOUT == ercd, "get_blf bad ercd" );
CYG_TEST_CHECK( NULL != vp, "no allocated block to free" );
CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
break;
case MEMVARGET:
// allocate all the memory in the pool; remember a couple
// for freeing as the signalling operation:
t2vp = NULL;
vp = vptmp = NULL;
do {
vp1 = vptmp;
vptmp = vp;
ercd = pget_blk( &vp, 1, T1_MALLOC );
} while ( E_OK == ercd );
CYG_TEST_CHECK( E_TMOUT == ercd, "get_blk bad ercd" );
CYG_TEST_CHECK( NULL != vp, "no allocated block to free" );
CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
}
 
void
do_tidyup( WAITOP wait )
{
ER ercd;
switch ( wait ) {
case SLEEP:
case DELAY:
case SEMGET:
case MSGGET:
// do nothing for all of those
break;
case FLAGWAIT:
// clear the flag variable
ercd = clr_flg( 1, 0 );
CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd, tidy vp" );
break;
case MEMFIXEDGET:
if ( NULL != vp ) {
ercd = rel_blf( 1, vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy vp" );
}
if ( NULL != vp1 ) {
ercd = rel_blf( 1, vp1 );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy vp1" );
}
if ( NULL != t2vp ) {
ercd = rel_blf( 1, t2vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy t2vp" );
}
break;
case MEMVARGET:
if ( NULL != vp ) {
ercd = rel_blk( 1, vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy vp" );
}
if ( NULL != vp1 ) {
ercd = rel_blk( 1, vp1 );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy vp1" );
}
if ( NULL != t2vp ) {
ercd = rel_blk( 1, t2vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy t2vp" );
}
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
}
 
void
do_recreate( WAITOP wait )
{
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
static T_CSEM t_csem = { NULL, 0, 0 };
#endif
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
static T_CMBX t_cmbx = { NULL, 0 };
#endif
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
static T_CFLG t_cflg = { NULL, 0, 0 };
#endif
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
static T_CMPF t_cmpf = { NULL, 0, 20, 95 };
#endif
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
static T_CMPL t_cmpl = { NULL, 0, 2000 };
#endif
ER ercd = E_OK;
switch ( wait ) {
case SLEEP:
case DELAY:
// do nothing for all of those
break;
case SEMGET:
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
// create the semaphore
ercd = cre_sem( 1, &t_csem );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_recreate SEMGET" );
#endif
break;
case FLAGWAIT:
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
// create the flag
ercd = cre_flg( 1, &t_cflg );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_recreate FLAGWAIT" );
#endif
break;
case MSGGET:
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
// create the mbox
ercd = cre_mbx( 1, &t_cmbx );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_recreate MSGGET" );
#endif
break;
case MEMFIXEDGET:
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
// create the mempool
ercd = cre_mpf( 1, &t_cmpf );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_recreate MEMFIXEDGET" );
#endif
break;
case MEMVARGET:
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
// create the mempool
ercd = cre_mpl( 1, &t_cmpl );
CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_recreate MEMVARGET" );
#endif
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
// this is just to use ercd to prevent warnings
CYG_TEST_CHECK( E_OK == ercd, "<blank> bad ercd" );
}
 
 
 
void
do_signal( WAITOP wait )
{
ER ercd;
switch ( wait ) {
case SLEEP:
// send a wakeup
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
break;
case DELAY:
// simply wait for task 2's delay to complete
ercd = dly_tsk( T1_WAIT );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
break;
case SEMGET:
// signal the semaphore
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
break;
case FLAGWAIT:
// set the flag bits
ercd = set_flg( 1, 0xff );
CYG_TEST_CHECK( E_OK == ercd, "set_flg bad ercd" );
break;
case MSGGET:
// send a message
ercd = snd_msg( 1, msg );
CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
break;
case MEMFIXEDGET:
// release a couple of blocks we allocated earlier. I hope.
CYG_TEST_CHECK( NULL != vp, "no allocated block to free" );
CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
ercd = rel_blf( 1, vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
vp = NULL;
ercd = rel_blf( 1, vp1 );
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd1" );
vp1 = NULL;
break;
case MEMVARGET:
// release a couple of blocks we allocated earlier. I hope.
CYG_TEST_CHECK( NULL != vp, "no allocated block to free" );
CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
ercd = rel_blk( 1, vp );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
vp = NULL;
ercd = rel_blk( 1, vp1 );
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd1" );
vp1 = NULL;
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
}
 
void
do_delete( WAITOP wait )
{
ER ercd = E_OK;
switch ( wait ) {
case SLEEP:
case DELAY:
CYG_TEST_FAIL( "bad call to do_delete( SLEEP or DELAY )" );
break;
case SEMGET:
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
// delete the semaphore
ercd = del_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_delete( SEMGET )" );
#endif
break;
case FLAGWAIT:
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
// delete the flag
ercd = del_flg( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_delete( FLAGWAIT )" );
#endif
break;
case MSGGET:
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
// delete the mbox
ercd = del_mbx( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_delete( MSGGET )" );
#endif
break;
case MEMFIXEDGET:
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
// delete the mempool
ercd = del_mpf( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_delete( MEMFIXEDGET )" );
#endif
break;
case MEMVARGET:
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
// delete the mempool
ercd = del_mpl( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
#else
CYG_TEST_FAIL( "bad call to do_delete( MEMVARGET )" );
#endif
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
// this is just to use ercd to prevent warnings
CYG_TEST_CHECK( E_OK == ercd, "<blank> bad ercd" );
}
 
 
ER
do_wait( WAITOP wait, WAITTYPE type )
{
switch ( wait ) {
case SLEEP:
return ( PLAIN == type ) ? slp_tsk() : tslp_tsk( T2_WAIT );
case DELAY:
return dly_tsk( T2_WAIT ); // forget the type
case SEMGET:
return ( PLAIN == type ) ? wai_sem( 1 ) : twai_sem( 1, T2_WAIT );
case FLAGWAIT:
return ( PLAIN == type ) ?
wai_flg( &scratch, 1, 0x55, TWF_ANDW ) :
twai_flg( &scratch, 1, 0xaa, TWF_ANDW, T2_WAIT );
case MSGGET:
return ( PLAIN == type ) ?
rcv_msg( &msg1, 1 ) :
trcv_msg( &msg1, 1, T2_WAIT );
case MEMFIXEDGET:
return ( PLAIN == type ) ?
get_blf( &t2vp, 1 ) :
tget_blf( &t2vp, 1, T2_WAIT );
case MEMVARGET:
return ( PLAIN == type ) ?
get_blk( &t2vp, 1, T2_MALLOC ) :
tget_blk( &t2vp, 1, T2_MALLOC, T2_WAIT );
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
CYG_TEST_FAIL( "Bad wait in do_wait" );
return E_SYS;
}
 
void
check_waitstate( WAITOP wait, int waiting )
{
ER ercd;
int waity = 0;
switch ( wait ) {
case SLEEP:
case DELAY:
return; // do nothing for these
case SEMGET: {
T_RSEM rsem;
ercd = ref_sem( &rsem, 1 );
waity = rsem.wtsk;
break;
}
case FLAGWAIT: {
T_RFLG rflg;
ercd = ref_flg( &rflg, 1 );
waity = rflg.wtsk;
break;
}
case MSGGET: {
T_RMBX rmbx;
ercd = ref_mbx( &rmbx, 1 );
waity = rmbx.wtsk;
break;
}
case MEMFIXEDGET: {
T_RMPF rmpf;
ercd = ref_mpf( &rmpf, 1 );
waity = rmpf.wtsk;
break;
}
case MEMVARGET: {
T_RMPL rmpl;
ercd = ref_mpl( &rmpl, 1 );
waity = rmpl.wtsk;
break;
}
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
if ( waiting )
CYG_TEST_CHECK( waity, "Object has no task waiting!" );
else
CYG_TEST_CHECK( !waity, "Object had a task waiting!" );
}
 
// ========================================================================
void task1( unsigned int arg )
{
ER ercd;
WAITOP wait;
WAITTYPE type;
KILLOP kill;
 
CYG_TEST_INFO( "Task 1 running" );
 
{
extern Cyg_Thread cyg_uitron_TASKS[];
cyg_test_dump_thread_stack_stats(
"Startup, task1", &cyg_uitron_TASKS[ 0 ] );
cyg_test_dump_thread_stack_stats(
"Startup, task2", &cyg_uitron_TASKS[ 1 ] );
cyg_test_dump_interrupt_stack_stats( "Startup" );
cyg_test_dump_idlethread_stack_stats( "Startup" );
cyg_test_clear_interrupt_stack();
}
 
ercd = chg_pri( 1, 8 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
 
for ( wait = START_WAITOP; wait < DONE_WAITOP ; wait++) {
for ( type = START_TYPE; type < DONE_TYPE ; type++ ) {
for ( kill = START_KILLOP; kill < DONE_KILLOP ; kill++ ) {
// These clauses deal with a couple of special cases:
// [doing it this way helps keep the rest of the code
// nicely general and orthogonal]
//
// 1) DELAY: dly_tsk(): when this times out, the retcode is
// E_OK rather than E_TMOUT, and it always times out. The
// "signalling" method here is just to wait yourself. So we
// do not test DELAY with TIMED type.
//
// 2) PLAIN tests with TIMEOUT kill operations: a PLAIN test
// will not time out, it'll wait forever, so waiting for it
// so to do is pointless; further, we would check for the
// wrong error code. So we do not test PLAIN tests with
// TIMOUT kill operations.
//
// 3) SLEEP or DELAY tests with DELETE operations: there is
// no synchronization to delete in those cases.
// 3a) Individual object types are tested for delete support,
// and if there is none, the test is skipped.
 
if ( DELAY == wait && TIMED == type )
continue;
 
if ( PLAIN == type &&
( ( TIMEOUT == kill) ||
(SUSPEND_TIMEOUT_RESUME == kill) ||
(SUSPEND_TIMEOUT_KILL == kill) ) )
continue;
 
if ( (
#ifndef CYGPKG_UITRON_SEMAS_CREATE_DELETE
(SEMGET == wait) ||
#endif
#ifndef CYGPKG_UITRON_FLAGS_CREATE_DELETE
(FLAGWAIT == wait) ||
#endif
#ifndef CYGPKG_UITRON_MBOXES_CREATE_DELETE
(MSGGET == wait) ||
#endif
#ifndef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
(MEMFIXEDGET == wait) ||
#endif
#ifndef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
(MEMVARGET == wait) ||
#endif
(SLEEP == wait) ||
(DELAY == wait)
) &&
((DELETE == kill) ||
(SUSPEND_DELETE_RESUME == kill) ||
(SUSPEND_DELETE_KILL == kill)) )
continue;
 
 
CYG_TEST_INFO( makemsg( "T1: ", wait, type, kill ) );
 
intercom = 0;
 
// prepare the synchronization objects
// (actually, just empty the mempools)
do_prep( wait );
 
// start task 2 at a higher priority than myself
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 2, task2arg( wait, type, kill ) );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
// task 2 should run now, until it waits.
 
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_WAI == rtsk.tskstat, "bad tskstat" );
CYG_TEST_CHECK( 5 == rtsk.tskpri, "bad tskpri" );
 
switch ( kill ) {
case SIGNAL:
// signal the task appropriately
do_signal( wait );
// it should now have run to completion
break;
case TIMEOUT:
check_waitstate( wait, 1 );
// wait for the timeout to occur
ercd = dly_tsk( T1_WAIT );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
check_waitstate( wait, 0 );
// it should now have run to completion
break;
case RELEASE:
// hit the task with a release-wait
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
// it should now have run to completion
break;
case DELETE:
// delete the object appropriately
do_delete( wait );
// it should now have run to completion
break;
case KILL:
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
case SUSPEND_SIGNAL_RESUME:
// suspend the task
do_suspend();
// signal the task appropriately
do_signal( wait );
// resume the task
do_resume();
// it should now have run to completion
break;
case SUSPEND_TIMEOUT_RESUME:
check_waitstate( wait, 1 );
// suspend the task
do_suspend();
check_waitstate( wait, 1 );
// wait for the timeout to occur
ercd = dly_tsk( T1_WAIT );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
check_waitstate( wait, 0 );
// resume the task
do_resume();
// it should now have run to completion
break;
case SUSPEND_RELEASE_RESUME:
// suspend the task
do_suspend();
// hit the task with a release-wait
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
// resume the task
do_resume();
// it should now have run to completion
break;
case SUSPEND_DELETE_RESUME:
// suspend the task
do_suspend();
// delete the object appropriately
do_delete( wait );
// resume the task
do_resume();
// it should now have run to completion
break;
case SUSPEND_KILL:
// suspend the task
do_suspend();
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
case SUSPEND_SIGNAL_KILL:
// suspend the task
do_suspend();
// signal the task appropriately
do_signal( wait );
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
case SUSPEND_TIMEOUT_KILL:
check_waitstate( wait, 1 );
// suspend the task
do_suspend();
check_waitstate( wait, 1 );
// wait for the timeout to occur
ercd = dly_tsk( T1_WAIT );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
check_waitstate( wait, 0 );
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
case SUSPEND_RELEASE_KILL:
// suspend the task
do_suspend();
// hit the task with a release-wait
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
case SUSPEND_DELETE_KILL:
// suspend the task
do_suspend();
// delete the object appropriately
do_delete( wait );
// kill the task
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
// it should now have terminated without running
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
// task 2 should be dormant now, however it got there
ercd = ref_tsk( &rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_DMT == rtsk.tskstat, "bad tskstat" );
 
if ( (SUSPEND_SIGNAL_KILL == kill) &&
((MEMFIXEDGET == wait) || (MEMVARGET == wait)) ) {
// it was a killed successful memory alloc, so we have
// lost the pointer to memory allocated; there is an
// implicit storeleak problem when the task trying
// to allocate is signalled then killed.
// Recreate the pointer from an old version:
CYG_TEST_CHECK( NULL == t2vp, "t2vp WAS allocated!" );
t2vp = t2vp_backup;
}
 
switch ( kill ) {
case KILL:
case SUSPEND_KILL:
case SUSPEND_SIGNAL_KILL:
case SUSPEND_TIMEOUT_KILL:
case SUSPEND_RELEASE_KILL:
case SUSPEND_DELETE_KILL:
// if task 2 was killed, expect only one increment
CYG_TEST_CHECK( 1 == intercom, "intercom bad value !1" );
break;
default:
// otherwise expect two increments
CYG_TEST_CHECK( 2 == intercom, "intercom bad value !2" );
break;
}
// tidy up or recreate the synchronization objects
if ( (DELETE == kill) ||
(SUSPEND_DELETE_RESUME == kill) ||
(SUSPEND_DELETE_KILL == kill) )
do_recreate( wait );
else
do_tidyup( wait );
}
}
}
CYG_TEST_PASS("synchronization interaction tests");
 
{
extern Cyg_Thread cyg_uitron_TASKS[];
cyg_test_dump_thread_stack_stats(
"All done, task1", &cyg_uitron_TASKS[ 0 ] );
cyg_test_dump_thread_stack_stats(
"All done, task2", &cyg_uitron_TASKS[ 1 ] );
cyg_test_dump_interrupt_stack_stats( "All done" );
cyg_test_dump_idlethread_stack_stats( "All done" );
}
// all done
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
WAITOP wait;
WAITTYPE waittype;
KILLOP kill;
 
decodearg( arg, &wait, &waittype, &kill );
 
// CYG_TEST_INFO( makemsg( " 2: ", wait, waittype, kill ) );
 
intercom++;
ercd = do_wait( wait, waittype );
intercom++;
 
switch ( kill ) {
case SIGNAL:
case SUSPEND_SIGNAL_RESUME:
// we expect to have been signalled correctly
CYG_TEST_CHECK( E_OK == ercd, "T2 wait bad ercd" );
// here we know that the op completed OK
if ( (MEMFIXEDGET == wait) || (MEMVARGET == wait) ) {
// it was a successful memory alloc of whichever type,
// so we can save away a copy of t2vp for working round an
// implicit storeleak problem when the task trying to allocate
// is signalled then killed:
CYG_TEST_CHECK( NULL != t2vp, "No t2vp allocated!" );
t2vp_backup = t2vp;
}
break;
case TIMEOUT:
case SUSPEND_TIMEOUT_RESUME:
// we expect to have timed out - if it's a timeout op.
CYG_TEST_CHECK( E_TMOUT == ercd, "T2 timeout bad ercd, !E_TMOUT" );
break;
case RELEASE:
case SUSPEND_RELEASE_RESUME:
// we expect to have suffered a release wait.
CYG_TEST_CHECK( E_RLWAI == ercd, "T2 release bad ercd, !E_RLWAI" );
break;
case DELETE:
case SUSPEND_DELETE_RESUME:
// we expect to be told the object is gone
CYG_TEST_CHECK( E_DLT == ercd, "T2 release bad ercd, !E_DLT" );
break;
case KILL:
case SUSPEND_KILL:
case SUSPEND_SIGNAL_KILL:
case SUSPEND_TIMEOUT_KILL:
case SUSPEND_RELEASE_KILL:
case SUSPEND_DELETE_KILL:
// we expect to have been killed here, ie. this won't execute!
CYG_TEST_FAIL( "Task 2 ran to completion!" );
break;
default:
CYG_TEST_FAIL( "bad switch" );
break;
}
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF testcx7.cxx
/v2_0/tests/testcx8.cxx
0,0 → 1,395
//===========================================================================
//
// testcx8.cxx
//
// uITRON "C++" test program eight
//
//===========================================================================
//####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-10-14
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough semaphores */ \
defined( CYGPKG_UITRON_SEMAS ) && \
(CYGNUM_UITRON_SEMAS >= 3) && \
(CYGNUM_UITRON_SEMAS < 90) && \
( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
volatile int intercount = 0;
INT scratch;
 
void newtask( unsigned int arg );
 
T_CTSK t_ctsk = { NULL, 0, (FP)&newtask, 1, CYGNUM_UITRON_STACK_SIZE };
T_RTSK t_rtsk;
 
extern "C" {
void task1( unsigned int arg );
void task2( unsigned int arg );
void task3( unsigned int arg );
void task4( unsigned int arg );
}
 
void task1( unsigned int arg )
{
ER ercd;
 
CYG_TEST_INFO( "Task 1 running" );
 
// change us to prio 3 for flexibility
ercd = chg_pri( 0, 3 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
 
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
// first, check that we can delete a task:
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_tsk( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
ercd = del_tsk( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
ercd = cre_tsk( -6, &t_ctsk );
CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
ercd = cre_tsk( 99, &t_ctsk );
CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
ercd = cre_tsk( 2, &t_ctsk );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
// try a pre-existing object - ourselves!
ercd = cre_tsk( 1, &t_ctsk );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
// try deleting an active task
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 2, 22222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
// Task 2 is now ready-to-run, lower prio than us
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
// Task 2 is now sleeping
CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
// try deleting a running task - ourselves!
ercd = del_tsk( 1 );
CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
// terminate task 2; should then be OK to delete it
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
// and check it is deleted
ercd = sta_tsk( 2, 99 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
ercd = chg_pri( 2, 6 );
CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
ercd = sus_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
ercd = rsm_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
ercd = frsm_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
ercd = can_wup( &scratch, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
ercd = ref_tsk( &t_rtsk, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
// recreate task2, with the same function
t_ctsk.task = (FP)&task2;
t_ctsk.itskpri = 7;
ercd = cre_tsk( 2, &t_ctsk );
CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
ercd = ref_tsk( &t_rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
CYG_TEST_CHECK( TTS_DMT == t_rtsk.tskstat,
"Bad tskstat in new task2 !TTS_DMT" );
CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
// now start the task and do the same lot again...
ercd = cre_tsk( 2, &t_ctsk );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
// try deleting an active task
ercd = sta_tsk( 2, 22222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
// Task 2 is now ready-to-run, lower prio than us
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
// Task 2 is now sleeping
ercd = ref_tsk( &t_rtsk, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
CYG_TEST_CHECK( TTS_WAI == t_rtsk.tskstat,
"Bad tskstat in new task2 !TTS_WAI" );
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
// up its priority
ercd = chg_pri( 2, 1 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
// awaken task 2; it will then exit-and-delete itself:
CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
// and check it is deleted
ercd = sta_tsk( 2, 99 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
ercd = chg_pri( 2, 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
ercd = sus_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
ercd = rsm_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
ercd = frsm_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
ercd = can_wup( &scratch, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
ercd = ref_tsk( &t_rtsk, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
ercd = del_tsk( 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_tsk( 2, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_tsk bad ercd !E_PAR" );
#endif
t_ctsk.stksz = 0x40000000;
ercd = cre_tsk( 2, &t_ctsk );
CYG_TEST_CHECK( E_NOMEM == ercd, "cre_tsk bad ercd !E_NOMEM" );
t_ctsk.stksz = CYGNUM_UITRON_STACK_SIZE;
CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
#endif // we can test bad param error returns
 
ercd = del_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
t_ctsk.task = (FP)&task4;
t_ctsk.itskpri = 9;
ercd = cre_tsk( 3, &t_ctsk );
CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
// check we can delete it again immediately
ercd = del_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
ercd = ref_tsk( &t_rtsk, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
t_ctsk.task = (FP)&newtask;
t_ctsk.itskpri = 1;
ercd = cre_tsk( 3, &t_ctsk );
CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
ercd = sta_tsk( 3, 999 );
CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
// it should have run now, and exited
CYG_TEST_CHECK( 5 == intercount, "bad intercount !5" );
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
// and check that it will just run again...
ercd = sta_tsk( 3, 999 );
CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
// it should have run now, and exited
CYG_TEST_CHECK( 7 == intercount, "bad intercount !7" );
ercd = wai_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
// all done.
 
CYG_TEST_PASS("create/delete tasks");
 
// all done
CYG_TEST_EXIT( "All done" );
#else // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
CYG_TEST_NA( "Tasks do not have create/delete enabled" );
#endif // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
ext_tsk();
}
 
 
 
void newtask( unsigned int arg )
{
ER ercd;
int i;
CYG_TEST_INFO( "Newtask running" );
CYG_TEST_CHECK( 999 == arg, "Bad arg to newtask() !999" );
ercd = get_tid( &i );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 3 == i, "tid not 3" );
intercount++;
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
intercount++;
// and just return
}
 
void task2( unsigned int arg )
{
ER ercd;
int i;
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &i );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == i, "tid not 2" );
if ( 22222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 22222" );
 
intercount++;
 
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
 
intercount++;
 
exd_tsk(); // if we are not killed first
 
intercount++; // shouldn't happen
}
 
void task3( unsigned int arg )
{
CYG_TEST_FAIL( "How come I'm being run?" );
}
 
void task4( unsigned int arg )
{
CYG_TEST_FAIL( "How come I'm being run?" );
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF testcx8.cxx
/v2_0/tests/testcxx.cxx
0,0 → 1,817
//===========================================================================
//
// testcxx.cxx
//
// uITRON "C++" test program
//
//===========================================================================
//####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-03-13
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
volatile int intercom = 0;
volatile int intercount = 0;
INT scratch = 0;
 
extern "C" {
void task1( unsigned int arg );
void task2( unsigned int arg );
void task3( unsigned int arg );
void task4( unsigned int arg );
}
 
 
#ifndef CYGSEM_KERNEL_SCHED_TIMESLICE
#define TIMESLICEMSG "Assuming no kernel timeslicing"
#define TSGO() (1)
#define TSRELEASE() CYG_EMPTY_STATEMENT
#define TSSTOP() CYG_EMPTY_STATEMENT
#define TSLOCK() CYG_EMPTY_STATEMENT
#define TSUNLOCK() CYG_EMPTY_STATEMENT
#define ICWAIT( _i_ ) CYG_EMPTY_STATEMENT
 
#else
// Now follow some nasty bodges to control the scheduling when basically it
// isn't controlled ie. timeslicing is on. It's bodgy because we're
// testing normal synchronization methods, so we shouldn't rely on them for
// comms between threads here. Instead there's a mixture of communicating
// via a flag (ts_interlock) which stops the "controlled" thread running
// away, and waiting for the controlled thread to run enough for us.
//
// Tasks 3 and 4 are waited for by the control task: task 3 locks the
// scheduler so is immediately descheduled when it unlocks it, task 4 does
// waiting-type operations, so we must give it chance to run by yielding a
// few times ourselves. Note the plain constant in ICWAIT() below.
 
#define TIMESLICEMSG "Assuming kernel timeslicing ENABLED"
volatile int ts_interlock = 0;
#define TSGO() (ts_interlock)
#define TSRELEASE() ts_interlock = 1
#define TSSTOP() ts_interlock = 0
 
#define TSLOCK() CYG_MACRO_START \
ER ercd2 = dis_dsp(); \
CYG_TEST_CHECK( E_OK == ercd2, "dis_dsp (TSLOCK) bad ercd2" ); \
CYG_MACRO_END
 
#define TSUNLOCK() CYG_MACRO_START \
ER ercd3 = ena_dsp(); \
CYG_TEST_CHECK( E_OK == ercd3, "ena_dsp (TSUNLOCK) bad ercd3" ); \
CYG_MACRO_END
 
#define ICWAIT( _i_ ) CYG_MACRO_START \
int loops; \
for ( loops = 3; (0 < loops) || ((_i_) > intercount); loops-- ) { \
ER ercd4 = rot_rdq( 0 ); /* yield */ \
CYG_TEST_CHECK( E_OK == ercd4, "rot_rdq (ICWAIT) bad ercd4" ); \
} \
CYG_MACRO_END
#endif // CYGSEM_KERNEL_SCHED_TIMESLICE
 
/*
#define IC() \
CYG_MACRO_START \
static char *msgs[] = { "ZERO", "ONE", "TWO", "THREE", "FOUR", "LOTS" }; \
CYG_TEST_INFO( msgs[ intercount > 5 ? 5 : intercount ] ); \
CYG_MACRO_END
*/
 
// #define CYG_TEST_UITRON_TEST1_LOOPING 1
 
void task1( unsigned int arg )
{
ER ercd;
T_RTSK ref_tskd;
 
#ifdef CYG_TEST_UITRON_TEST1_LOOPING
while ( 1 ) {
#endif // CYG_TEST_UITRON_TEST1_LOOPING
 
CYG_TEST_INFO( "Task 1 running" );
CYG_TEST_INFO( TIMESLICEMSG );
 
intercom = 0;
intercount = 0;
 
CYG_TEST_INFO( "Testing get_tid and ref_tsk" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = get_tid( NULL );
CYG_TEST_CHECK( E_PAR == ercd, "get_tid bad ercd !E_PAR" );
#endif
ercd = ref_tsk( &ref_tskd, -6 );
CYG_TEST_CHECK( E_ID == ercd, "ref_tsk bad ercd !E_ID" );
ercd = ref_tsk( &ref_tskd, 99 );
CYG_TEST_CHECK( E_ID == ercd, "ref_tsk bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = ref_tsk( NULL, 1 );
CYG_TEST_CHECK( E_PAR == ercd, "ref_tsk bad ercd !E_PAR" );
#endif
#endif // we can test bad param error returns
ercd = ref_tsk( &ref_tskd, 1 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_RUN == ref_tskd.tskstat, "Bad task status 1" );
ercd = ref_tsk( &ref_tskd, 0 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_RUN == ref_tskd.tskstat, "Bad task status 0" );
ercd = ref_tsk( &ref_tskd, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_DMT == ref_tskd.tskstat, "Bad task status 2" );
CYG_TEST_CHECK( 2 == ref_tskd.tskpri, "Bad task prio 2" );
 
ercd = rsm_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk DMT bad ercd !E_OBJ" );
ercd = frsm_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk DMT bad ercd !E_OBJ" );
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai DMT bad ercd !E_OBJ" );
ercd = sus_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "sus_tsk DMT bad ercd !E_OBJ" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk DMT bad ercd !E_OBJ" );
ercd = can_wup( &scratch, 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "can_wup DMT bad ercd !E_OBJ" );
 
CYG_TEST_PASS( "get_tid, ref_tsk" );
 
CYG_TEST_INFO( "Testing prio change and start task" );
ercd = sta_tsk( 2, 99 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
 
// drop pri of task 2
ercd = chg_pri( 2, 4 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ref_tsk( &ref_tskd, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( TTS_RDY == ref_tskd.tskstat, "Bad task status 2" );
CYG_TEST_CHECK( 4 == ref_tskd.tskpri, "Bad task prio 2" );
 
// drop our pri below task 2
ercd = chg_pri( 0, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
 
ercd = ref_tsk( &ref_tskd, 1 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( 5 == ref_tskd.tskpri, "Bad task prio 1" );
ercd = ref_tsk( &ref_tskd, 0 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
CYG_TEST_CHECK( 5 == ref_tskd.tskpri, "Bad task prio 0" );
ercd = ref_tsk( &ref_tskd, 2 );
CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
// it will have run to completion and regained its original prio
CYG_TEST_CHECK( 2 == ref_tskd.tskpri, "Bad task prio 2" );
CYG_TEST_CHECK( TTS_DMT == ref_tskd.tskstat, "Bad task status 2" );
 
// retest these now that the task has executed once
ercd = rsm_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk DMT bad ercd !E_OBJ" );
ercd = frsm_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk DMT bad ercd !E_OBJ" );
ercd = rel_wai( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai DMT bad ercd !E_OBJ" );
ercd = sus_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "sus_tsk DMT bad ercd !E_OBJ" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk DMT bad ercd !E_OBJ" );
ercd = can_wup( &scratch, 2 );
CYG_TEST_CHECK( E_OBJ == ercd, "can_wup DMT bad ercd !E_OBJ" );
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = chg_pri( -6, 9 );
CYG_TEST_CHECK( E_ID == ercd, "chg_pri bad ercd !E_ID" );
ercd = chg_pri( 99, 9 );
CYG_TEST_CHECK( E_ID == ercd, "chg_pri bad ercd !E_ID" );
ercd = sta_tsk( -6, 99 );
CYG_TEST_CHECK( E_ID == ercd, "sta_tsk bad ercd !E_ID" );
ercd = sta_tsk( 99, 99 );
CYG_TEST_CHECK( E_ID == ercd, "sta_tsk bad ercd !E_ID" );
#endif // we can test bad param error returns
 
CYG_TEST_PASS( "sta_tsk, chg_pri" );
 
CYG_TEST_INFO( "Testing delay and dispatch disabling" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
#endif // we can test bad param error returns
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
CYG_TEST_PASS( "dly_tsk, ena_dsp, dis_dsp" );
CYG_TEST_INFO( "Testing ready queue manipulation" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ercd = rot_rdq( 4 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ercd = rot_rdq( 5 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = rot_rdq( -6 );
CYG_TEST_CHECK( E_PAR == ercd, "rot_rdq bad ercd !E_PAR" );
ercd = rot_rdq( 99 );
CYG_TEST_CHECK( E_PAR == ercd, "rot_rdq bad ercd !E_PAR" );
#endif // we can test bad param error returns
CYG_TEST_PASS( "rot_rdq" );
 
CYG_TEST_INFO( "Testing suspend/resume" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = sus_tsk( -6 );
CYG_TEST_CHECK( E_ID == ercd, "sus_tsk bad ercd !E_ID" );
ercd = sus_tsk( 99 );
CYG_TEST_CHECK( E_ID == ercd, "sus_tsk bad ercd !E_ID" );
ercd = rsm_tsk( -6 );
CYG_TEST_CHECK( E_ID == ercd, "rsm_tsk bad ercd !E_ID" );
ercd = rsm_tsk( 99 );
CYG_TEST_CHECK( E_ID == ercd, "rsm_tsk bad ercd !E_ID" );
ercd = frsm_tsk( -6 );
CYG_TEST_CHECK( E_ID == ercd, "frsm_tsk bad ercd !E_ID" );
ercd = frsm_tsk( 99 );
CYG_TEST_CHECK( E_ID == ercd, "frsm_tsk bad ercd !E_ID" );
#endif // we can test bad param error returns
// drop task 3 pri to same as us
CYG_TEST_CHECK( 0 == intercount, "intercount != 0" );
 
intercom = 3; // tell T3 to loop
TSRELEASE();
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 3, 66 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 3, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
 
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 1 );
CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
ercd = sus_tsk( 3 );
TSRELEASE();
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
intercom = 0; // bad data to T3
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
intercom = 3; // tell T3 to loop
TSRELEASE();
ercd = rsm_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 2 );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
 
CYG_TEST_INFO( "Command task 3 inner loop stop" );
intercom = 2 + 4;
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
ercd = sus_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
intercom = 0; // bad data to T3
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ercd = sus_tsk( 3 ); // suspend AGAIN
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
ercd = sus_tsk( 3 ); // AND AGAIN
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
ercd = rsm_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
ercd = rsm_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
intercom = 3; // tell T3 to loop
TSRELEASE();
ercd = rsm_tsk( 3 ); // expect restart this time
CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 3 );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
 
CYG_TEST_INFO( "Command task 3 inner loop stop 2" );
intercom = 2 + 4;
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
ercd = sus_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
intercom = 0; // bad data to T3
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
ercd = sus_tsk( 3 ); // suspend AGAIN
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
ercd = sus_tsk( 3 ); // AND AGAIN
CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
intercom = 3; // tell T3 to loop
TSRELEASE();
ercd = frsm_tsk( 3 ); // expect restart this time
CYG_TEST_CHECK( E_OK == ercd, "frsm_tsk bad ercd" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 4 );
CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
 
TSRELEASE();
ercd = rsm_tsk( 3 ); // try it again
CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk bad ercd !E_OBJ" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 5 );
CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
 
TSRELEASE();
ercd = frsm_tsk( 3 ); // try it again
CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk bad ercd !E_OBJ" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 6 );
CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
 
CYG_TEST_INFO( "Command task 3 all loops stop" );
intercom = 4 + 8;
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
intercom = intercount = 0;
 
CYG_TEST_PASS( "sus_tsk, rsm_tsk, frsm_tsk" );
 
CYG_TEST_INFO( "Testing sleep/wakeup stuff" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = wup_tsk( -6 );
CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
ercd = wup_tsk( 99 );
CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
ercd = can_wup( &scratch, -6 );
CYG_TEST_CHECK( E_ID == ercd, "can_wup bad ercd !E_ID" );
ercd = can_wup( &scratch, 99 );
CYG_TEST_CHECK( E_ID == ercd, "can_wup bad ercd !E_ID" );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = can_wup( NULL, 2 );
CYG_TEST_CHECK( E_PAR == ercd, "can_wup bad ercd !E_PAR" );
#endif
ercd = wup_tsk( 0 ); // not ourself
CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
ercd = wup_tsk( 1 ); // ourself
CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk bad ercd !E_OBJ" );
#endif // we can test bad param error returns
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = tslp_tsk( -6 );
CYG_TEST_CHECK( E_PAR == ercd, "tslp_tsk bad ercd !E_PAR" );
#endif // we can test bad param error returns
ercd = tslp_tsk( TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
ercd = tslp_tsk( 5 );
CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = tslp_tsk( TMO_FEVR );
CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
ercd = tslp_tsk( TMO_POL );
CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
ercd = tslp_tsk( 5 );
CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = tslp_tsk( -6 );
CYG_TEST_CHECK( E_PAR == ercd, "tslp_tsk bad ercd !E_PAR" );
#endif // we can test bad param error returns
ercd = tslp_tsk( TMO_POL );
CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
ercd = tslp_tsk( 5 );
CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
 
// drop task 4 pri to same as us
intercount = 0;
intercom = 1; // test plain slp_tsk
TSRELEASE();
ercd = chg_pri( 4, 5 );
CYG_TEST_CHECK( E_OBJ == ercd, "chg_pri bad ercd" );
 
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 4, 77 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 4, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
 
ercd = wup_tsk( 4 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 1 );
CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
intercom = 2; // test tslp_tsk
TSRELEASE();
ercd = wup_tsk( 4 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 2 );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
intercom = 3; // test tslp_tsk
TSRELEASE();
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
intercom = 1; // test slp_tsk next...
ercd = dly_tsk( 20 ); // without a wup
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
ICWAIT( 3 );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
 
intercom = 1; // ...test slp_tsk
TSRELEASE();
ercd = dly_tsk( 20 ); // without a wup (yet)
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
TSRELEASE();
ercd = tslp_tsk( 20 ); // yield again
CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
TSRELEASE();
ercd = rot_rdq( 0 ); // and again
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
TSRELEASE();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rot_rdq( 0 ); // and yield
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 4 );
CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
 
intercom = 1; // test slp_tsk
TSRELEASE();
ercd = dly_tsk( 20 ); // without a wup (yet)
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
 
// this wup will restart it when we yield:
TSLOCK();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
// these will count up:
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
scratch = -1;
ercd = can_wup( &scratch, 4 );
CYG_TEST_CHECK( E_OK == ercd, "can_wup bad ercd" );
CYG_TEST_CHECK( 2 == scratch, "Cancelled wups not 2" );
CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
TSUNLOCK();
 
intercom = 4; // do nothing
TSRELEASE();
ercd = rot_rdq( 0 ); // and yield
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 5 );
CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
TSRELEASE();
ercd = dly_tsk( 20 ); // let it do nothing
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
TSRELEASE();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
TSRELEASE();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
TSRELEASE();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
TSRELEASE();
ercd = dly_tsk( 20 ); // lots of wups but no sleep
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
scratch = -1;
ercd = can_wup( &scratch, 4 );
CYG_TEST_CHECK( E_OK == ercd, "can_wup bad ercd" );
CYG_TEST_CHECK( 3 == scratch, "Cancelled wups not 3" );
// now check that they are cancelled by doing a wait again
intercom = 1; // test slp_tsk
TSRELEASE();
ercd = rot_rdq( 0 ); // still without a wup
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 ); // still without a wup
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
intercom = 4; // do nothing next
TSRELEASE();
ICWAIT( 6 );
CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
ercd = rot_rdq( 0 ); // still without a wup
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
TSRELEASE();
ercd = wup_tsk( 4 ); // now issue a wup
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = rot_rdq( 0 ); // it will run now
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
TSRELEASE();
ercd = rot_rdq( 0 ); // it will run now
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 7 );
CYG_TEST_CHECK( 7 == intercount, "intercount != 7" );
 
TSRELEASE();
intercom = 99; // exit, all done
ercd = rot_rdq( 0 ); // let it run
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
ICWAIT( 8 );
CYG_TEST_CHECK( 8 == intercount, "intercount != 8" );
 
TSRELEASE();
ercd = rot_rdq( 0 ); // let it run
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
CYG_TEST_CHECK( 8 == intercount, "intercount != 8" );
CYG_TEST_PASS( "wup_tsk, can_wup, slp_tsk, tslp_tsk" );
 
#ifdef CYG_TEST_UITRON_TEST1_LOOPING
chg_pri( 1, 1 );
rot_rdq( 0 );
ter_tsk( 2 );
rot_rdq( 0 );
ter_tsk( 3 );
rot_rdq( 0 );
ter_tsk( 4 );
rot_rdq( 0 );
}
#endif // CYG_TEST_UITRON_TEST1_LOOPING
 
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
CYG_TEST_PASS( "Task 2 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
if ( 99 != arg )
CYG_TEST_FAIL( "Task 2 arg not 99" );
ext_tsk();
CYG_TEST_FAIL( "Task 2 failed to exit" );
}
 
void task3( unsigned int arg )
{
ER ercd;
TSLOCK();
CYG_TEST_PASS("Task3 running");
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 3 == scratch, "tid not 3" );
if ( 66 != arg )
CYG_TEST_FAIL( "Task 3 arg not 66" );
 
while ( 2 & intercom ) {
while ( 1 & intercom ) {
intercount++;
TSSTOP();
do {
TSUNLOCK();
ercd = rot_rdq( 0 ); // yield()
TSLOCK();
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq 1 (task3) bad ercd" );
} while ( !TSGO() );
}
CYG_TEST_CHECK( 4 & intercom, "should not have got here yet 1" );
TSSTOP();
do {
TSUNLOCK();
ercd = rot_rdq( 0 ); // yield()
TSLOCK();
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq 2 (task3) bad ercd" );
} while ( !TSGO() );
}
CYG_TEST_CHECK( 8 & intercom, "should not have got here yet 2" );
TSUNLOCK();
ext_tsk();
CYG_TEST_FAIL( "Task 3 failed to exit" );
}
 
void task4( unsigned int arg )
{
ER ercd;
CYG_TEST_PASS("Task4 running");
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 4 == scratch, "tid not 4" );
if ( 77 != arg )
CYG_TEST_FAIL( "Task 4 arg not 77" );
while ( 1 ) {
switch ( intercom ) {
case 1:
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk (task4) bad ercd" );
break;
case 2:
ercd = tslp_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk (task4) bad ercd" );
break;
case 3:
ercd = tslp_tsk( 10 );
CYG_TEST_CHECK( E_TMOUT == ercd,
"slp_tsk (task4) bad ercd !E_TMOUT" );
break;
case 4:
// busily do nothing
while ( 4 == intercom ) {
ercd = rot_rdq( 0 );
CYG_TEST_CHECK( E_OK == ercd,
"rot_rdq (task4 idle) bad ercd" );
}
break;
case 99:
goto out;
default:
CYG_TEST_FAIL( "Task 4 bad intercom" );
goto out;
}
intercount++;
TSSTOP();
do {
ercd = rot_rdq( 0 ); // yield()
CYG_TEST_CHECK( E_OK == ercd, "rot_rdq (task4) bad ercd" );
} while ( !TSGO() );
}
out:
ext_tsk();
CYG_TEST_FAIL( "Task 4 failed to exit" );
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF testcxx.cxx
/v2_0/tests/testcx9.cxx
0,0 → 1,492
//===========================================================================
//
// testcx9.cxx
//
// uITRON "C++" test program nine
//
//===========================================================================
//####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-10-16
// Purpose: uITRON API testing
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#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 ) && \
\
/* test configuration for enough fixed memory pools */ \
defined( CYGPKG_UITRON_MEMPOOLFIXED ) && \
(CYGNUM_UITRON_MEMPOOLFIXED >= 3) && \
(CYGNUM_UITRON_MEMPOOLFIXED < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3 ) && \
\
/* test configuration for enough variable mempools */ \
defined( CYGPKG_UITRON_MEMPOOLVAR ) && \
(CYGNUM_UITRON_MEMPOOLVAR >= 3) && \
(CYGNUM_UITRON_MEMPOOLVAR < 90) && \
( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) || \
CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3 ) && \
\
/* the end of the large #if statement */ \
1
 
// ============================ END ============================
 
 
 
#include <cyg/compat/uitron/uit_func.h> // uITRON
 
externC void
cyg_package_start( void )
{
CYG_TEST_INIT();
CYG_TEST_INFO( "Calling cyg_uitron_start()" );
cyg_uitron_start();
}
 
VP vp;
 
T_CMPL t_cmpl = { NULL, 0, 1000 };
T_RMPL t_rmpl;
T_CMPF t_cmpf = { NULL, 0, 10, 100 };
T_RMPF t_rmpf;
 
 
extern "C" {
void task1( unsigned int arg );
void task2( unsigned int arg );
void task3( unsigned int arg );
void task4( unsigned int arg );
}
 
void task1( unsigned int arg )
{
ER ercd;
int tests = 0;
 
CYG_TEST_INFO( "Task 1 running" );
 
ercd = dis_dsp();
CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
ercd = sta_tsk( 2, 22222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
ercd = ena_dsp();
CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
ercd = dly_tsk( 10 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
tests++;
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_mpf( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_mpf bad ercd !E_ID" );
ercd = del_mpf( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_mpf bad ercd !E_ID" );
ercd = cre_mpf( -6, &t_cmpf );
CYG_TEST_CHECK( E_ID == ercd, "cre_mpf bad ercd !E_ID" );
ercd = cre_mpf( 99, &t_cmpf );
CYG_TEST_CHECK( E_ID == ercd, "cre_mpf bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
// [first get a valid block from it for the freeing test later]
ercd = pget_blf( &vp, 3 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
ercd = cre_mpf( 3, &t_cmpf );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_mpf bad ercd !E_OBJ" );
// delete it so we can play
ercd = del_mpf( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
// check it is deleted
ercd = rel_blf( 3, vp ); // vp did come from this pool
CYG_TEST_CHECK( E_NOEXS == ercd, "rel_blf bad ercd !E_NOEXS" );
ercd = pget_blf( &vp, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
ercd = tget_blf( &vp, 3, 10 );
CYG_TEST_CHECK( E_NOEXS == ercd, "tget_blf bad ercd !E_NOEXS" );
ercd = get_blf( &vp, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
ercd = ref_mpf( &t_rmpf, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mpf bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_mpf( 3, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_mpf bad ercd !E_PAR" );
#endif
t_cmpf.mpfatr = 0xfff;
ercd = cre_mpf( 3, &t_cmpf );
CYG_TEST_CHECK( E_RSATR == ercd, "cre_mpf bad ercd !E_RSATR" );
#endif // we can test bad param error returns
t_cmpf.mpfatr = 0;
t_cmpf.mpfcnt = 10000;
t_cmpf.blfsz = 100;
ercd = cre_mpf( 3, &t_cmpf );
CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpf bad ercd" );
t_cmpf.mpfcnt = 100;
t_cmpf.blfsz = 100000;
ercd = cre_mpf( 3, &t_cmpf );
CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpf bad ercd" );
// now create it well
t_cmpf.mpfatr = 0;
t_cmpf.mpfcnt = 10;
t_cmpf.blfsz = 100;
ercd = cre_mpf( 3, &t_cmpf );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
// and check we can use it
ercd = pget_blf( &vp, 3 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
ercd = tget_blf( &vp, 3, 10 );
CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
ercd = get_blf( &vp, 3 );
CYG_TEST_CHECK( E_OK == ercd, "get_blf bad ercd" );
ercd = rel_blf( 3, vp ); // vp did come from new pool
CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
ercd = rel_blf( 3, vp ); // vp already freed
CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
ercd = ref_mpf( &t_rmpf, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
 
// In order to wait on the pools, we must first consume all they have:
while ( E_OK == (ercd = pget_blf( &vp, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
while ( E_OK == (ercd = tget_blf( &vp, 2, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = get_blf( &vp, 1 );
CYG_TEST_CHECK( E_DLT == ercd, "get_blf bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = tget_blf( &vp, 2, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "tget_blf bad ercd !E_DLT" );
// check they are deleted
ercd = get_blf( &vp, 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
ercd = pget_blf( &vp, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
 
// re-create and do it again
t_cmpf.mpfcnt = 90;
t_cmpf.blfsz = 20;
ercd = cre_mpf( 1, &t_cmpf );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
t_cmpf.mpfcnt = 5;
t_cmpf.blfsz = 200;
ercd = cre_mpf( 2, &t_cmpf );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
 
// In order to wait on the pools, we must first consume all they have:
while ( E_OK == (ercd = pget_blf( &vp, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
while ( E_OK == (ercd = tget_blf( &vp, 2, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = get_blf( &vp, 1 );
CYG_TEST_CHECK( E_DLT == ercd, "get_blf bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = tget_blf( &vp, 2, 10 );
CYG_TEST_CHECK( E_DLT == ercd, "tget_blf bad ercd !E_DLT" );
// check they are deleted
ercd = tget_blf( &vp, 1, 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
ercd = get_blf( &vp, 2 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
 
CYG_TEST_PASS("create/delete fixed mempools");
#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
 
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
tests++;
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = del_mpl( -6 );
CYG_TEST_CHECK( E_ID == ercd, "del_mpl bad ercd !E_ID" );
ercd = del_mpl( 99 );
CYG_TEST_CHECK( E_ID == ercd, "del_mpl bad ercd !E_ID" );
ercd = cre_mpl( -6, &t_cmpl );
CYG_TEST_CHECK( E_ID == ercd, "cre_mpl bad ercd !E_ID" );
ercd = cre_mpl( 99, &t_cmpl );
CYG_TEST_CHECK( E_ID == ercd, "cre_mpl bad ercd !E_ID" );
#endif // we can test bad param error returns
// try a pre-existing object
// [first get a valid block from it for the freeing test later]
ercd = pget_blk( &vp, 3, 100 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
ercd = cre_mpl( 3, &t_cmpl );
CYG_TEST_CHECK( E_OBJ == ercd, "cre_mpl bad ercd !E_OBJ" );
// delete it so we can play
ercd = del_mpl( 3 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
// check it is deleted
ercd = rel_blk( 3, vp ); // vp did come from this pool
CYG_TEST_CHECK( E_NOEXS == ercd, "rel_blk bad ercd !E_NOEXS" );
ercd = pget_blk( &vp, 3, 100 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
ercd = tget_blk( &vp, 3, 100, 10 );
CYG_TEST_CHECK( E_NOEXS == ercd, "tget_blk bad ercd !E_NOEXS" );
ercd = get_blk( &vp, 3, 100 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
ercd = ref_mpl( &t_rmpl, 3 );
CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mpl bad ercd !E_NOEXS" );
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// now try creating it (badly)
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
ercd = cre_mpl( 3, NULL );
CYG_TEST_CHECK( E_PAR == ercd, "cre_mpl bad ercd !E_PAR" );
#endif
t_cmpl.mplatr = 0xfff;
ercd = cre_mpl( 3, &t_cmpl );
CYG_TEST_CHECK( E_RSATR == ercd, "cre_mpl bad ercd !E_RSATR" );
#endif // we can test bad param error returns
t_cmpl.mplatr = 0;
t_cmpl.mplsz = 100000000;
ercd = cre_mpl( 3, &t_cmpl );
CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpl bad ercd" );
// now create it well
t_cmpl.mplatr = 0;
t_cmpl.mplsz = 1000;
ercd = cre_mpl( 3, &t_cmpl );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
// and check we can use it
ercd = pget_blk( &vp, 3, 100 );
CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
ercd = pget_blk( &vp, 3, 100000000 ); // way too large
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
ercd = tget_blk( &vp, 3, 100, 10 );
CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
ercd = get_blk( &vp, 3, 100 );
CYG_TEST_CHECK( E_OK == ercd, "get_blk bad ercd" );
ercd = rel_blk( 3, vp ); // vp did come from new pool
CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
ercd = rel_blk( 3, vp ); // vp already freed
CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
ercd = ref_mpl( &t_rmpl, 3 );
CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
 
// In order to wait on the pools, we must first consume all they have:
while ( E_OK == (ercd = pget_blk( &vp, 1, 100 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
while ( E_OK == (ercd = tget_blk( &vp, 2, 100, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = get_blk( &vp, 1, 200 );
CYG_TEST_CHECK( E_DLT == ercd, "get_blk bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = tget_blk( &vp, 2, 100, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "tget_blk bad ercd !E_DLT" );
// check they are deleted
ercd = get_blk( &vp, 1, 200 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
ercd = pget_blk( &vp, 2, 20 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
 
// re-create and do it again
ercd = cre_mpl( 1, &t_cmpl );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
ercd = cre_mpl( 2, &t_cmpl );
CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
 
// In order to wait on the pools, we must first consume all they have:
while ( E_OK == (ercd = pget_blk( &vp, 1, 20 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
while ( E_OK == (ercd = tget_blk( &vp, 2, 400, 1 )) ) /* nothing */;
CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
// now wait while task 2 deletes the wait objects
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = get_blk( &vp, 1, 200 );
CYG_TEST_CHECK( E_DLT == ercd, "get_blk bad ercd !E_DLT" );
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
ercd = tget_blk( &vp, 2, 500, 20 );
CYG_TEST_CHECK( E_DLT == ercd, "tget_blk bad ercd !E_DLT" );
// check they are deleted
ercd = tget_blk( &vp, 1, 200, 1 );
CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
ercd = get_blk( &vp, 2, 20 );
CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
 
CYG_TEST_PASS("create/delete variable mempools");
#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
 
ercd = ter_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
ercd = dly_tsk( 5 );
CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
 
// all done
if ( 0 == tests ) {
CYG_TEST_NA( "No objects have create/delete enabled" );
}
else {
CYG_TEST_EXIT( "All done" );
}
ext_tsk();
}
 
 
 
void task2( unsigned int arg )
{
ER ercd;
int i;
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &i );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == i, "tid not 2" );
if ( 22222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 22222" );
 
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
 
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
ercd = del_mpf( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpf( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpf( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpf( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
 
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
ercd = del_mpl( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpl( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpl( 1 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
ercd = del_mpl( 2 );
CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
 
// we expect task2 to be killed here
CYG_TEST_FAIL( "Task 2 ran to completion!" );
}
 
void task3( unsigned int arg )
{
}
 
void task4( unsigned int arg )
{
}
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF testcx9.cxx
/v2_0/tests/testintr.cxx
0,0 → 1,892
//===========================================================================
//
// 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 ); \
} while ( 0 )
 
#define DELAY() \
if ( 1 & loops ) \
DELAYLOCKSCHED(); \
else \
LONGDELAY();
 
volatile int wakeups[ 5 ] = { 0,0,0,0,0 };
volatile int prewups[ 5 ] = { 0,0,0,0,0 };
 
 
void task1( unsigned int arg )
{
ER ercd;
int loops;
 
CYG_TEST_INFO( "Task 1 running" );
 
if ( cyg_test_is_simulator ) {
// take less time
events = EVENTSSIM;
}
 
 
// First test that dis_int() and ena_int() work for the clock interrupt
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
ercd = ena_int( 123456789 ); // Hope this is large enough to error
CYG_TEST_CHECK( E_PAR == ercd, "ena_int bad ercd !E_PAR" );
ercd = dis_int( 123456789 );
CYG_TEST_CHECK( E_PAR == ercd, "dis_int bad ercd !E_PAR" );
#endif
 
// This may take too long on a sim...
// On the synthetic target this test cannot run reliably - the
// loop counting assumes exclusive access to the processor.
#ifndef CYGPKG_HAL_SYNTH
if ( ! cyg_test_is_simulator ) {
SYSTIME t1, t2;
 
CYG_TEST_INFO( "Testing masking of clock interrupt" );
 
ercd = get_tim( &t1 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
 
// Wait for a tick. This loop acts as a synchronizer for the loop
// below, ensuring that it starts just after a tick.
for ( loops = 0; loops < 10000000; loops++ ) {
ercd = get_tim( &t2 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
if ( t2 != t1 )
break;
}
// Wait for next tick. Reset loops counter so we get the
// approximate loop count of one clock tick.
for ( loops = 0; loops < 10000000; loops++ ) {
ercd = get_tim( &t1 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
if ( t2 != t1 )
break;
}
 
// save how many loops could be executed in one tick. Multiply
// with 3 : we run loops in pairs below and add the time of
// one extra to avoid small variations to trigger failures.
intercom = loops * 3;
 
ercd = ena_int( clock_interrupt ); // was initialized already
CYG_TEST_CHECK( E_OK == ercd, "ena_int bad ercd" );
 
ercd = get_tim( &t1 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
 
// Wait for a tick
for ( loops = intercom; loops > 0; loops-- ) {
ercd = get_tim( &t2 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
if ( t2 != t1 )
break;
}
CYG_TEST_CHECK( 0 < loops, "No first tick" );
// and a second one
for ( ; loops > 0; loops-- ) {
ercd = get_tim( &t1 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
if ( t2 != t1 )
break;
}
CYG_TEST_CHECK( 0 < loops, "No second tick" );
// The PowerPC cannot disable the timer interrupt (separately).
#ifndef CYGPKG_HAL_POWERPC
ercd = dis_int( clock_interrupt ); // was initialized already
CYG_TEST_CHECK( E_OK == ercd, "dis_int bad ercd" );
 
ercd = get_tim( &t1 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
 
// Wait for a tick (should not happen)
for ( loops = intercom; loops > 0; loops-- ) {
ercd = get_tim( &t2 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
if ( t2 != t1 )
break;
}
CYG_TEST_CHECK( 0 == loops, "A tick occured - should be masked" );
CYG_TEST_CHECK( t1 == t2, "Times are different" );
 
// Now enable it again and ensure all is well:
ercd = ena_int( clock_interrupt );
CYG_TEST_CHECK( E_OK == ercd, "ena_int bad ercd" );
#endif
ercd = get_tim( &t1 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
 
// Wait for a tick
for ( loops = intercom; loops > 0; loops-- ) {
ercd = get_tim( &t2 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
if ( t2 != t1 )
break;
}
CYG_TEST_CHECK( 0 < loops, "No first tick" );
// and a second one
for ( ; loops > 0; loops-- ) {
ercd = get_tim( &t1 );
CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
if ( t2 != t1 )
break;
}
CYG_TEST_CHECK( 0 < loops, "No second tick" );
 
CYG_TEST_PASS( "dis_int(), ena_int() OK" );
}
#endif
intercom = 0;
 
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
 
// start all other tasks (our prio is 1 by default)
ercd = sta_tsk( 2, 222 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk 2 bad ercd" );
ercd = sta_tsk( 3, 333 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk 3 bad ercd" );
ercd = sta_tsk( 4, 444 );
CYG_TEST_CHECK( E_OK == ercd, "sta_tsk 4 bad ercd" );
// drop pri of other tasks all to 5
ercd = chg_pri( 2, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri 2 bad ercd" );
ercd = chg_pri( 3, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri 3 bad ercd" );
ercd = chg_pri( 4, 5 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri 4 bad ercd" );
 
// Test sleep/wakeup
intercom = SLP;
// Drop our prio to lower; they will run in turn until asleep
ercd = chg_pri( 1, 6 );
CYG_TEST_CHECK( E_OK == ercd, "chg_pri 1 (self) bad ercd" );
loops = 4;
do {
 
if ( 1 & loops )
CYG_TEST_INFO( " (toggling scheduler lock) " );
else
CYG_TEST_INFO( " (unlocked scheduler) " );
 
 
CYG_TEST_CHECK( 0 == wakeups[0], "init: Wakeups[0] hit" );
CYG_TEST_CHECK( 0 == wakeups[1], "init: Wakeups[1] hit" );
CYG_TEST_CHECK( prewups[2] == wakeups[2], "init: Wakeups[2] hit" );
CYG_TEST_CHECK( prewups[3] == wakeups[3], "init: Wakeups[3] hit" );
CYG_TEST_CHECK( prewups[4] == wakeups[4], "init: Wakeups[4] hit" );
 
// -------- TIMERS AND TIMESLICING DISABLED ---------
// install an isr that will wake them all up in turn
attach_isr( isr_wup_tsk );
DELAY();
detach_isr( isr_wup_tsk );
// -------- timers and timeslicing ENABLED ---------
CYG_TEST_CHECK( 0 == wakeups[0], "iwup_tsk: Wakeups[0] hit" );
CYG_TEST_CHECK( 0 == wakeups[1], "iwup_tsk: Wakeups[1] hit" );
CYG_TEST_CHECK( prewups[2] < wakeups[2], "iwup_tsk: Wakeups[2] not hit" );
CYG_TEST_CHECK( prewups[3] < wakeups[3], "iwup_tsk: Wakeups[3] not hit" );
CYG_TEST_CHECK( prewups[4] < wakeups[4], "iwup_tsk: Wakeups[4] not hit" );
diag_printf( "INFO:<(fg loops %10d) thread wakeups : %2d %2d %2d >\n", count,
wakeups[2] - prewups[2],
wakeups[3] - prewups[3],
wakeups[4] - prewups[4] );
prewups[2] = wakeups[2];
prewups[3] = wakeups[3];
prewups[4] = wakeups[4];
// -------- TIMERS AND TIMESLICING DISABLED ---------
// install an isr that will wake them all up in turn
attach_isr( isr_ret_wup );
DELAY();
detach_isr( isr_ret_wup );
// -------- timers and timeslicing ENABLED ---------
CYG_TEST_CHECK( 0 == wakeups[0], "ret_wup: Wakeups[0] hit" );
CYG_TEST_CHECK( 0 == wakeups[1], "ret_wup: Wakeups[1] hit" );
CYG_TEST_CHECK( prewups[2] < wakeups[2], "ret_wup: Wakeups[2] not hit" );
CYG_TEST_CHECK( prewups[3] < wakeups[3], "ret_wup: Wakeups[3] not hit" );
CYG_TEST_CHECK( prewups[4] < wakeups[4], "ret_wup: Wakeups[4] not hit" );
diag_printf( "INFO:<(fg loops %10d) thread ret_wups: %2d %2d %2d >\n", count,
wakeups[2] - prewups[2],
wakeups[3] - prewups[3],
wakeups[4] - prewups[4] );
prewups[2] = wakeups[2];
prewups[3] = wakeups[3];
prewups[4] = wakeups[4];
// move them on to waiting for a semaphore
intercom = SEM;
ercd = wup_tsk( 2 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk(2) bad ercd" );
ercd = wup_tsk( 3 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk(3) bad ercd" );
ercd = wup_tsk( 4 );
CYG_TEST_CHECK( E_OK == ercd, "wup_tsk(4) bad ercd" );
CYG_TEST_CHECK( 0 == wakeups[0], "wup_tsk: Wakeups[0] hit" );
CYG_TEST_CHECK( 0 == wakeups[1], "wup_tsk: Wakeups[1] hit" );
CYG_TEST_CHECK( prewups[2] + 1 == wakeups[2], "wup_tsk: Wakeups[2] not hit" );
CYG_TEST_CHECK( prewups[3] + 1 == wakeups[3], "wup_tsk: Wakeups[3] not hit" );
CYG_TEST_CHECK( prewups[4] + 1 == wakeups[4], "wup_tsk: Wakeups[4] not hit" );
prewups[2] = wakeups[2];
prewups[3] = wakeups[3];
prewups[4] = wakeups[4];
// -------- TIMERS AND TIMESLICING DISABLED ---------
// install an isr that will wake them all up in turn
attach_isr( isr_sig_sem );
DELAY();
detach_isr( isr_sig_sem );
// -------- timers and timeslicing ENABLED ---------
CYG_TEST_CHECK( 0 == wakeups[0], "isig_sem: Wakeups[0] hit" );
CYG_TEST_CHECK( 0 == wakeups[1], "isig_sem: Wakeups[1] hit" );
CYG_TEST_CHECK( prewups[2] < wakeups[2], "isig_sem: Wakeups[2] not hit" );
CYG_TEST_CHECK( prewups[3] < wakeups[3], "isig_sem: Wakeups[3] not hit" );
CYG_TEST_CHECK( prewups[4] < wakeups[4], "isig_sem: Wakeups[4] not hit" );
diag_printf( "INFO:<(fg loops %10d) semaphore waits: %2d %2d %2d >\n", count,
wakeups[2] - prewups[2],
wakeups[3] - prewups[3],
wakeups[4] - prewups[4] );
prewups[2] = wakeups[2];
prewups[3] = wakeups[3];
prewups[4] = wakeups[4];
 
// move them on to waiting for a flag
intercom = FLG;
ercd = sig_sem( 1 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem(1) bad ercd" );
ercd = sig_sem( 2 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem(2) bad ercd" );
ercd = sig_sem( 3 );
CYG_TEST_CHECK( E_OK == ercd, "sig_sem(3) bad ercd" );
 
CYG_TEST_CHECK( 0 == wakeups[0], "sig_sem: Wakeups[0] hit" );
CYG_TEST_CHECK( 0 == wakeups[1], "sig_sem: Wakeups[1] hit" );
CYG_TEST_CHECK( prewups[2] + 1 == wakeups[2], "sig_sem: Wakeups[2] not hit" );
CYG_TEST_CHECK( prewups[3] + 1 == wakeups[3], "sig_sem: Wakeups[3] not hit" );
CYG_TEST_CHECK( prewups[4] + 1 == wakeups[4], "sig_sem: Wakeups[4] not hit" );
prewups[2] = wakeups[2];
prewups[3] = wakeups[3];
prewups[4] = wakeups[4];
// -------- TIMERS AND TIMESLICING DISABLED ---------
// install an isr that will wake them all up in turn
attach_isr( isr_set_flg );
DELAY();
detach_isr( isr_set_flg );
// -------- timers and timeslicing ENABLED ---------
CYG_TEST_CHECK( 0 == wakeups[0], "iset_flg: Wakeups[0] hit" );
CYG_TEST_CHECK( 0 == wakeups[1], "iset_flg: Wakeups[1] hit" );
CYG_TEST_CHECK( prewups[2] < wakeups[2], "iset_flg: Wakeups[2] not hit" );
CYG_TEST_CHECK( prewups[3] < wakeups[3], "iset_flg: Wakeups[3] not hit" );
CYG_TEST_CHECK( prewups[4] < wakeups[4], "iset_flg: Wakeups[4] not hit" );
diag_printf( "INFO:<(fg loops %10d) flag waits/sets: %2d %2d %2d >\n", count,
wakeups[2] - prewups[2],
wakeups[3] - prewups[3],
wakeups[4] - prewups[4] );
prewups[2] = wakeups[2];
prewups[3] = wakeups[3];
prewups[4] = wakeups[4];
 
// move them on to waiting for a message box
intercom = MBX;
ercd = set_flg( 2, 0xfff );
CYG_TEST_CHECK( E_OK == ercd, "set_flg(2) bad ercd" );
ercd = set_flg( 3, 0xfff );
CYG_TEST_CHECK( E_OK == ercd, "set_flg(3) bad ercd" );
ercd = set_flg( 4, 0xfff );
CYG_TEST_CHECK( E_OK == ercd, "set_flg(4) bad ercd" );
CYG_TEST_CHECK( 0 == wakeups[0], "set_flg: Wakeups[0] hit" );
CYG_TEST_CHECK( 0 == wakeups[1], "set_flg: Wakeups[1] hit" );
CYG_TEST_CHECK( prewups[2] + 1 == wakeups[2], "set_flg: Wakeups[2] not hit" );
CYG_TEST_CHECK( prewups[3] + 1 == wakeups[3], "set_flg: Wakeups[3] not hit" );
CYG_TEST_CHECK( prewups[4] + 1 == wakeups[4], "set_flg: Wakeups[4] not hit" );
prewups[2] = wakeups[2];
prewups[3] = wakeups[3];
prewups[4] = wakeups[4];
// -------- TIMERS AND TIMESLICING DISABLED ---------
// install an isr that will wake them all up in turn
attach_isr( isr_snd_msg );
DELAY();
detach_isr( isr_snd_msg );
// -------- timers and timeslicing ENABLED ---------
 
CYG_TEST_CHECK( 0 == wakeups[0], "isnd_msg: Wakeups[0] hit" );
CYG_TEST_CHECK( 0 == wakeups[1], "isnd_msg: Wakeups[1] hit" );
CYG_TEST_CHECK( prewups[2] < wakeups[2], "isnd_msg: Wakeups[2] not hit" );
CYG_TEST_CHECK( prewups[3] < wakeups[3], "isnd_msg: Wakeups[3] not hit" );
CYG_TEST_CHECK( prewups[4] < wakeups[4], "isnd_msg: Wakeups[4] not hit" );
diag_printf( "INFO:<(fg loops %10d) message rec'pts: %2d %2d %2d >\n", count,
wakeups[2] - prewups[2],
wakeups[3] - prewups[3],
wakeups[4] - prewups[4] );
prewups[2] = wakeups[2];
prewups[3] = wakeups[3];
prewups[4] = wakeups[4];
 
// move them on to exiting, all done
if ( 1 == loops )
// then we are about to exit
intercom = EXIT;
else
intercom = SLP;
ercd = snd_msg( 2, (T_MSG *)&intercom );
CYG_TEST_CHECK( E_OK == ercd, "snd_msg(2) bad ercd" );
ercd = snd_msg( 3, (T_MSG *)&intercom );
CYG_TEST_CHECK( E_OK == ercd, "snd_msg(3) bad ercd" );
ercd = snd_msg( 4, (T_MSG *)&intercom );
CYG_TEST_CHECK( E_OK == ercd, "snd_msg(4) bad ercd" );
 
CYG_TEST_CHECK( 0 == wakeups[0], "snd_msg: Wakeups[0] hit" );
CYG_TEST_CHECK( 0 == wakeups[1], "snd_msg: Wakeups[1] hit" );
CYG_TEST_CHECK( prewups[2] + 1 == wakeups[2], "snd_msg: Wakeups[2] not hit" );
CYG_TEST_CHECK( prewups[3] + 1 == wakeups[3], "snd_msg: Wakeups[3] not hit" );
CYG_TEST_CHECK( prewups[4] + 1 == wakeups[4], "snd_msg: Wakeups[4] not hit" );
prewups[2] = wakeups[2];
prewups[3] = wakeups[3];
prewups[4] = wakeups[4];
 
CYG_TEST_PASS( "Tested ISR invoked uITRON functions" );
 
} while ( 0 < --loops );
 
CYG_TEST_EXIT( "All done" );
ext_tsk();
}
 
 
void body( int n )
{
unsigned int z;
ER ercd;
T_MSG *pk_msg;
 
do {
switch ( intercom ) {
case NOTHING:
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk (doing nothing)" );
continue;
case SLP:
ercd = slp_tsk();
CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
wakeups[ n ]++;
break;
case SEM:
ercd = wai_sem( n-1 ); // 1..3 for semas
CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
wakeups[ n ]++;
break;
case FLG:
ercd = wai_flg( &z, n, (1<<n), TWF_CLR | TWF_ANDW );
CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
CYG_TEST_CHECK( z & (1<<n), "Flag bit not set" );
wakeups[ n ]++;
break;
case MBX:
ercd = rcv_msg( &pk_msg, n );
CYG_TEST_CHECK( E_OK == ercd, "rcv_msg bad ercd" );
CYG_TEST_CHECK( pk_msg, "rcv_msg NULL msg" );
wakeups[ n ]++;
break;
case EXIT:
return;
}
} while ( 1 );
}
 
void task2( unsigned int arg )
{
ER ercd;
CYG_TEST_INFO( "Task 2 running" );
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
if ( 222 != arg )
CYG_TEST_FAIL( "Task 2 arg not 222" );
body(2);
CYG_TEST_INFO( "Task 2 exiting" );
ext_tsk();
CYG_TEST_FAIL( "Task 2 failed to exit" );
}
 
void task3( unsigned int arg )
{
ER ercd;
CYG_TEST_INFO("Task 3 running");
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 3 == scratch, "tid not 3" );
if ( 333 != arg )
CYG_TEST_FAIL( "Task 3 arg not 333" );
body(3);
CYG_TEST_INFO( "Task 3 exiting" );
ext_tsk();
CYG_TEST_FAIL( "Task 3 failed to exit" );
}
 
void task4( unsigned int arg )
{
ER ercd;
CYG_TEST_INFO("Task 4 running");
ercd = get_tid( &scratch );
CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
CYG_TEST_CHECK( 4 == scratch, "tid not 4" );
if ( 444 != arg )
CYG_TEST_FAIL( "Task 4 arg not 444" );
body(4);
CYG_TEST_INFO( "Task 4 exiting" );
ext_tsk();
CYG_TEST_FAIL( "Task 4 failed to exit" );
}
 
// ------------------------------------------------------------------------
// Start of C++ aware portion, so to speak.
//
 
#include <cyg/hal/hal_intr.h>
#include <cyg/kernel/intr.hxx>
#include <cyg/kernel/clock.hxx>
#include <cyg/kernel/sched.hxx>
#include <cyg/kernel/sched.inl>
 
void set_interrupt_number( void )
{
clock_interrupt = CYGNUM_HAL_INTERRUPT_RTC;
}
 
// This snippet stolen from kernel/.../clock.cxx to be able to detach
// the RTC from its interrupt source.
class Cyg_RealTimeClock
: public Cyg_Clock
{
public:
Cyg_Interrupt interrupt;
 
static cyg_uint32 isr(cyg_vector vector, CYG_ADDRWORD data);
 
static void dsr(cyg_vector vector, cyg_ucount32 count, CYG_ADDRWORD data);
 
Cyg_RealTimeClock();
};
 
 
static Cyg_Interrupt uit_intr(
(unsigned)CYGNUM_HAL_INTERRUPT_RTC, // Vector to attach to
0, // Queue priority
(unsigned)0, // Data pointer
&isr_wup_tsk, // Interrupt Service Routine
&cyg_uitron_dsr // Deferred Service Routine
);
 
void
attach_isr( unsigned int (*isr)(unsigned int, unsigned int) )
{
int inuse;
int old_ints;
Cyg_RealTimeClock *prtc = (Cyg_RealTimeClock *)Cyg_Clock::real_time_clock;
HAL_DISABLE_INTERRUPTS(old_ints);
HAL_INTERRUPT_MASK( CYGNUM_HAL_INTERRUPT_RTC );
prtc->interrupt.detach();
#ifndef CYGIMP_KERNEL_INTERRUPTS_CHAIN
// Only check that the vector was cleared when there's a specific
// vector for the RTC. In chain mode, other interrupt handlers
// may prevent the shared vector from being cleared when detaching
// the RTC ISR, and this assertion fails.
HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse );
CYG_TEST_CHECK( !inuse, "Failed to detach clock ISR" );
#endif
uit_intr = Cyg_Interrupt(
CYGNUM_HAL_INTERRUPT_RTC, // Vector to attach to
1, // Queue priority
0, // Data pointer
isr, // Interrupt Service Routine
cyg_uitron_dsr // Deferred Service Routine
);
uit_intr.attach();
HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse );
CYG_TEST_CHECK( inuse, "Failed to attach new ISR" );
ACK_CLOCK();
HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_RTC );
HAL_RESTORE_INTERRUPTS(old_ints);
}
 
void
detach_isr( unsigned int (*isr)(unsigned int, unsigned int) )
{
int inuse;
int old_ints;
Cyg_RealTimeClock *prtc = (Cyg_RealTimeClock *)Cyg_Clock::real_time_clock;
HAL_DISABLE_INTERRUPTS(old_ints);
HAL_INTERRUPT_MASK( CYGNUM_HAL_INTERRUPT_RTC );
uit_intr.detach();
#ifndef CYGIMP_KERNEL_INTERRUPTS_CHAIN
// See comment above in attach_isr.
HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse );
CYG_TEST_CHECK( !inuse, "Failed to detach my ISR" );
#endif
prtc->interrupt.attach();
HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse );
CYG_TEST_CHECK( inuse, "Failed to attach clock ISR" );
ACK_CLOCK();
HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_RTC );
HAL_RESTORE_INTERRUPTS(old_ints);
}
 
 
void
lock_sched( void )
{
cyg_uint32 l;
Cyg_Scheduler::lock();
l = Cyg_Scheduler::get_sched_lock();
CYG_TEST_CHECK( 0 < l, "lock: Sched not locked" );
CYG_TEST_CHECK( 2 > l, "lock: Sched already locked" );
}
 
void
unlock_sched( void )
{
cyg_uint32 l;
l = Cyg_Scheduler::get_sched_lock();
CYG_TEST_CHECK( 0 < l, "unlock: Sched not locked" );
CYG_TEST_CHECK( 2 > l, "unlock: Sched already locked" );
Cyg_Scheduler::unlock();
}
 
 
#else // not enough (or too many) uITRON objects configured in
#define N_A_MSG "not enough uITRON objects to run test"
#endif // not enough (or too many) uITRON objects configured in
#else // not C++ and some C++ specific options enabled
#define N_A_MSG "C++ specific options selected but this is C"
#endif // not C++ and some C++ specific options enabled
#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
#else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
#endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
#else // ! CYGIMP_THREAD_PRIORITY - can't test without it
#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
#else // ! CYGPKG_UITRON
#define N_A_MSG "uITRON Compatibility layer disabled"
#endif // CYGPKG_UITRON
 
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG defined ie. we are N/A.
 
// EOF testintr.c
/v2_0/include/uit_ifnc.inl
0,0 → 1,218
#ifndef CYGONCE_COMPAT_UITRON_UIT_IFNC_INL
#define CYGONCE_COMPAT_UITRON_UIT_IFNC_INL
//===========================================================================
//
// uit_ifnc.inl
//
// uITRON compatibility functions
//
//===========================================================================
//####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: 1999-08-16
// Purpose: uITRON compatibility functions
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#ifdef CYGPKG_UITRON
 
#ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
 
class Cyg_Uit_Action {
public:
typedef enum {
WUP_TSK,
SIG_SEM,
SET_FLG,
SND_MSG
} action;
};
 
extern volatile int cyg_uit_dsr_actions_head;
extern volatile int cyg_uit_dsr_actions_tail;
 
#define CYGNUM_UITRON_ISR_ACTION_QUEUEMASK (CYGNUM_UITRON_ISR_ACTION_QUEUESIZE-1)
 
#if ((~CYGNUM_UITRON_ISR_ACTION_QUEUEMASK) & \
~((~CYGNUM_UITRON_ISR_ACTION_QUEUEMASK)-1)) \
!= CYGNUM_UITRON_ISR_ACTION_QUEUESIZE
#error CYGNUM_UITRON_ISR_ACTION_QUEUESIZE not a power of 2
#endif
 
extern Cyg_Uit_Action::action
cyg_uit_dsr_actions[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
 
extern ID
cyg_uit_dsr_act_ids[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
 
extern CYG_ADDRWORD
cyg_uit_dsr_act_a1s[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
 
CYG_UIT_FUNC_INLINE
ER
iwup_tsk ( ID tskid )
{
#ifdef CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION
if ( 1 >= Cyg_Scheduler::get_sched_lock() ) {
// then this ISR is the first one, and the sched was locked by the
// interrupt code. So this is safe.
return wup_tsk( tskid );
}
#endif
register int i, head;
i = cyg_uit_dsr_actions_head;
head = CYGNUM_UITRON_ISR_ACTION_QUEUEMASK & ( 1 + i );
// If interrupts can be recursive, then there is a race here where a
// slot may be overwritten by a recursive interrupt, or actions from
// such lost; better though than having a slot contain *mixed* data
// from two intermingled interrupts.
if ( head != cyg_uit_dsr_actions_tail ) {
cyg_uit_dsr_actions_head = head;
cyg_uit_dsr_actions[ i ] = Cyg_Uit_Action::WUP_TSK;
cyg_uit_dsr_act_ids[ i ] = tskid;
}
return E_OK;
}
#ifdef CYGPKG_UITRON_SEMAS
#if 0 < CYG_UITRON_NUM( SEMAS )
CYG_UIT_FUNC_INLINE
ER
isig_sem ( ID semid )
{
#ifdef CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION
if ( 1 >= Cyg_Scheduler::get_sched_lock() ) {
// then this ISR is the first one, and the sched was locked by the
// interrupt code. So this is safe.
return sig_sem( semid );
}
#endif
register int i, head;
i = cyg_uit_dsr_actions_head;
head = CYGNUM_UITRON_ISR_ACTION_QUEUEMASK & ( 1 + i );
// If interrupts can be recursive, then there is a race here where a
// slot may be overwritten by a recursive interrupt, or actions from
// such lost; better though than having a slot contain *mixed* data
// from two intermingled interrupts.
if ( head != cyg_uit_dsr_actions_tail ) {
cyg_uit_dsr_actions_head = head;
cyg_uit_dsr_actions[ i ] = Cyg_Uit_Action::SIG_SEM;
cyg_uit_dsr_act_ids[ i ] = semid;
}
return E_OK;
}
#endif // 0 < CYG_UITRON_NUM( SEMAS )
#endif // CYGPKG_UITRON_SEMAS
 
#ifdef CYGPKG_UITRON_FLAGS
#if 0 < CYG_UITRON_NUM( FLAGS )
CYG_UIT_FUNC_INLINE
ER
iset_flg ( ID flgid, UINT setptn )
{
#ifdef CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION
if ( 1 >= Cyg_Scheduler::get_sched_lock() ) {
// then this ISR is the first one, and the sched was locked by the
// interrupt code. So this is safe.
return set_flg( flgid, setptn );
}
#endif
register int i, head;
i = cyg_uit_dsr_actions_head;
head = CYGNUM_UITRON_ISR_ACTION_QUEUEMASK & ( 1 + i );
// If interrupts can be recursive, then there is a race here where a
// slot may be overwritten by a recursive interrupt, or actions from
// such lost; better though than having a slot contain *mixed* data
// from two intermingled interrupts.
if ( head != cyg_uit_dsr_actions_tail ) {
cyg_uit_dsr_actions_head = head;
cyg_uit_dsr_actions[ i ] = Cyg_Uit_Action::SET_FLG;
cyg_uit_dsr_act_ids[ i ] = flgid;
cyg_uit_dsr_act_a1s[ i ] = (CYG_ADDRWORD)setptn;
}
return E_OK;
}
#endif // 0 < CYG_UITRON_NUM( FLAGS )
#endif // CYGPKG_UITRON_FLAGS
 
#ifdef CYGPKG_UITRON_MBOXES
#if 0 < CYG_UITRON_NUM( MBOXES )
CYG_UIT_FUNC_INLINE
ER
isnd_msg ( ID mbxid, T_MSG *pk_msg )
{
#ifdef CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION
if ( 1 >= Cyg_Scheduler::get_sched_lock() ) {
// then this ISR is the first one, and the sched was locked by the
// interrupt code. So this is safe.
return snd_msg( mbxid, pk_msg );
}
#endif
register int i, head;
i = cyg_uit_dsr_actions_head;
head = CYGNUM_UITRON_ISR_ACTION_QUEUEMASK & ( 1 + i );
// If interrupts can be recursive, then there is a race here where a
// slot may be overwritten by a recursive interrupt, or actions from
// such lost; better though than having a slot contain *mixed* data
// from two intermingled interrupts.
if ( head != cyg_uit_dsr_actions_tail ) {
cyg_uit_dsr_actions_head = head;
cyg_uit_dsr_actions[ i ] = Cyg_Uit_Action::SND_MSG;
cyg_uit_dsr_act_ids[ i ] = mbxid;
cyg_uit_dsr_act_a1s[ i ] = (CYG_ADDRWORD)pk_msg;
}
return E_OK;
}
#endif // 0 < CYG_UITRON_NUM( MBOXES )
#endif // CYGPKG_UITRON_MBOXES
// ========================================================================
 
#endif // CYGPKG_UITRON
 
#endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW
 
#endif // CYGONCE_COMPAT_UITRON_UIT_IFNC_INL
//EOF uit_ifnc.inl
/v2_0/include/uit_func.h
0,0 → 1,402
#ifndef CYGONCE_COMPAT_UITRON_UIT_FUNC_H
#define CYGONCE_COMPAT_UITRON_UIT_FUNC_H
//===========================================================================
//
// uit_func.h
//
// uITRON compatibility functions
//
//===========================================================================
//####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-03-13
// Purpose: uITRON compatibility functions
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
// ------------------------------------------------------------------------
// Source Code Organization
//
// First, see pkgconf/uitron.h for details of applicable configuration
// options.
//
// This file uit_func.h provides prototypes for the uITRON API. All the
// uITRON functions are listed here. The prototypes are configurable
// either to have C or C++ linkage, and if being compiled in a C++
// environment, to be inline.
//
// The function prototypes are all in terms of uITRON type definitions from
// uit_type.h, which is included at the head of uit_func.h.
//
// The implementations of the uITRON functions are in uit_func.inl, which
// is either included at the end of uit_func.h (if functions are inline) or
// in uit_func.cxx (if outline).
//
// uit_func.cxx provides some startup functions plus, if the uITRON
// functions are out of line, uit_func.inl is included to instantiate those
// functions.
//
// uITRON system objects (tasks, semaphores...) are described in
// uit_obj.hxx. This is a C++ file and is used by the implementation of
// the uITRON functions.
//
// The uITRON system objects are instantiated in uit_obj.cxx, which uses
// uit_obj.hxx to define the objects, and the configuration file
// pkgconf/uitron.h to construct them as required.
//
// The include graph from an application, which should only include
// uit_func.h, is similar to the following:
//
//
// [inline uITRON functions:]
//
// <your_app.c>
// . uit_func.h ; prototypes for funcs
// . . pkgconf/uitron.h ; configuration info
// . . uit_type.h ; typedefs for func args
// . (function prototypes)
// . . uit_func.inl ; full function bodies
// . . . uit_objs.hxx ; defs of uITRON data
// . . (function implementations)
//
//
// [out-of-line uITRON functions:]
//
// <your_app.c>
// . uit_func.h ; prototypes for funcs
// . . pkgconf/uitron.h ; configuration info
// . . uit_type.h ; typedefs for func args
// . (function prototypes)
//
//
// [other uITRON compilation units:]
//
// uit_func.cxx ; out-of-line functions
// . pkgconf/uitron.h ; configuration info
// . uit_func.h ; prototypes for funcs
// . . uit_type.h ; typedefs for func args
// . (function prototypes)
// . . uit_func.inl ; full function bodies
// . . . uit_objs.hxx ; defs of uITRON data
// . . (function implementations)
//
//
// uit_objs.cxx ; static uITRON data objects
// . pkgconf/uitron.h ; configuration info
// . uit_objs.hxx ; defs of uITRON data
// (static uITRON system objects)
//
//
// The various include files are protected against multiple inclusion and
// so may be safely re-included as convenient.
//
// ------------------------------------------------------------------------
 
#include <pkgconf/uitron.h> // uITRON setup CYGNUM_UITRON_SEMAS
// CYGPKG_UITRON et al
 
#ifdef CYGPKG_UITRON
 
#include <cyg/infra/cyg_type.h> // types; cyg_int32, CYG_ADDRWORD
 
#include <cyg/compat/uitron/uit_type.h> // uITRON types; ER ID TMO T_MSG
 
// ------------------------------------------------------------------------
// Object operations:
//
// The functions can be inlined in C compiled by C++, or C++ of course,
// and also outlined in extern "C" functions, eg. for taking the address
// of, or for use by a pure C program, or of course outlined in C++ for
// Code size reasons.
//
//
// Summary:
//
// IF compiling in C
// THEN functions must be C linkage and out of line:
// do NOT specify CYGIMP_UITRON_INLINE_FUNCS nor
// CYGIMP_UITRON_CPP_OUTLINE_FUNCS.
// IF compiling in C++
// THEN functions can be inline: specify CYGIMP_UITRON_INLINE_FUNCS
// OR by default, functions are out of line:
// outline functions can have C++ linkage:
// specify CYGIMP_UITRON_CPP_OUTLINE_FUNCS
// OR by default, outline functions have C linkage.
 
 
#ifdef __cplusplus
// C++ environment; functions can be inline or not as we please.
// If not inline they might as well be "C" linkage for sharing with
// any pure "C" code present.
 
#ifdef CYGIMP_UITRON_INLINE_FUNCS
 
#define CYG_UIT_FUNC_EXTERN_BEGIN
#define CYG_UIT_FUNC_EXTERN_END
#define CYG_UIT_FUNC_INLINE inline
#ifndef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
#define CYGPRI_UITRON_FUNCS_HERE_AND_NOW
#endif
 
#else
 
#ifdef CYGIMP_UITRON_CPP_OUTLINE_FUNCS
#define CYG_UIT_FUNC_EXTERN_BEGIN extern "C++" {
#define CYG_UIT_FUNC_EXTERN_END }
#else
#define CYG_UIT_FUNC_EXTERN_BEGIN extern "C" {
#define CYG_UIT_FUNC_EXTERN_END }
#endif
 
#define CYG_UIT_FUNC_INLINE
#endif
 
#else // !__cplusplus
// Vanilla "C" environment; external "C" linkage, no inline functions
 
#ifdef CYGIMP_UITRON_INLINE_FUNCS
#error "Cannot inline uITRON functions in pure C environment"
#endif
#ifdef CYGIMP_UITRON_CPP_OUTLINE_FUNCS
#error "Cannot use C++ linkage of outline fns in pure C environment"
#endif
 
#define CYG_UIT_FUNC_EXTERN_BEGIN
#define CYG_UIT_FUNC_EXTERN_END
#define CYG_UIT_FUNC_INLINE
 
#endif // !__cplusplus
 
// ========================================================================
// u I T R O N F U N C T I O N S
// The function declarations themselves:
 
CYG_UIT_FUNC_EXTERN_BEGIN
 
// this routine is outside the uITRON specification; call it from main() to
// start the uITRON tasks and scheduler. It does not return.
 
#ifdef CYGNUM_UITRON_START_TASKS
void cyg_uitron_start( void );
#endif
 
// ******************************************************
// *** 6.5 C Language Interfaces ***
// ******************************************************
 
// - Task Management Functions
 
ER cre_tsk ( ID tskid, T_CTSK *pk_ctsk );
ER del_tsk ( ID tskid );
ER sta_tsk ( ID tskid, INT stacd );
void ext_tsk ( void );
void exd_tsk ( void );
ER ter_tsk ( ID tskid );
 
ER dis_dsp ( void );
ER ena_dsp ( void );
ER chg_pri ( ID tskid, PRI tskpri );
ER rot_rdq ( PRI tskpri );
ER rel_wai ( ID tskid );
ER get_tid ( ID *p_tskid );
ER ref_tsk ( T_RTSK *pk_rtsk, ID tskid );
// - Task-Dependent Synchronization Functions
ER sus_tsk ( ID tskid );
ER rsm_tsk ( ID tskid );
ER frsm_tsk ( ID tskid );
ER slp_tsk ( void );
ER tslp_tsk ( TMO tmout );
ER wup_tsk ( ID tskid );
ER can_wup ( INT *p_wupcnt, ID tskid );
// - Synchronization and Communication Functions
ER cre_sem ( ID semid, T_CSEM *pk_csem );
ER del_sem ( ID semid );
ER sig_sem ( ID semid );
ER wai_sem ( ID semid );
ER preq_sem ( ID semid );
ER twai_sem ( ID semid, TMO tmout );
ER ref_sem ( T_RSEM *pk_rsem, ID semid );
 
ER cre_flg ( ID flgid, T_CFLG *pk_cflg );
ER del_flg ( ID flgid );
ER set_flg ( ID flgid, UINT setptn );
ER clr_flg ( ID flgid, UINT clrptn );
ER wai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode );
ER pol_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode );
ER twai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode,
TMO tmout );
ER ref_flg ( T_RFLG *pk_rflg, ID flgid );
 
ER cre_mbx ( ID mbxid, T_CMBX* pk_cmbx );
ER del_mbx ( ID mbxid );
ER snd_msg ( ID mbxid, T_MSG *pk_msg );
ER rcv_msg ( T_MSG **ppk_msg, ID mbxid );
ER prcv_msg ( T_MSG **ppk_msg, ID mbxid );
ER trcv_msg ( T_MSG **ppk_msg, ID mbxid, TMO tmout );
ER ref_mbx ( T_RMBX *pk_rmbx, ID mbxid );
// - Extended Synchronization and Communication Functions
#if 0 // NOT SUPPORTED
ER cre_mbf ( ID mbfid, T_CMBF *pk_cmbf );
ER del_mbf ( ID mbfid );
ER snd_mbf ( ID mbfid, VP msg, INT msgsz );
ER psnd_mbf ( ID mbfid, VP msg, INT msgsz );
ER tsnd_mbf ( ID mbfid, VP msg, INT msgsz, TMO tmout );
ER rcv_mbf ( VP msg, INT *p_msgsz, ID mbfid );
ER prcv_mbf ( VP msg, INT *p_msgsz, ID mbfid );
ER trcv_mbf ( VP msg, INT *p_msgsz, ID mbfid, TMO tmout );
ER ref_mbf ( T_RMBF *pk_rmbf, ID mbfid );
ER cre_por ( ID porid, T_CPOR *pk_cpor );
ER del_por ( ID porid );
ER cal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
cmsgsz );
ER pcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
cmsgsz );
ER tcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
cmsgsz, TMO tmout );
ER acp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
acpptn );
ER pacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
acpptn );
ER tacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
acpptn, TMO tmout );
ER fwd_por ( ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz
);
ER rpl_rdv ( RNO rdvno, VP msg, INT rmsgsz );
ER ref_por ( T_RPOR *pk_rpor, ID porid );
#endif
// - Interrupt Management Functions
#if 0 // NOT SUPPORTED
ER def_int ( UINT dintno, T_DINT *pk_dint );
void ret_wup ( ID tskid );
#endif
#if 0
void ret_int ( void );
#endif
#define ret_int() return
ER loc_cpu ( void );
ER unl_cpu ( void );
 
ER dis_int ( UINT eintno );
ER ena_int ( UINT eintno );
 
#if 0 // NOT SUPPORTED
ER chg_iXX ( UINT iXXXX );
ER ref_iXX ( UINT *p_iXXXX );
#endif
// - Memorypool Management Functions
ER cre_mpl ( ID mplid, T_CMPL *pk_cmpl );
ER del_mpl ( ID mplid );
ER get_blk ( VP *p_blk, ID mplid, INT blksz );
ER pget_blk ( VP *p_blk, ID mplid, INT blksz );
ER tget_blk ( VP *p_blk, ID mplid, INT blksz, TMO tmout );
ER rel_blk ( ID mplid, VP blk );
ER ref_mpl ( T_RMPL *pk_rmpl, ID mplid );
 
ER cre_mpf ( ID mpfid, T_CMPF *pk_cmpf );
ER del_mpf ( ID mpfid );
ER get_blf ( VP *p_blf, ID mpfid );
ER pget_blf ( VP *p_blf, ID mpfid );
ER tget_blf ( VP *p_blf, ID mpfid, TMO tmout );
ER rel_blf ( ID mpfid, VP blf );
ER ref_mpf ( T_RMPF *pk_rmpf, ID mpfid );
// - Time Management Functions
ER set_tim ( SYSTIME *pk_tim );
ER get_tim ( SYSTIME *pk_tim );
ER dly_tsk ( DLYTIME dlytim );
ER def_cyc ( HNO cycno, T_DCYC *pk_dcyc );
ER act_cyc ( HNO cycno, UINT cycact );
ER ref_cyc ( T_RCYC *pk_rcyc, HNO cycno );
ER def_alm ( HNO almno, T_DALM *pk_dalm );
ER ref_alm ( T_RALM *pk_ralm, HNO almno );
#if 0
void ret_tmr ( void );
#endif
#define ret_tmr() return
// - System Management Functions
ER get_ver ( T_VER *pk_ver );
ER ref_sys ( T_RSYS *pk_rsys );
ER ref_cfg ( T_RCFG *pk_rcfg );
#if 0 // NOT SUPPORTED
ER def_svc ( FN s_fncd, T_DSVC *pk_dsvc );
ER def_exc ( UINT exckind, T_DEXC *pk_dexc );
#endif
// - Network Support Functions
#if 0 // NOT SUPPORTED
ER nrea_dat ( INT *p_reasz, VP dstadr, NODE srcnode, VP srcadr,
INT datsz );
ER nwri_dat ( INT *p_wrisz, NODE dstnode, VP dstadr, VP srcadr,
INT datsz );
ER nget_nod ( NODE *p_node );
ER nget_ver ( T_VER *pk_ver, NODE node );
#endif
 
CYG_UIT_FUNC_EXTERN_END
 
// ========================================================================
 
#ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
// functions are inline OR we are in the outline implementation, so define
// the functions as inlines or plain functions depending on the value of
// CYG_UIT_FUNC_INLINE from above.
#include <cyg/compat/uitron/uit_func.inl>
#endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW
 
// ------------------------------------------------------------------------
#endif // CYGPKG_UITRON
 
#endif // CYGONCE_COMPAT_UITRON_UIT_FUNC_H
// EOF uit_func.h
/v2_0/include/uit_objs.hxx
0,0 → 1,177
#ifndef CYGONCE_COMPAT_UITRON_UIT_OBJS_HXX
#define CYGONCE_COMPAT_UITRON_UIT_OBJS_HXX
//===========================================================================
//
// uit_objs.hxx
//
// uITRON static objects
//
//===========================================================================
//####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-03-13
// Purpose: uITRON static system objects
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#include <pkgconf/uitron.h> // uITRON setup CYGNUM_UITRON_SEMAS
// CYGPKG_UITRON et al
 
#ifdef CYGPKG_UITRON
 
#include <cyg/infra/cyg_type.h> // types; cyg_int32, CYG_ADDRWORD
 
#include <pkgconf/kernel.h>
 
#include <cyg/kernel/ktypes.h>
 
#include <cyg/kernel/thread.hxx> // Cyg_Thread
#include <cyg/kernel/mbox.hxx> // Cyg_Mbox
#include <cyg/kernel/flag.hxx> // Cyg_Flag
#include <cyg/kernel/sema2.hxx> // Cyg_Counting_Semaphore2
#include <cyg/memalloc/memfixed.hxx> // Cyg_Mempool_Fixed
#include <cyg/memalloc/memvar.hxx> // Cyg_Mempool_Variable
#include <cyg/kernel/timer.hxx> // Cyg_Timer
 
// ------------------------------------------------------------------------
// Some pasting macros to create names of the config macro and the
// static data resulting:
 
#define CYG_UITRON_NUM( _which_ ) (CYGNUM_UITRON_ ## _which_)
#define CYG_UITRON_OBJS( _which_ ) cyg_uitron_ ## _which_
#define CYG_UITRON_PTRS( _which_ ) cyg_uitron_ ## _which_ ## _ptrs
// ------------------------------------------------------------------------
// CYG_UITRON_DECL
//
// Macro to declare static uitron static objects; uses the appropriate
// config define for the number of them to have.
 
#define CYG_UITRON_OBJS_INIT_PRIORITY CYG_INIT_PRIORITY( COMPAT )
 
#define CYG_UITRON_DECL( _which_ ) \
CYG_UITRON_OBJS( _which_ ) [ CYG_UITRON_NUM( _which_ ) ] \
CYG_UITRON_OBJS_INIT_PRIORITY
 
// and the array of pointers to them for those with dynamic existence:
#define CYG_UITRON_DECL_PTRS( _which_ ) \
CYG_UITRON_PTRS( _which_ ) [ CYG_UITRON_NUM( _which_ ) ]
 
 
// ------------------------------------------------------------------------
// The external system objects themselves.
 
#ifdef CYGPKG_UITRON_SEMAS
extern
Cyg_Counting_Semaphore2 CYG_UITRON_OBJS( SEMAS ) [];
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
extern
Cyg_Counting_Semaphore2 *CYG_UITRON_PTRS( SEMAS ) [];
#endif
#endif
#ifdef CYGPKG_UITRON_MBOXES
extern
Cyg_Mbox CYG_UITRON_OBJS( MBOXES ) [];
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
extern
Cyg_Mbox *CYG_UITRON_PTRS( MBOXES ) [];
#endif
#endif
#ifdef CYGPKG_UITRON_FLAGS
extern
Cyg_Flag CYG_UITRON_OBJS( FLAGS ) [];
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
extern
Cyg_Flag *CYG_UITRON_PTRS( FLAGS ) [];
#endif
#endif
// there must always be tasks
extern
Cyg_Thread CYG_UITRON_OBJS( TASKS ) [];
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
extern
Cyg_Thread *CYG_UITRON_PTRS( TASKS ) [];
#endif
// no endif
#ifdef CYGPKG_UITRON_MEMPOOLFIXED
extern
Cyg_Mempool_Fixed CYG_UITRON_OBJS( MEMPOOLFIXED ) [];
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
extern
Cyg_Mempool_Fixed *CYG_UITRON_PTRS( MEMPOOLFIXED )[];
#endif
#endif
#ifdef CYGPKG_UITRON_MEMPOOLVAR
extern
Cyg_Mempool_Variable CYG_UITRON_OBJS( MEMPOOLVAR ) [];
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
extern
Cyg_Mempool_Variable *CYG_UITRON_PTRS( MEMPOOLVAR ) [];
#endif
#endif
#ifdef CYGPKG_UITRON_CYCLICS
extern
Cyg_Timer CYG_UITRON_OBJS( CYCLICS ) [];
#endif
#ifdef CYGPKG_UITRON_ALARMS
extern
Cyg_Timer CYG_UITRON_OBJS( ALARMS ) [];
#endif
 
// ------------------------------------------------------------------------
// Ancillary system objects - cleaner than extending the basic class
 
#ifdef CYGIMP_THREAD_PRIORITY
// An array of priorities, for resetting back to the "created" prio when a
// task cycles though exit, dormancy, restart.
extern cyg_priority
cyg_uitron_task_initial_priorities[ CYG_UITRON_NUM( TASKS ) ];
// and an accessor macro, for the addressing of this is naturally
// from 1..N also:
#define CYG_UITRON_TASK_INITIAL_PRIORITY( _tskid_ ) \
(cyg_uitron_task_initial_priorities[ (_tskid_) - 1 ])
#endif // CYGIMP_THREAD_PRIORITY
 
// ------------------------------------------------------------------------
 
#endif // CYGPKG_UITRON
 
#endif // CYGONCE_COMPAT_UITRON_UIT_OBJS_HXX
// EOF uit_objs.hxx
/v2_0/include/uit_ifnc.h
0,0 → 1,182
#ifndef CYGONCE_COMPAT_UITRON_UIT_IFNC_H
#define CYGONCE_COMPAT_UITRON_UIT_IFNC_H
//===========================================================================
//
// uit_ifnc.h
//
// uITRON compatibility functions
//
//===========================================================================
//####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: 1999-08-16
// Purpose: uITRON compatibility functions
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
// ------------------------------------------------------------------------
// Source Code Organization
//
// First, see pkgconf/uitron.h for details of applicable configuration
// options.
//
// This file uit_ifnc.h provides prototypes for the task-independent parts
// of the uITRON API, that is functions named ixxx_yyy() for calling in
// ISRs. We also define the uitron helper DSR that is needed to despool
// stored up requests.
// ------------------------------------------------------------------------
 
#include <pkgconf/uitron.h> // uITRON setup CYGNUM_UITRON_SEMAS
// CYGPKG_UITRON et al
 
#ifdef CYGPKG_UITRON
 
#include <cyg/infra/cyg_type.h> // types; cyg_int32, CYG_ADDRWORD
 
#include <cyg/compat/uitron/uit_type.h> // uITRON types; ER ID TMO T_MSG
#include <cyg/compat/uitron/uit_func.h> // uITRON funcs and control macros.
 
// ========================================================================
// u I T R O N F U N C T I O N S
// The function declarations themselves:
 
// ------------------- These functions can be inline if so configured
CYG_UIT_FUNC_EXTERN_BEGIN
 
// ******************************************************
// *** 6.5 C Language Interfaces ***
// ******************************************************
 
// - Task Management Functions
 
// (None)
// - Task-Dependent Synchronization Functions
//ER irsm_tsk ( ID tskid );
//ER ifrsm_tsk ( ID tskid );
 
ER iwup_tsk ( ID tskid );
// - Synchronization and Communication Functions
ER isig_sem ( ID semid );
 
ER iset_flg ( ID flgid, UINT setptn );
 
ER isnd_msg ( ID mbxid, T_MSG *pk_msg );
// - Extended Synchronization and Communication Functions
// - Interrupt Management Functions
// (None)
// ---------------------------------------------------------------
 
#define CYGPRI_UITRON_SET_RETCODE( _z_ ) do { \
extern volatile int cyg_uit_dsr_actions_head; \
extern volatile int cyg_uit_dsr_actions_tail; \
(_z_) = (cyg_uit_dsr_actions_head == cyg_uit_dsr_actions_tail) ? 1 : 3; \
} while ( 0 )
 
//void ret_wup ( ID tskid );
// Awaken the task (safely) and return Cyg_Interrupt::CALL_DSR
#define ret_wup( _id_ ) do { \
register int retcode; \
(void)iwup_tsk( (_id_) ); \
CYGPRI_UITRON_SET_RETCODE( retcode ); \
return retcode; \
} while ( 0 )
 
// Subsitute a version of ret_int that returns Cyg_Interrupt::CALL_DSR
#undef ret_int
#define ret_int() do { \
register int retcode; \
CYGPRI_UITRON_SET_RETCODE( retcode ); \
return retcode; \
} while ( 0 )
 
 
// - Memorypool Management Functions
 
// (None)
// - Time Management Functions
// (None)
// - System Management Functions
// (None)
// - Network Support Functions
// (None)
CYG_UIT_FUNC_EXTERN_END
// ------------------- End of functions that can be inlined
 
 
// ========================================================================
// DSR: use this DSR with the uITRON-type ISR that uses the functions above
// to get delayed/safe execution of the wakeup-type functions above.
 
#ifdef __cplusplus
extern "C"
#endif
void cyg_uitron_dsr( unsigned int vector, unsigned int count, unsigned int data );
 
 
// ========================================================================
 
#ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
// functions are inline OR we are in the outline implementation, so define
// the functions as inlines or plain functions depending on the value of
// CYG_UIT_FUNC_INLINE from above.
#include <cyg/compat/uitron/uit_ifnc.inl>
#endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW
 
// ------------------------------------------------------------------------
#endif // CYGPKG_UITRON
 
#endif // CYGONCE_COMPAT_UITRON_UIT_IFNC_H
// EOF uit_ifnc.h
/v2_0/include/uit_type.h
0,0 → 1,687
#ifndef CYGONCE_COMPAT_UITRON_UIT_TYPE_H
#define CYGONCE_COMPAT_UITRON_UIT_TYPE_H
//===========================================================================
//
// uit_type.h
//
// uITRON specific data types as required by the API
//
//===========================================================================
//####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-03-13
// Purpose: uITRON specific data types as required by the API
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#include <pkgconf/uitron.h> // uITRON setup CYGNUM_UITRON_SEMAS
// CYGPKG_UITRON et al
 
#ifdef CYGPKG_UITRON
 
// ------------------------------------------------------------------------
// uITRON types
//
 
// from this section of the uITRON 3.02 manual:
// ***********************************************************************
// *** 6.4 Data Types ***
// ***********************************************************************
//
// *** General-Purpose Data Types ***************************************
 
typedef cyg_int8 B; // signed 8-bit integer
typedef cyg_int16 H; // signed 16-bit integer
typedef cyg_int32 W; // signed 32-bit integer
typedef cyg_uint8 UB; // unsigned 8-bit integer
typedef cyg_uint16 UH; // unsigned 16-bit integer
typedef cyg_uint32 UW; // unsigned 32-bit integer
//
typedef cyg_uint32 VW; // unpredictable data type (32-bit size)
typedef cyg_uint16 VH; // unpredictable data type (16-bit size)
typedef cyg_uint8 VB; // unpredictable data type (8-bit size)
typedef void * VP; // pointer to an unpredictable data type
typedef CYG_ADDRWORD FP; // program start address
 
// * The difference between VB, VH and VW and B, H and W is that only the
// number of bits is known for the former, not the data type of the
// contents. The latter clearly represent integers.
//
// *** Data Types Dependent on ITRON Specification ***
//
// In order to clarify the meanings of certain parameters, the following
// names are used for data types which appear frequently and/or have
// special meanings.
 
typedef cyg_int32 INT; // Signed integer (bit width of processor)
typedef cyg_uint32 UINT; // Unsigned integer (bit width of processor)
typedef cyg_int32 BOOL; // Boolean value. TRUE (1) or FALSE (0).
typedef cyg_uint16 FN; // Function code. Signed integer. Maximum 2 bytes.
typedef INT ID; // Object ID number (???id)
typedef INT BOOL_ID;// Boolean value or ID number
typedef INT HNO; // Handler number
typedef INT RNO; // Rendezvous number
typedef INT NODE; // Node Number. Usually a signed integer.
typedef UINT ATR; // Object or handler attribute. An unsigned integer.
typedef INT ER; // Error code. A signed integer.
typedef INT PRI; // Task priority. A signed integer.
typedef UB T_MSG; // Message packet data structure used for mailboxes
typedef INT TMO; // Timeout value. A signed integer.
// TMO_POL = 0 indicates polling,
// while TMO_FEVR = -1 indicates wait forever.
 
typedef cyg_uint64 CYGTM;
typedef CYGTM SYSTIME;// Data types used for specifying times.
typedef CYGTM CYCTIME;// Often split into upper and lower sections.
typedef CYGTM ALMTIME;// For details, see the chapter giving system
typedef CYGTM DLYTIME;// call descriptions;.
 
// ***********************************************************************
// *** 6.7 Error Codes ***
// ***********************************************************************
 
enum {
//------------------------------------------------------
//Mnemonic Value Description
//------------------------------------------------------
E_OK = 0, // Normal completion
// - - - - - - - - // - - - - - - - - - - - - - - - - - -
E_SYS = (-5), // System error
// - - - - - - - - // - - - - - - - - - - - - - - - - - -
E_NOMEM = (-10), // Insufficient memory
// - - - - - - - - // - - - - - - - - - - - - - - - - - -
E_NOSPT = (-17), // Feature not supported
E_INOSPT = (-18), // Feature not supported by ITRON/FILE specification
E_RSFN = (-20), // Reserved function code number
E_RSATR = (-24), // Reserved attribute
// - - - - - - - - // - - - - - - - - - - - - - - - - - -
E_PAR = (-33), // Parameter error
E_ID = (-35), // Invalid ID number
// - - - - - - - - // - - - - - - - - - - - - - - - - - -
E_NOEXS = (-52), // Object does not exist
E_OBJ = (-63), // Invalid object state
// - - - - - - - - // - - - - - - - - - - - - - - - - - -
E_MACV = (-65), // Memory access disabled or memory access violation
E_OACV = (-66), // Object access violation
// - - - - - - - - // - - - - - - - - - - - - - - - - - -
E_CTX = (-69), // Context error
// - - - - - - - - // - - - - - - - - - - - - - - - - - -
E_QOVR = (-73), // Queuing or nesting overflow
// - - - - - - - - // - - - - - - - - - - - - - - - - - -
E_DLT = (-81), // Object being waited for was deleted
// - - - - - - - - // - - - - - - - - - - - - - - - - - -
E_TMOUT = (-85), // Polling failure or timeout exceeded
E_RLWAI = (-86), // WAIT state was forcibly released
// - - - - - - - - // - - - - - - - - - - - - - - - - - - -
#if 0 // CONNECTION FUNCTIONS ARE NOT SUPPORTED
EN_NOND = (-113), // Target node does not exist or cannot be accessed
EN_OBJNO = (-114), // Specifies an object number which could not be
// accessed on the target node
EN_PROTO = (-115), // Protocol not supported on target node
EN_RSFN = (-116), // System call or function not supported on target node
EN_COMM = (-117), // No response from target node
EN_RLWAI = (-118), // Connection function response wait state was forcibly
// released
EN_PAR = (-119), // A value outside the range supported by the target
// node and/or transmission packet format was specified
// as a parameter
EN_RPAR = (-120), // A value outside the range supported by the issuing
// node and/or transmission packet format was returned
// as a return parameter
EN_CTXID = (-121), // An object on another node was specified to a system
// call issued from a task in dispatch disabled state
// or from a task-independent portion
EN_EXEC = (-122), // System call could not be executed due to
// insufficient resources on the target node
EN_NOSPT = (-123), // Connection function not supported
#endif // 0 CONNECTION FUNCTIONS ARE NOT SUPPORTED
// - - - - - - - - // - - - - - - - - - - - - - - - - - - -
};
 
 
// *******************************************************************
// *** 6.6 Common Constants and Data Structure Packet Formats ***
// *******************************************************************
 
/* --- overall ----------------------- */
 
/* invalid address or pointer value */
#define NADR ((void *)(-1))
 
enum {
TRUE = 1, /* true */
FALSE = 0, /* false */
};
 
/* TMO tmout: */
enum {
TMO_POL = 0, /* polling */
TMO_FEVR = (-1) /* wait forever */
};
 
/* --- for task management functions ----------------------- */
 
// cre_tsk:
typedef struct t_ctsk {
VP exinf; /* extended information */
ATR tskatr; /* task attributes */
FP task; /* task start address */
PRI itskpri; /* initial task priority */
INT stksz; /* stack size */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_CTSK;
 
// tskatr:
enum {
TA_ASM = 0x00, /* program written in assembly language */
TA_HLNG = 0x01, /* program written in high-level language */
TA_COP0 = 0x8000, /* uses coprocessor having ID = 0 */
TA_COP1 = 0x4000, /* uses coprocessor having ID = 1 */
TA_COP2 = 0x2000, /* uses coprocessor having ID = 2 */
TA_COP3 = 0x1000, /* uses coprocessor having ID = 3 */
TA_COP4 = 0x0800, /* uses coprocessor having ID = 4 */
TA_COP5 = 0x0400, /* uses coprocessor having ID = 5 */
TA_COP6 = 0x0200, /* uses coprocessor having ID = 6 */
TA_COP7 = 0x0100, /* uses coprocessor having ID = 7 */
};
 
// tskid:
enum {
TSK_SELF = 0, /* task specifies itself */
/* FALSE = 0, */ /* indicates a task-independent portion (return
parameters only) */
};
// tskpri:
enum {
TPRI_INI = 0, /* specifies the initial priority on task startup
(chg_pri) */
TPRI_RUN = 0, /* specifies the highest priority during execution
(rot_rdq) */
};
/* ref_tsk */
typedef struct t_rtsk {
VP exinf; /* extended information */
PRI tskpri; /* current priority */
UINT tskstat; /* task state */
/* the following are represent extended features of support
[level X] (implementation-dependent) */
#if 0 // NOT SUPPORTED
UINT tskwait; /* cause of wait */
ID wid; /* ID of object being waited for */
INT wupcnt; /* wakeup request count */
INT suscnt; /* SUSPEND request count */
ATR tskatr; /* task attributes */
FP task; /* task start address */
PRI itskpri; /* initial task priority */
INT stksz; /* stack size */
// ...
#endif
} T_RTSK;
 
// tskstat:
enum {
TTS_RUN = 0x01, /* RUN */
TTS_RDY = 0x02, /* READY */
TTS_WAI = 0x04, /* WAIT */
TTS_SUS = 0x08, /* SUSPEND */
TTS_WAS = 0x0C, /* WAIT-SUSPEND */
TTS_DMT = 0x10, /* DORMANT */
};
// tskwait:
enum {
TTW_SLP = 0x0001, /* wait due to slp_tsk or tslp_tsk */
TTW_DLY = 0x0002, /* wait due to dly_tsk */
TTW_NOD = 0x0008, /* connection function response wait */
TTW_FLG = 0x0010, /* wait due to wai_flg or twai_flg */
TTW_SEM = 0x0020, /* wait due to wai_sem or twai_sem */
TTW_MBX = 0x0040, /* wait due to rcv_msg or trcv_msg */
TTW_SMBF = 0x0080, /* wait due to snd_mbf or tsnd_mbf */
TTW_MBF = 0x0100, /* wait due to rcv_mbf or trcv_mbf */
TTW_CAL = 0x0200, /* wait for rendezvous call */
TTW_ACP = 0x0400, /* wait for rendezvous accept */
TTW_RDV = 0x0800, /* wait for rendezvous completion */
TTW_MPL = 0x1000, /* wait due to get_blk or tget_blk */
TTW_MPF = 0x2000, /* wait due to get_blf or tget_blf */
};
/* Since the task states given by tskstat and tskwait are expressed
by bit correspondences, they are convenient when looking for OR
conditions (such as whether a task is in WAIT or READY state).
*/
 
/* --- for semaphore functions ----------------------- */
 
/* cre_sem */
typedef struct t_csem {
VP exinf; /* extended information */
ATR sematr; /* semaphore attributes */
/* Following is the extended function for [level X]. */
INT isemcnt; /* initial semaphore count */
/* INT maxsem; NOT SUPPORTED maximum semaphore count */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_CSEM;
 
/* ref_sem */
typedef struct t_rsem {
VP exinf; /* extended information */
BOOL_ID wtsk; /* indicates whether or not there is a
waiting task */
INT semcnt; /* current semaphore count */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_RSEM;
 
/* --- for eventflag functions ----------------------- */
 
/* cre_flg */
typedef struct t_cflg {
VP exinf; /* extended information */
ATR flgatr; /* eventflag attribute */
UINT iflgptn; /* initial eventflag */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_CFLG;
 
// flgatr:
enum {
TA_WSGL = 0x00, /* multiple tasks are not allowed to wait (Wait
Single Task) */
TA_WMUL = 0x08, /* multiple tasks are allowed to wait (Wait
Multiple Task) */
};
// wfmode:
enum {
TWF_ANDW = 0x00, /* AND wait */
TWF_ORW = 0x02, /* OR wait */
TWF_CLR = 0x01, /* clear specification */
};
/* ref_flg */
typedef struct t_rflg {
VP exinf; /* extended information */
BOOL_ID wtsk; /* indicates whether or not there is a
waiting task */
UINT flgptn; /* eventflag bit pattern */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_RFLG;
 
/* --- for mailbox functions ----------------------- */
 
/* cre_mbx */
typedef struct t_cmbx {
VP exinf; /* extended information */
ATR mbxatr; /* mailbox attributes */
/* Following is implementation-dependent function */
/* INT bufcnt; NOT SUPPORTED ring buffer size IS FIXED */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_CMBX;
 
// mbxatr:
enum {
TA_TFIFO = 0x00, /* waiting tasks are handled by FIFO */
TA_TPRI = 0x01, /* waiting tasks are handled by priority */
TA_MFIFO = 0x00, /* messages are handled by FIFO */
TA_MPRI = 0x02, /* messages are handled by priority */
};
 
/* ref_mbx */
typedef struct t_rmbx {
VP exinf; /* extended information */
BOOL_ID wtsk; /* indicates whether or not there is a
waiting task */
T_MSG* pk_msg; /* message to be sent next */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_RMBX;
 
/* --- for messagebuffer functions ----------------------- */
 
#if 0 // NOT SUPPORTED
/* cre_mbf */
typedef struct t_cmbf {
VP exinf; /* extended information */
ATR mbfatr; /* messagebuffer attributes */
INT bufsz; /* messagebuffer size */
INT maxmsz; /* maximum size of messages */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_CMBF;
 
// mbfatr:
// mbfid:
enum {
TMBF_OS = (-4), /* messagebuffer used for OS error log */
TMBF_DB = (-3), /* messagebuffer used for debugging */
};
/* ref_mbf */
typedef struct t_rmbf {
VP exinf; /* extended information */
BOOL_ID wtsk; /* indicates whether or not there is a
task waiting to receive a message */
BOOL_ID stsk; /* indicates whether or not there is a
task waiting to send a message */
INT msgsz; /* size of message to be sent next */
INT frbufsz; /* size of free buffer */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_RMBF;
 
#endif
/* --- for port or rendezvous functions ----------------------- */
 
#if 0 // NOT SUPPORTED
 
/* cre_por */
typedef struct t_cpor {
VP exinf; /* extended information */
ATR poratr; /* port attributes */
INT maxcmsz; /* maximum call message size */
INT maxrmsz; /* maximum reply message size */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_CPOR;
 
// poratr:
enum {
TA_NULL = 0, /* specifies no particular attributes */
/* TA_NULL should be used in place of zeroes to turn off all
attribute features. */
};
/* ref_por */
typedef struct t_rpor {
VP exinf; /* extended information */
BOOL_ID wtsk; /* indicates whether or not there is a task
waiting to call a rendezvous */
BOOL_ID atsk; /* indicates whether or not there is a task
waiting to accept a rendezvous */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_RPOR;
#endif
 
/* --- for interrupt management functions ----------------------- */
 
#if 0 // NOT SUPPORTED
/* def_int */
typedef struct t_dint {
ATR intatr; /* interrupt handler attributes */
FP inthdr; /* interrupt handler address */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_DINT;
#endif
 
/* --- for memorypool management functions ----------------------- */
 
/* cre_mpl */
typedef struct t_cmpl {
VP exinf; /* extended information */
ATR mplatr; /* memorypool attributes */
INT mplsz; /* memorypool size */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_CMPL;
 
// mplatr:
// mplid:
enum {
TMPL_OS = (-4) /* memorypool used by OS */
};
/* ref_mpl */
typedef struct t_rmpl {
VP exinf; /* extended information */
BOOL_ID wtsk; /* indicates whether or not there are
waiting tasks */
INT frsz; /* total size of free memory */
INT maxsz; /* size of largest contiguous memory */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_RMPL;
 
/* cre_mpf */
typedef struct t_cmpf {
VP exinf; /* extended information */
ATR mpfatr; /* memorypool attributes */
INT mpfcnt; /* block count for entire memorypool */
INT blfsz; /* fixed-size memory block size */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_CMPF;
 
// mpfatr:
/* ref_mpf */
typedef struct t_rmpf {
VP exinf; /* extended information */
BOOL_ID wtsk; /* indicates whether or not there are
waiting tasks */
INT frbcnt; /* free block count */
/* additional information may be included depending on the
implementation */
INT numbcnt; /* total number of blocks */
INT bsize; /* block size */
 
} T_RMPF;
 
/* --- for time management functions ----------------------- */
 
#if 0 // native definition is at head of this file
/* example for 32-bit CPUs */
typedef struct t_systime {
H utime; /* upper 16 bits */
UW ltime; /* lower 32 bits */
} SYSTIME, CYCTIME, ALMTIME;
 
/* example for 16-bit CPUs */
typedef struct t_systime {
H utime; /* upper 16 bits */
UH mtime; /* middle 16 bits */
UH ltime; /* lower 16 bits */
} SYSTIME, CYCTIME, ALMTIME;
#endif
/* Member configuration depends on the bit width of the processor and
on the implementation. A total of 48 bits is recommended. */
 
/* def_cyc */
typedef struct t_dcyc {
VP exinf; /* extended information */
ATR cycatr; /* cyclic handler attributes */
FP cychdr; /* cyclic handler address */
UINT cycact; /* cyclic handler activation */
CYCTIME cyctim; /* cyclic startup period */
} T_DCYC;
 
// cycact:
enum {
TCY_OFF = 0x00, /* do not invoke cyclic handler */
TCY_ON = 0x01, /* invoke cyclic handler */
TCY_INT = 0x02, /* initialize cycle count */
/* Following changed from TCY_INT to TCY_INI to match
description in the body of the standard. I assume TCY_INT
is a hypercorrection/typo; keep both */
TCY_INI = 0x02, /* initialize cycle count */
};
/* ref_cyc */
typedef struct t_rcyc {
VP exinf; /* extended information */
CYCTIME lfttim; /* time left before next handler startup */
UINT cycact; /* cyclic handler activation */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_RCYC;
 
/* def_alm */
typedef struct t_dalm {
VP exinf; /* extended information */
ATR almatr; /* alarm handler attributes */
FP almhdr; /* alarm handler address */
UINT tmmode; /* start time specification mode */
ALMTIME almtim; /* handler startup time */
} T_DALM;
 
// tmmode:
enum {
TTM_ABS = 0x00, /* specified as an absolute time */
TTM_REL = 0x01, /* specified as a relative time */
};
/* ref_alm */
typedef struct t_ralm {
VP exinf; /* extended information */
ALMTIME lfttim; /* time left before next handler startup */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_RALM;
 
/* --- for system management functions ----------------------- */
 
/* get_ver */
typedef struct t_ver {
UH maker; /* vendor */
UH id; /* format number */
UH spver; /* specification version */
UH prver; /* product version */
UH prno[4]; /* product control information */
UH cpu; /* CPU information */
UH var; /* variation descriptor */
} T_VER;
 
/* ref_sys */
typedef struct t_rsys {
INT sysstat; /* system state */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_RSYS;
 
// sysstat:
enum {
TSS_TSK = 0, /* normal state in which dispatching is enabled during
task portion execution */
TSS_DDSP = 1, /* state after dis_dsp has been executed during task
portion execution (dispatch disabled) */
TSS_LOC = 3, /* state after loc_cpu has been executed during task
portion execution (interrupt and dispatch disabled)
*/
TSS_INDP = 4, /* state during execution of task-independent portions
(interrupt and timer handlers) */
};
/* ref_cfg */
typedef struct t_rcfg {
/* details concerning members are implementation dependent */
} T_RCFG;
 
#if 0 // NOT SUPPORTED
/* def_svc */
typedef struct t_dsvc {
ATR svcatr; /* extended SVC handler attributes */
FP svchdr; /* extended SVC handler address */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_DSVC;
 
/* def_exc */
typedef struct t_dexc {
ATR excatr; /* exception handler attributes */
FP exchdr; /* exception handler address */
// ...
/* additional information may be included depending on the
implementation */
// ...
} T_DEXC;
#endif
 
/* --- for network management functions ----------------------- */
 
#if 0 // NOT SUPPORTED
// NODE srcnode, dstnode, node:
enum {
TND_SELF = 0, /* specifies the local node */
TND_OTHR = (-1) /* specifies default remote node */
};
#endif
/* ------------------------------------------------------ */
 
 
 
#endif // CYGPKG_UITRON
 
#endif // CYGONCE_COMPAT_UITRON_UIT_TYPE_H
// EOF uit_type.h
/v2_0/include/uit_func.inl
0,0 → 1,1950
#ifndef CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
#define CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
//===========================================================================
//
// uit_func.inl
//
// uITRON compatibility functions
//
//===========================================================================
//####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-03-13
// Purpose: uITRON compatibility functions
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#ifdef CYGPKG_UITRON
 
#ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
 
#include <cyg/compat/uitron/uit_objs.hxx> // uITRON setup CYGNUM_UITRON_SEMAS
 
// kernel facilities only needed here
#include <cyg/kernel/intr.hxx>
#include <cyg/kernel/sched.hxx>
 
// and the implementations of other kernel facilities
#include <cyg/kernel/thread.inl>
#include <cyg/kernel/sched.inl>
#include <cyg/kernel/clock.inl>
 
 
// ------------------------------------------------------------------------
// The variable where dis_dsp/ena_dsp state is held:
extern cyg_uint32 cyg_uitron_dis_dsp_old_priority;
 
// ------------------------------------------------------------------------
// Parameter checking; either check the expression and return an error code
// if not true, or assert the truth with a made-up message.
 
#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// default: uitron error codes are returned
#define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START \
if ( ! (_true_) ) return (_error_); \
CYG_MACRO_END
#else
// ...but they are asserted if asserts are on
#define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START \
CYG_ASSERT( (_true_), "CYG_UIT_PARAMCHECK fail: " #_true_ ); \
CYG_MACRO_END
#endif // else !CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
 
// ------------------------------------------------------------------------
// CYG_UITRON_CHECK_AND_GETP
//
// Macro to rangecheck and do the addressing of a static uitron system
// object; _which_ sort of object is given, and token pasting is used
// horribly to get the static array, limits and the like.
//
// Usage:
// INT snd_msg( ID mbxid, ... ) {
// Cyg_Mbox *p;
// CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
// p->...(...);
 
// internal: plain assignment to the object pointer, from static array
#define CYG_UIT_SPTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START \
(_ptr_) = CYG_UITRON_OBJS( _which_ ) + ((_idx_) - 1); \
CYG_MACRO_END
 
// internal: plain assignment to the object pointer, from pointer array
// with error checking.
#define CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START \
(_ptr_) = CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ]; \
if ( NULL == (_ptr_) ) return E_NOEXS; \
CYG_MACRO_END
 
#define CYG_UITRON_CHECK_AND_GETP_DIRECT( _which_, _idx_, _ptr_ ) \
CYG_MACRO_START \
CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID ); \
CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID ); \
CYG_UIT_SPTR( _which_, _idx_, _ptr_ ); \
CYG_MACRO_END
 
#define CYG_UITRON_CHECK_AND_GETP_INDIRECT( _which_, _idx_, _ptr_ ) \
CYG_MACRO_START \
CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID ); \
CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID ); \
CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ ); \
CYG_MACRO_END
 
// As above but for handler numbers which return E_PAR when out of range
#define CYG_UITRON_CHECK_AND_GETHDLR( _which_, _num_, _ptr_ ) \
CYG_MACRO_START \
CYG_UIT_PARAMCHECK( 0 < (_num_), E_PAR ); \
CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_num_), E_PAR ); \
CYG_UIT_SPTR( _which_, _num_, _ptr_ ); \
CYG_MACRO_END
 
// And a macro to check that creation of an object is OK
#define CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( _which_, _idx_ ) \
CYG_MACRO_START \
CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID ); \
CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID ); \
Cyg_Scheduler::lock(); \
if ( NULL != CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ] ) { \
Cyg_Scheduler::unlock(); \
return E_OBJ; \
} \
CYG_MACRO_END
 
// define a magic new operator in order to call constructors
#define CYG_UITRON_NEWFUNCTION( _class_ ) \
inline void *operator new(size_t size, _class_ *ptr) \
{ \
CYG_CHECK_DATA_PTR( ptr, "Bad pointer" ); \
return ptr; \
}
 
// now configury to support selectable create/delete support ie. an
// array of pointers to the objects themselves.
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_INDIRECT( TASKS, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_DIRECT( TASKS, _idx_, _ptr_ )
#endif
 
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_INDIRECT( SEMAS, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_DIRECT( SEMAS, _idx_, _ptr_ )
#endif
 
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_INDIRECT( MBOXES, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_DIRECT( MBOXES, _idx_, _ptr_ )
#endif
 
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_INDIRECT( FLAGS, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_DIRECT( FLAGS, _idx_, _ptr_ )
#endif
 
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLFIXED, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLFIXED, _idx_, _ptr_ )
#endif
 
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLVAR, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ ) \
CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLVAR, _idx_, _ptr_ )
#endif
 
// ------------------------------------------------------------------------
// Common error checking macros
 
#if !defined( CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS ) && \
!defined( CYGDBG_USE_ASSERTS )
// if not checking and not asserted, these are removed to avoid usused
// variable warnings.
#define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ ) CYG_EMPTY_STATEMENT
#define CYG_UITRON_CHECK_TASK_CONTEXT() CYG_EMPTY_STATEMENT
#define CYG_UITRON_CHECK_DISPATCH_ENABLED() CYG_EMPTY_STATEMENT
#define CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( _tmout_ ) CYG_EMPTY_STATEMENT
 
#else
// the default:
// Check a task is actually a uITRON task
#define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ ) CYG_MACRO_START \
CYG_UIT_PARAMCHECK( \
(&cyg_uitron_TASKS[0] <= (_self_)) && \
((_self_) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]), \
E_CTX ); \
CYG_MACRO_END
 
#define CYG_UITRON_CHECK_TASK_CONTEXT() CYG_MACRO_START \
Cyg_Thread *self = Cyg_Thread::self(); \
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self ); \
CYG_MACRO_END
 
// Check dispatching is enabled for calls which might wait
#define CYG_UITRON_CHECK_DISPATCH_ENABLED() CYG_MACRO_START \
CYG_UIT_PARAMCHECK( 0 == cyg_uitron_dis_dsp_old_priority, E_CTX ); \
CYG_MACRO_END
 
#define CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO(_tmout_) CYG_MACRO_START \
CYG_UIT_PARAMCHECK( -1 <= (_tmout_), E_PAR ); \
if ( TMO_POL != (_tmout_) ) \
CYG_UITRON_CHECK_DISPATCH_ENABLED(); \
CYG_MACRO_END
 
#endif
 
#ifdef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
#define CYG_UIT_PARAMCHECK_PTR( _p_ ) CYG_MACRO_START \
CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR ); \
CYG_MACRO_END
#else // do check for NULL
#define CYG_UIT_PARAMCHECK_PTR( _p_ ) CYG_MACRO_START \
CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR ); \
CYG_UIT_PARAMCHECK( NULL != (_p_), E_PAR ); \
CYG_MACRO_END
#endif // !CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
 
// ------------------------------------------------------------------------
// CYG_UITRON_FAIL_RETURN
//
// After a call which waits, it might return with success, or due to a
// timeout or a release wait (a forced escape from the waiting condition).
// This macro examines context and finds out which, then executes a return
// with the correct uITRON condition code.
 
#define CYG_UITRON_FAIL_RETURN_SELF( _self_ ) CYG_MACRO_START \
Cyg_Thread::cyg_reason reason = (_self_)->get_wake_reason(); \
if ( Cyg_Thread::TIMEOUT == reason ) \
return E_TMOUT; \
if ( Cyg_Thread::BREAK == reason ) \
return E_RLWAI; \
if ( Cyg_Thread::DESTRUCT == reason ) \
return E_DLT; \
return E_SYS; /* if no plausible reason was found */ \
CYG_MACRO_END
 
#define CYG_UITRON_FAIL_RETURN() CYG_MACRO_START \
Cyg_Thread *self = Cyg_Thread::self(); \
CYG_UITRON_FAIL_RETURN_SELF( self ); \
CYG_MACRO_END
 
// ------------------------------------------------------------------------
// Interrupts disabled?
#define CYG_UITRON_CHECK_CPU_UNLOC() \
CYG_UIT_PARAMCHECK( (Cyg_Interrupt::interrupts_enabled()), E_CTX )
 
// ------------------------------------------------------------------------
// Timing: is it in eCos clock ticks or milliSeconds (or something else?)
 
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
 
#ifdef CYGSEM_UITRON_TIME_IS_MILLISECONDS
extern Cyg_Clock::converter uit_clock_to_system;
extern Cyg_Clock::converter uit_clock_from_system;
 
#define CYG_UITRON_TIME_UIT_TO_SYS32( t ) \
Cyg_Clock::convert( (cyg_uint64)(t), &uit_clock_to_system )
 
#define CYG_UITRON_TIME_SYS_TO_UIT32( t ) \
Cyg_Clock::convert( (cyg_uint64)(t), &uit_clock_from_system )
 
// long (cyg_uint64) versions:
#define CYG_UITRON_TIME_UIT_TO_SYS64( t ) \
Cyg_Clock::convert( (t), &uit_clock_to_system )
 
#define CYG_UITRON_TIME_SYS_TO_UIT64( t ) \
Cyg_Clock::convert( (t), &uit_clock_from_system )
 
#else // Time is whatever the system clock is doing:
 
// Straight through - int (cyg_int32) argument versions:
#define CYG_UITRON_TIME_UIT_TO_SYS32( t ) ( t )
#define CYG_UITRON_TIME_SYS_TO_UIT32( t ) ( t )
// long (cyg_uint64) versions:
#define CYG_UITRON_TIME_UIT_TO_SYS64( t ) ( t )
#define CYG_UITRON_TIME_SYS_TO_UIT64( t ) ( t )
#endif
 
#endif // CYGVAR_KERNEL_COUNTERS_CLOCK - otherwise these should not be used.
 
// ------------------------------------------------------------------------
// the function definitions themselves:
 
// ******************************************************
// *** 6.5 C Language Interfaces ***
// ******************************************************
 
// - Task Management Functions
 
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
CYG_UITRON_NEWFUNCTION( Cyg_Thread )
 
CYG_UIT_FUNC_INLINE
ER
cre_tsk ( ID tskid, T_CTSK *pk_ctsk )
{
ER ret = E_OK;
CYG_UIT_PARAMCHECK_PTR( pk_ctsk );
CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( TASKS, tskid );
 
Cyg_Thread *p = &(CYG_UITRON_OBJS( TASKS )[ tskid - 1 ]);
cyg_uint32 state = p->get_state();
if ( 0 == (state & Cyg_Thread::EXITED) )
ret = E_OBJ; // how did it get to be running?
else if ( ((INT)p->get_stack_size()) < pk_ctsk->stksz )
ret = E_NOMEM; // more stack requested than available
else {
CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] =
new( p ) Cyg_Thread(
(CYG_ADDRWORD) pk_ctsk->itskpri,
(cyg_thread_entry *)pk_ctsk->task,
(CYG_ADDRWORD) 0,
// preserve the original name and stack:
#ifdef CYGVAR_KERNEL_THREADS_NAME
p->get_name(),
#else
NULL,
#endif
p->get_stack_base(),
p->get_stack_size() );
// but ensure the task state is dormant:
// (it is not constructed dormant, but suspended)
p->kill();
#ifdef CYGIMP_THREAD_PRIORITY
// and record the initial priority outside the task too.
CYG_UITRON_TASK_INITIAL_PRIORITY( tskid ) = pk_ctsk->itskpri;
#endif
}
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
del_tsk ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
Cyg_Scheduler::lock();
// deal with the race condition here
if ( p != CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] ) {
Cyg_Scheduler::unlock();
return E_NOEXS;
}
cyg_uint32 state = p->get_state();
if ( state & Cyg_Thread::EXITED )
// just disconnect the pointer from its object
CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] = NULL;
else
ret = E_OBJ;
Cyg_Scheduler::unlock();
return ret;
}
#endif // CYGPKG_UITRON_TASKS_CREATE_DELETE
 
CYG_UIT_FUNC_INLINE
ER
sta_tsk ( ID tskid, INT stacd )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
Cyg_Scheduler::lock();
cyg_uint32 state = p->get_state();
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
// there is a race condition with deleting the task
// so test it now that we have the scheduler locked
if ( p != CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] )
ret = E_NOEXS;
else // NOTE dangling else to the next line:
#endif
if ( state & Cyg_Thread::EXITED ) {
p->reinitialize();
#ifdef CYGIMP_THREAD_PRIORITY
p->set_priority( CYG_UITRON_TASK_INITIAL_PRIORITY( tskid ) );
#endif
p->set_entry_data( (CYG_ADDRWORD)stacd );
p->force_resume();
}
else
ret = E_OBJ;
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
void
ext_tsk ( void )
{
Cyg_Thread::exit();
}
 
CYG_UIT_FUNC_INLINE
void
exd_tsk ( void )
{
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
Cyg_Thread *p;
 
Cyg_Scheduler::lock();
p = Cyg_Thread::self();
ID tskid = (p - (&cyg_uitron_TASKS[0])) + 1;
// just disconnect the pointer from its object
CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] = NULL;
// Any associated storage management, and possibly calling the task
// destructor, is for future versions.
#else
// do nothing - deletion not supported so just exit...
#endif
Cyg_Thread::exit();
// does not return, does unlock the scheduler for us
}
 
CYG_UIT_FUNC_INLINE
ER
ter_tsk ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock();
if ( (0 != (Cyg_Thread::EXITED & p->get_state())) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
// already dormant
ret = E_OBJ;
else {
p->force_resume(); // let it run
p->kill(); // and set prio high so it runs RIGHT NOW!!
#ifdef CYGIMP_THREAD_PRIORITY
#if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES != 0
// see if we are already at prio 0:
if ( 0 == cyg_uitron_dis_dsp_old_priority )
// then dispatch is enabled, we are not at prio 0
#endif
p->set_priority( (cyg_priority) 0 );
// if we do not do this, then we are not running a strictly
// uITRON compatible scheduler - so just hope for the best.
#endif
}
Cyg_Scheduler::unlock();
#ifdef CYGIMP_THREAD_PRIORITY
#if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES == 0
if ( (E_OK == ret) && (0 != cyg_uitron_dis_dsp_old_priority) ) {
// then dispatching is disabled, so our prio is 0 too
Cyg_Thread::yield(); // so let the dying thread run;
Cyg_Thread::yield(); // no cost here of making sure.
}
#endif
#endif
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
dis_dsp ( void )
{
CYG_UITRON_CHECK_TASK_CONTEXT();
CYG_UITRON_CHECK_CPU_UNLOC();
Cyg_Scheduler::lock();
// Prevent preemption by going up to prio 0
if ( 0 == cyg_uitron_dis_dsp_old_priority ) {
#ifdef CYGIMP_THREAD_PRIORITY
Cyg_Thread *p = Cyg_Thread::self();
cyg_uitron_dis_dsp_old_priority = p->get_priority();
p->set_priority( 0 );
#else
cyg_uitron_dis_dsp_old_priority = 1;
#endif
}
Cyg_Scheduler::unlock();
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
ena_dsp ( void )
{
CYG_UITRON_CHECK_TASK_CONTEXT();
CYG_UITRON_CHECK_CPU_UNLOC();
Cyg_Scheduler::lock();
// Enable dispatching (if disabled) and maybe switch threads
if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
// We had prevented preemption by going up to prio 0
#ifdef CYGIMP_THREAD_PRIORITY
Cyg_Thread *p = Cyg_Thread::self();
p->set_priority( cyg_uitron_dis_dsp_old_priority );
p->to_queue_head(); // to ensure we continue to run
// if nobody higher pri
#endif
cyg_uitron_dis_dsp_old_priority = 0;
}
Cyg_Scheduler::unlock();
CYG_UITRON_CHECK_DISPATCH_ENABLED(); // NB: afterwards!
return E_OK;
}
 
 
CYG_UIT_FUNC_INLINE
ER
chg_pri ( ID tskid, PRI tskpri )
{
Cyg_Thread *p;
ER ret = E_OK;
if ( 0 == tskid ) {
p = Cyg_Thread::self();
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
}
else
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
 
#ifdef CYGIMP_THREAD_PRIORITY
if ( 0 == tskpri )
// then use the initial priority [Level X]
tskpri = CYG_UITRON_TASK_INITIAL_PRIORITY( tskid );
#endif
CYG_UIT_PARAMCHECK( 0 < tskpri, E_PAR );
#ifdef CYGIMP_THREAD_PRIORITY
#if CYG_THREAD_MAX_PRIORITY < CYG_THREAD_MIN_PRIORITY
CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY <= tskpri &&
tskpri <= CYG_THREAD_MIN_PRIORITY, E_PAR );
#else
CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY >= tskpri &&
tskpri >= CYG_THREAD_MIN_PRIORITY, E_PAR );
#endif
// Handle changing our own prio specially, if dispatch disabled:
if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
// our actual prio is 0 now and must remain so:
if ( Cyg_Thread::self() == p ) { // by whichever route p was set
// set the priority we will return to when dispatch is enabled:
cyg_uitron_dis_dsp_old_priority = (cyg_uint32)tskpri;
return E_OK;
}
}
Cyg_Scheduler::lock();
if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
ret = E_OBJ; // task is dormant
else
p->set_priority( (cyg_priority)tskpri );
Cyg_Scheduler::unlock();
#endif // CYGIMP_THREAD_PRIORITY got priorities at all?
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
rot_rdq ( PRI tskpri )
{
// zero means our level; easiet way is to yield() the CPU.
if ( 0 == tskpri ) {
Cyg_Thread::yield();
return E_OK;
}
#ifdef CYGIMP_THREAD_PRIORITY
#if CYG_THREAD_MAX_PRIORITY < CYG_THREAD_MIN_PRIORITY
CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY <= tskpri &&
tskpri <= CYG_THREAD_MIN_PRIORITY, E_PAR );
#else
CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY >= tskpri &&
tskpri >= CYG_THREAD_MIN_PRIORITY, E_PAR );
#endif
Cyg_Thread::rotate_queue( tskpri );
#endif // CYGIMP_THREAD_PRIORITY got priorities at all?
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
rel_wai ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock(); // get an atomic view of the task
if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
ret = E_OBJ; // task is dormant
else {
p->release();
// return E_OBJ if the thread was not sleeping
if ( Cyg_Thread::BREAK != p->get_wake_reason() )
ret = E_OBJ;
}
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
get_tid ( ID *p_tskid )
{
Cyg_Thread *self = Cyg_Thread::self();
CYG_UIT_PARAMCHECK_PTR( p_tskid );
if ( (&cyg_uitron_TASKS[0] <= (self)) &&
((self) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]) &&
(0 == Cyg_Scheduler::get_sched_lock()) )
// then I am a uITRON task and not in an interrupt or DSR
*p_tskid = (self - (&cyg_uitron_TASKS[0])) + 1;
else
*p_tskid = 0; // Otherwise, non-task portion
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
ref_tsk ( T_RTSK *pk_rtsk, ID tskid )
{
Cyg_Thread *p;
if ( 0 == tskid ) {
p = Cyg_Thread::self();
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
tskid = (p - (&cyg_uitron_TASKS[0])) + 1; // it gets used below
}
else
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
 
CYG_UIT_PARAMCHECK_PTR( pk_rtsk );
pk_rtsk->exinf = NADR;
Cyg_Scheduler::lock(); // get an atomic view of the task
cyg_uint32 state = p->get_state();
if ( (state & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
pk_rtsk->tskstat = TTS_DMT;
else if ( state == Cyg_Thread::RUNNING )
// If it's us, it's running, else it's ready
pk_rtsk->tskstat = (Cyg_Thread::self() == p)
? TTS_RUN // RUN state (we are it)
: TTS_RDY; // READY state
else if ( state & Cyg_Thread::SUSPENDED )
pk_rtsk->tskstat =
(state & (Cyg_Thread::COUNTSLEEP | Cyg_Thread::SLEEPING))
? TTS_WAS // WAIT-SUSPEND state
: TTS_SUS; // SUSPEND state
else
pk_rtsk->tskstat =
(state & (Cyg_Thread::COUNTSLEEP | Cyg_Thread::SLEEPING))
? TTS_WAI // WAIT state
: 0; // Not sure what's happening here!
#ifdef CYGIMP_THREAD_PRIORITY
if ( TTS_DMT == pk_rtsk->tskstat )
pk_rtsk->tskpri = CYG_UITRON_TASK_INITIAL_PRIORITY( tskid );
else if ( (TTS_RUN == pk_rtsk->tskstat) &&
(0 != cyg_uitron_dis_dsp_old_priority) )
// then we are it and dispatching is disabled, so
// report our "real" priority - it is 0 in the kernel at the moment
pk_rtsk->tskpri = cyg_uitron_dis_dsp_old_priority;
else
pk_rtsk->tskpri = p->get_priority();
#else
pk_rtsk->tskpri = -1; // Not applicable
#endif
Cyg_Scheduler::unlock();
return E_OK;
}
// - Task-Dependent Synchronization Functions
CYG_UIT_FUNC_INLINE
ER
sus_tsk ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock(); // get an atomic view of the task
if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
ret = E_OBJ; // task is dormant
else
p->suspend();
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
rsm_tsk ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock(); // get an atomic view of the task
cyg_uint32 state = p->get_state();
if ( 0 == (Cyg_Thread::SUSPENDED & state) )
ret = E_OBJ; // thread is not suspended
else
p->resume();
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
frsm_tsk ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock(); // get an atomic view of the task
cyg_uint32 state = p->get_state();
if ( 0 == (Cyg_Thread::SUSPENDED & state) )
ret = E_OBJ; // thread is not suspended
else
p->force_resume();
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
slp_tsk ( void )
{
Cyg_Thread *self = Cyg_Thread::self();
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
CYG_UITRON_CHECK_DISPATCH_ENABLED();
// do this now for the case when no sleeping actually occurs
self->set_wake_reason( Cyg_Thread::DONE );
Cyg_Thread::counted_sleep();
if ( Cyg_Thread::DONE != self->get_wake_reason() )
CYG_UITRON_FAIL_RETURN_SELF( self );
return E_OK;
}
 
#ifdef CYGFUN_KERNEL_THREADS_TIMER
CYG_UIT_FUNC_INLINE
ER
tslp_tsk ( TMO tmout )
{
Cyg_Thread *self = Cyg_Thread::self();
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
CYG_UIT_PARAMCHECK( -1 <= tmout, E_PAR );
CYG_UITRON_CHECK_DISPATCH_ENABLED();
// do this now for the case when no sleeping actually occurs
self->set_wake_reason( Cyg_Thread::DONE );
// note that TMO_POL is not treated specially, though it
// happens to work almost as a poll (some sleeping may occur)
if ( TMO_FEVR == tmout )
Cyg_Thread::counted_sleep();
else
Cyg_Thread::counted_sleep(
(cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
if ( Cyg_Thread::DONE != self->get_wake_reason() )
CYG_UITRON_FAIL_RETURN_SELF( self );
return E_OK;
}
#endif // CYGFUN_KERNEL_THREADS_TIMER
 
CYG_UIT_FUNC_INLINE
ER
wup_tsk ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock(); // get an atomic view of the task
if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
ret = E_OBJ; // task is dormant
else
p->counted_wake();
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
can_wup ( INT *p_wupcnt, ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
if ( 0 == tskid ) {
p = Cyg_Thread::self();
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
}
else
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK_PTR( p_wupcnt );
Cyg_Scheduler::lock(); // get an atomic view of the task
if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
ret = E_OBJ; // task is dormant
else {
cyg_uint32 result = p->cancel_counted_wake();
*p_wupcnt = result;
}
Cyg_Scheduler::unlock();
return ret;
}
// - Synchronization and Communication Functions
#ifdef CYGPKG_UITRON_SEMAS
#if 0 < CYG_UITRON_NUM( SEMAS )
 
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
 
CYG_UITRON_NEWFUNCTION( Cyg_Counting_Semaphore2 )
 
CYG_UIT_FUNC_INLINE
ER
cre_sem ( ID semid, T_CSEM *pk_csem )
{
ER ret = E_OK;
CYG_UIT_PARAMCHECK_PTR( pk_csem );
CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( SEMAS, semid );
if ( TA_TFIFO != pk_csem->sematr )
ret = E_RSATR;
else
CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] =
new( &(CYG_UITRON_OBJS( SEMAS )[ semid - 1 ]) )
Cyg_Counting_Semaphore2( (cyg_count32)pk_csem->isemcnt );
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
del_sem ( ID semid )
{
Cyg_Counting_Semaphore2 *p;
CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
Cyg_Scheduler::lock();
// deal with the race condition here
if ( p != CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] ) {
Cyg_Scheduler::unlock();
return E_NOEXS;
}
CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] = NULL;
p->~Cyg_Counting_Semaphore2();
Cyg_Scheduler::unlock();
return E_OK;
}
#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
 
CYG_UIT_FUNC_INLINE
ER
sig_sem( ID semid )
{
Cyg_Counting_Semaphore2 *p;
CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
p->post();
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
wai_sem( ID semid )
{
Cyg_Counting_Semaphore2 *p;
CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
CYG_UITRON_CHECK_DISPATCH_ENABLED();
cyg_bool result = p->wait();
if ( !result )
CYG_UITRON_FAIL_RETURN();
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
preq_sem ( ID semid )
{
Cyg_Counting_Semaphore2 *p;
CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
cyg_bool result = p->trywait();
if ( !result )
return E_TMOUT;
return E_OK;
}
 
#ifdef CYGFUN_KERNEL_THREADS_TIMER
CYG_UIT_FUNC_INLINE
ER
twai_sem ( ID semid, TMO tmout )
{
Cyg_Counting_Semaphore2 *p;
CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
// do this now for the case when no sleeping actually occurs
Cyg_Thread *self = Cyg_Thread::self();
self->set_wake_reason( Cyg_Thread::TIMEOUT );
cyg_bool result;
if ( TMO_FEVR == tmout )
result = p->wait();
else if ( TMO_POL == tmout )
result = p->trywait();
else
result = p->wait(
Cyg_Clock::real_time_clock->current_value() +
(cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
if ( ! result )
CYG_UITRON_FAIL_RETURN_SELF( self );
return E_OK;
 
}
#endif // CYGFUN_KERNEL_THREADS_TIMER
 
CYG_UIT_FUNC_INLINE
ER
ref_sem ( T_RSEM *pk_rsem, ID semid )
{
Cyg_Counting_Semaphore2 *p;
CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
CYG_UIT_PARAMCHECK_PTR( pk_rsem );
pk_rsem->exinf = NADR;
pk_rsem->wtsk = p->waiting();
pk_rsem->semcnt = p->peek();
return E_OK;
}
 
#endif // 0 < CYG_UITRON_NUM( SEMAS )
#endif // CYGPKG_UITRON_SEMAS
 
#ifdef CYGPKG_UITRON_FLAGS
#if 0 < CYG_UITRON_NUM( FLAGS )
 
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
 
CYG_UITRON_NEWFUNCTION( Cyg_Flag )
 
CYG_UIT_FUNC_INLINE
ER
cre_flg ( ID flgid, T_CFLG *pk_cflg )
{
ER ret = E_OK;
CYG_UIT_PARAMCHECK_PTR( pk_cflg );
CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( FLAGS, flgid );
if ( 0 != ((~(TA_WMUL | TA_WSGL)) & pk_cflg->flgatr) )
ret = E_RSATR;
else
CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] =
new( &(CYG_UITRON_OBJS( FLAGS )[ flgid - 1 ]) )
Cyg_Flag( (Cyg_FlagValue) pk_cflg->iflgptn );
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
del_flg ( ID flgid )
{
Cyg_Flag *p;
CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
Cyg_Scheduler::lock();
// deal with the race condition here
if ( p != CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] ) {
Cyg_Scheduler::unlock();
return E_NOEXS;
}
CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] = NULL;
p->~Cyg_Flag();
Cyg_Scheduler::unlock();
return E_OK;
}
#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
 
CYG_UIT_FUNC_INLINE
ER
set_flg ( ID flgid, UINT setptn )
{
Cyg_Flag *p;
CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
p->setbits( setptn );
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
clr_flg ( ID flgid, UINT clrptn )
{
Cyg_Flag *p;
CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
p->maskbits( clrptn );
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
wai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode )
{
Cyg_Flag *p;
CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
CYG_UIT_PARAMCHECK_PTR( p_flgptn );
CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
CYG_UITRON_CHECK_DISPATCH_ENABLED();
// check we can use the wfmode value unchanged
CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
CYG_ASSERT( Cyg_Flag::OR == TWF_ORW, "Flag OR value bad" );
CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR, "Flag CLR value bad" );
 
UINT result = p->wait( waiptn, wfmode );
if ( ! result )
CYG_UITRON_FAIL_RETURN();
*p_flgptn = result;
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
pol_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode )
{
Cyg_Flag *p;
CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
CYG_UIT_PARAMCHECK_PTR( p_flgptn );
CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
// check we can use the wfmode value unchanged
CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
CYG_ASSERT( Cyg_Flag::OR == TWF_ORW, "Flag OR value bad" );
CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR, "Flag CLR value bad" );
 
UINT result = p->poll( waiptn, wfmode );
if ( ! result )
return E_TMOUT;
*p_flgptn = result;
return E_OK;
}
 
#ifdef CYGFUN_KERNEL_THREADS_TIMER
CYG_UIT_FUNC_INLINE
ER
twai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode,
TMO tmout )
{
Cyg_Flag *p;
CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
CYG_UIT_PARAMCHECK_PTR( p_flgptn );
CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
// check we can use the wfmode value unchanged
CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
CYG_ASSERT( Cyg_Flag::OR == TWF_ORW, "Flag OR value bad" );
CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR, "Flag CLR value bad" );
 
// do this now for the case when no sleeping actually occurs
Cyg_Thread *self = Cyg_Thread::self();
self->set_wake_reason( Cyg_Thread::TIMEOUT );
UINT result;
if ( TMO_FEVR == tmout )
result = p->wait( waiptn, wfmode );
else if ( TMO_POL == tmout )
result = p->poll( waiptn, wfmode );
else
result = p->wait( waiptn, wfmode,
Cyg_Clock::real_time_clock->current_value() +
(cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
if ( ! result )
CYG_UITRON_FAIL_RETURN_SELF( self );
*p_flgptn = result;
return E_OK;
}
#endif // CYGFUN_KERNEL_THREADS_TIMER
 
CYG_UIT_FUNC_INLINE
ER
ref_flg ( T_RFLG *pk_rflg, ID flgid )
{
Cyg_Flag *p;
CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
CYG_UIT_PARAMCHECK_PTR( pk_rflg );
pk_rflg->exinf = NADR;
pk_rflg->wtsk = p->waiting();
pk_rflg->flgptn = p->peek();
return E_OK;
}
 
#endif // 0 < CYG_UITRON_NUM( FLAGS )
#endif // CYGPKG_UITRON_FLAGS
 
#ifdef CYGPKG_UITRON_MBOXES
#if 0 < CYG_UITRON_NUM( MBOXES )
 
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
CYG_UITRON_NEWFUNCTION( Cyg_Mbox )
 
CYG_UIT_FUNC_INLINE
ER
cre_mbx ( ID mbxid, T_CMBX* pk_cmbx )
{
ER ret = E_OK;
CYG_UIT_PARAMCHECK_PTR( pk_cmbx );
CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MBOXES, mbxid );
if ( ((ATR)(TA_TFIFO + TA_MFIFO)) != pk_cmbx->mbxatr )
ret = E_RSATR;
else
CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] =
new( &(CYG_UITRON_OBJS( MBOXES )[ mbxid - 1 ]) )
Cyg_Mbox();
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
del_mbx ( ID mbxid )
{
Cyg_Mbox *p;
CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
Cyg_Scheduler::lock();
// deal with the race condition here
if ( p != CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] ) {
Cyg_Scheduler::unlock();
return E_NOEXS;
}
CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] = NULL;
p->~Cyg_Mbox();
Cyg_Scheduler::unlock();
return E_OK;
}
#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
 
// This bit of unpleasantness is to allow uITRON programs to send a NULL
// message - if permitted by the parameter checking.
//
// NULL is used internally to mean no message; but -1 is fine. So we send
// a NULL as a NADR and if we see a NULL coming back, change it to a NADR.
//
// One hopes that often this will be optimized out, since the one or both
// of these being true has been detected and errored out just above.
 
#ifdef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
// represent a NULL as NADR internally
#define CYG_UIT_TMSG_FIXUP_IN( _p_ ) CYG_MACRO_START \
if ( NULL == (_p_) ) \
(_p_) = (T_MSG *)NADR; \
CYG_MACRO_END
 
// we get a NADR back sometimes, meaning NULL
#define CYG_UIT_TMSG_FIXUP_OUT( _p_ ) CYG_MACRO_START \
if ( NADR == (_p_) ) \
(_p_) = (T_MSG *)NULL; \
CYG_MACRO_END
 
#else
// NULL is checked for and makes an error
#define CYG_UIT_TMSG_FIXUP_IN( _p_ ) CYG_EMPTY_STATEMENT
#define CYG_UIT_TMSG_FIXUP_OUT( _p_ ) CYG_EMPTY_STATEMENT
#endif
 
// and sometimes either in status enquiries
#define CYG_UIT_TMSG_FIXUP_ALL( _p_ ) CYG_MACRO_START \
if ( NULL == (_p_) ) \
(_p_) = (T_MSG *)NADR; \
else if ( NADR == (_p_) ) \
(_p_) = (T_MSG *)NULL; \
CYG_MACRO_END
 
CYG_UIT_FUNC_INLINE
ER
snd_msg ( ID mbxid, T_MSG *pk_msg )
{
Cyg_Mbox *p;
CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
CYG_UIT_PARAMCHECK_PTR( pk_msg );
CYG_UIT_TMSG_FIXUP_IN( pk_msg );
cyg_bool result = p->tryput( (void *)pk_msg );
if ( ! result )
return E_QOVR;
return E_OK;
}
 
 
CYG_UIT_FUNC_INLINE
ER
rcv_msg ( T_MSG **ppk_msg, ID mbxid )
{
Cyg_Mbox *p;
CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
CYG_UIT_PARAMCHECK_PTR( ppk_msg );
CYG_UITRON_CHECK_DISPATCH_ENABLED();
T_MSG *result = (T_MSG *)p->get();
if ( ! result )
CYG_UITRON_FAIL_RETURN();
CYG_UIT_TMSG_FIXUP_OUT( result );
*ppk_msg = result;
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
prcv_msg ( T_MSG **ppk_msg, ID mbxid )
{
Cyg_Mbox *p;
CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
CYG_UIT_PARAMCHECK_PTR( ppk_msg );
T_MSG *result = (T_MSG *)p->tryget();
if ( ! result )
return E_TMOUT;
CYG_UIT_TMSG_FIXUP_OUT( result );
*ppk_msg = result;
return E_OK;
}
 
#ifdef CYGFUN_KERNEL_THREADS_TIMER
CYG_UIT_FUNC_INLINE
ER
trcv_msg ( T_MSG **ppk_msg, ID mbxid, TMO tmout )
{
Cyg_Mbox *p;
CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
CYG_UIT_PARAMCHECK_PTR( ppk_msg );
CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
// do this now for the case when no sleeping actually occurs
Cyg_Thread *self = Cyg_Thread::self();
self->set_wake_reason( Cyg_Thread::TIMEOUT );
T_MSG *result;
if ( TMO_FEVR == tmout )
result = (T_MSG *)p->get();
else if ( TMO_POL == tmout )
result = (T_MSG *)p->tryget();
else
result = (T_MSG *)p->get(
Cyg_Clock::real_time_clock->current_value() +
(cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
if ( ! result )
CYG_UITRON_FAIL_RETURN_SELF( self );
CYG_UIT_TMSG_FIXUP_OUT( result );
*ppk_msg = result;
return E_OK;
}
#endif // CYGFUN_KERNEL_THREADS_TIMER
 
CYG_UIT_FUNC_INLINE
ER
ref_mbx ( T_RMBX *pk_rmbx, ID mbxid )
{
Cyg_Mbox *p;
CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
CYG_UIT_PARAMCHECK_PTR( pk_rmbx );
pk_rmbx->exinf = NADR;
pk_rmbx->wtsk = p->waiting_to_get();
pk_rmbx->pk_msg = (T_MSG *)p->peek_item();
CYG_UIT_TMSG_FIXUP_ALL( pk_rmbx->pk_msg );
return E_OK;
}
 
#undef CYG_UIT_TMSG_FIXUP_IN
#undef CYG_UIT_TMSG_FIXUP_OUT
#undef CYG_UIT_TMSG_FIXUP_ALL
#endif // 0 < CYG_UITRON_NUM( MBOXES )
#endif // CYGPKG_UITRON_MBOXES
 
// - Extended Synchronization and Communication Functions
#if 0 // NOT SUPPORTED
ER cre_mbf ( ID mbfid, T_CMBF *pk_cmbf );
ER del_mbf ( ID mbfid );
ER snd_mbf ( ID mbfid, VP msg, INT msgsz );
ER psnd_mbf ( ID mbfid, VP msg, INT msgsz );
ER tsnd_mbf ( ID mbfid, VP msg, INT msgsz, TMO tmout );
ER rcv_mbf ( VP msg, INT *p_msgsz, ID mbfid );
ER prcv_mbf ( VP msg, INT *p_msgsz, ID mbfid );
ER trcv_mbf ( VP msg, INT *p_msgsz, ID mbfid, TMO tmout );
ER ref_mbf ( T_RMBF *pk_rmbf, ID mbfid );
ER cre_por ( ID porid, T_CPOR *pk_cpor );
ER del_por ( ID porid );
ER cal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
cmsgsz );
ER pcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
cmsgsz );
ER tcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
cmsgsz, TMO tmout );
ER acp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
acpptn );
ER pacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
acpptn );
ER tacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
acpptn, TMO tmout );
ER fwd_por ( ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz
);
ER rpl_rdv ( RNO rdvno, VP msg, INT rmsgsz );
ER ref_por ( T_RPOR *pk_rpor, ID porid );
#endif
// - Interrupt Management Functions
#if 0 // NOT SUPPORTED
ER def_int ( UINT dintno, T_DINT *pk_dint );
void ret_wup ( ID tskid );
#endif
 
CYG_UIT_FUNC_INLINE
ER
loc_cpu ( void )
{
CYG_UITRON_CHECK_TASK_CONTEXT();
Cyg_Scheduler::lock();
// Prevent preemption by going up to prio 0
if ( 0 == cyg_uitron_dis_dsp_old_priority ) {
#ifdef CYGIMP_THREAD_PRIORITY
Cyg_Thread *p = Cyg_Thread::self();
cyg_uitron_dis_dsp_old_priority = p->get_priority();
p->set_priority( 0 );
#else
cyg_uitron_dis_dsp_old_priority = 1;
#endif
}
Cyg_Interrupt::disable_interrupts();
Cyg_Scheduler::unlock();
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
unl_cpu ( void )
{
CYG_UITRON_CHECK_TASK_CONTEXT();
Cyg_Scheduler::lock();
// Enable dispatching (if disabled) and maybe switch threads
if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
// We had prevented preemption by going up to prio 0
#ifdef CYGIMP_THREAD_PRIORITY
Cyg_Thread *p = Cyg_Thread::self();
p->set_priority( cyg_uitron_dis_dsp_old_priority );
#endif
cyg_uitron_dis_dsp_old_priority = 0;
}
Cyg_Interrupt::enable_interrupts();
Cyg_Scheduler::unlock();
CYG_UITRON_CHECK_DISPATCH_ENABLED(); // NB: afterwards!
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
dis_int ( UINT eintno )
{
CYG_INTERRUPT_STATE old_ints;
#if 0 < CYGNUM_HAL_ISR_MIN
CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MIN <= eintno, E_PAR );
#endif
CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MAX >= eintno, E_PAR );
HAL_DISABLE_INTERRUPTS(old_ints);
HAL_INTERRUPT_MASK( eintno );
HAL_RESTORE_INTERRUPTS(old_ints);
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
ena_int ( UINT eintno )
{
CYG_INTERRUPT_STATE old_ints;
 
#if 0 < CYGNUM_HAL_ISR_MIN
CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MIN <= eintno, E_PAR );
#endif
CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MAX >= eintno, E_PAR );
HAL_DISABLE_INTERRUPTS(old_ints);
HAL_INTERRUPT_UNMASK( eintno );
HAL_RESTORE_INTERRUPTS(old_ints);
return E_OK;
}
 
#if 0 // NOT SUPPORTED
ER chg_iXX ( UINT iXXXX );
ER ref_iXX ( UINT *p_iXXXX );
#endif
// - Memorypool Management Functions
#ifdef CYGPKG_UITRON_MEMPOOLVAR
#if 0 < CYG_UITRON_NUM( MEMPOOLVAR )
 
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
 
CYG_UITRON_NEWFUNCTION( Cyg_Mempool_Variable )
 
CYG_UIT_FUNC_INLINE
ER
cre_mpl ( ID mplid, T_CMPL *pk_cmpl )
{
ER ret = E_OK;
CYG_UIT_PARAMCHECK_PTR( pk_cmpl );
CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MEMPOOLVAR, mplid );
Cyg_Mempool_Variable *p = &(CYG_UITRON_OBJS( MEMPOOLVAR )[ mplid - 1 ]);
Cyg_Mempool_Status stat;
 
// preserve the original memory area to use
p->get_status( CYG_MEMPOOL_STAT_ORIGBASE|CYG_MEMPOOL_STAT_ORIGSIZE, stat );
 
if ( stat.origsize < pk_cmpl->mplsz )
ret = E_NOMEM;
else if ( TA_TFIFO != pk_cmpl->mplatr )
ret = E_RSATR;
else
CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] =
new( p ) Cyg_Mempool_Variable(
const_cast<cyg_uint8 *>(stat.origbase), stat.origsize );
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
del_mpl ( ID mplid )
{
Cyg_Mempool_Variable *p;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
Cyg_Scheduler::lock();
// deal with the race condition here
if ( p != CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] ) {
Cyg_Scheduler::unlock();
return E_NOEXS;
}
CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] = NULL;
p->~Cyg_Mempool_Variable();
Cyg_Scheduler::unlock();
return E_OK;
}
#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
 
CYG_UIT_FUNC_INLINE
ER
get_blk ( VP *p_blk, ID mplid, INT blksz )
{
Cyg_Mempool_Variable *p;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
CYG_UIT_PARAMCHECK_PTR( p_blk );
CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
CYG_UITRON_CHECK_DISPATCH_ENABLED();
VP result = (VP)p->alloc(blksz);
if ( ! result )
CYG_UITRON_FAIL_RETURN();
*p_blk = result;
return E_OK;
}
 
 
CYG_UIT_FUNC_INLINE
ER
pget_blk ( VP *p_blk, ID mplid, INT blksz )
{
Cyg_Mempool_Variable *p;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
CYG_UIT_PARAMCHECK_PTR( p_blk );
CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
VP result = (VP)p->try_alloc(blksz);
if ( ! result )
return E_TMOUT;
*p_blk = result;
return E_OK;
}
 
#ifdef CYGFUN_KERNEL_THREADS_TIMER
CYG_UIT_FUNC_INLINE
ER
tget_blk ( VP *p_blk, ID mplid, INT blksz, TMO tmout )
{
Cyg_Mempool_Variable *p;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
CYG_UIT_PARAMCHECK_PTR( p_blk );
CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
// do this now for the case when no sleeping actually occurs
Cyg_Thread *self = Cyg_Thread::self();
self->set_wake_reason( Cyg_Thread::TIMEOUT );
VP result;
if ( TMO_FEVR == tmout )
result = p->alloc(blksz);
else if ( TMO_POL == tmout )
result = p->try_alloc(blksz);
else
result = p->alloc( blksz,
Cyg_Clock::real_time_clock->current_value() +
(cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
if ( ! result )
CYG_UITRON_FAIL_RETURN_SELF( self );
*p_blk = result;
return E_OK;
}
#endif // CYGFUN_KERNEL_THREADS_TIMER
 
CYG_UIT_FUNC_INLINE
ER
rel_blk ( ID mplid, VP blk )
{
Cyg_Mempool_Variable *p;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
CYG_UIT_PARAMCHECK_PTR( blk );
cyg_bool result = p->free( (cyg_uint8 *)blk );
if ( ! result )
return E_PAR;
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
ref_mpl ( T_RMPL *pk_rmpl, ID mplid )
{
Cyg_Mempool_Variable *p;
Cyg_Mempool_Status stat;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
CYG_UIT_PARAMCHECK_PTR( pk_rmpl );
p->get_status( CYG_MEMPOOL_STAT_WAITING|
CYG_MEMPOOL_STAT_TOTALFREE|
CYG_MEMPOOL_STAT_MAXFREE, stat );
 
pk_rmpl->exinf = NADR;
pk_rmpl->wtsk = stat.waiting;
pk_rmpl->frsz = stat.totalfree;
pk_rmpl->maxsz = stat.maxfree;
 
return E_OK;
}
 
#endif // 0 < CYG_UITRON_NUM( MEMPOOLVAR )
#endif // CYGPKG_UITRON_MEMPOOLVAR
 
#ifdef CYGPKG_UITRON_MEMPOOLFIXED
#if 0 < CYG_UITRON_NUM( MEMPOOLFIXED )
 
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
 
CYG_UITRON_NEWFUNCTION( Cyg_Mempool_Fixed )
 
CYG_UIT_FUNC_INLINE
ER
cre_mpf ( ID mpfid, T_CMPF *pk_cmpf )
{
ER ret = E_OK;
CYG_UIT_PARAMCHECK_PTR( pk_cmpf );
CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MEMPOOLFIXED, mpfid );
Cyg_Mempool_Fixed *p = &(CYG_UITRON_OBJS( MEMPOOLFIXED )[ mpfid - 1 ]);
Cyg_Mempool_Status stat;
 
// preserve the original memory area to use
p->get_status( CYG_MEMPOOL_STAT_ORIGBASE|CYG_MEMPOOL_STAT_ORIGSIZE, stat );
 
if ( stat.origsize < (pk_cmpf->blfsz * (pk_cmpf->mpfcnt + 1)) )
ret = E_NOMEM;
else if ( TA_TFIFO != pk_cmpf->mpfatr )
ret = E_RSATR;
else
CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] =
new( p )
Cyg_Mempool_Fixed( const_cast<cyg_uint8 *>(stat.origbase),
stat.origsize, (CYG_ADDRWORD)pk_cmpf->blfsz );
Cyg_Scheduler::unlock();
return ret;
}
 
CYG_UIT_FUNC_INLINE
ER
del_mpf ( ID mpfid )
{
Cyg_Mempool_Fixed *p;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
Cyg_Scheduler::lock();
// deal with the race condition here
if ( p != CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] ) {
Cyg_Scheduler::unlock();
return E_NOEXS;
}
CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] = NULL;
p->~Cyg_Mempool_Fixed();
Cyg_Scheduler::unlock();
return E_OK;
}
#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
 
CYG_UIT_FUNC_INLINE
ER
get_blf ( VP *p_blf, ID mpfid )
{
Cyg_Mempool_Fixed *p;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
CYG_UIT_PARAMCHECK_PTR( p_blf );
CYG_UITRON_CHECK_DISPATCH_ENABLED();
VP result = (VP)p->alloc();
if ( ! result )
CYG_UITRON_FAIL_RETURN();
*p_blf = result;
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
pget_blf ( VP *p_blf, ID mpfid )
{
Cyg_Mempool_Fixed *p;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
CYG_UIT_PARAMCHECK_PTR( p_blf );
VP result = (VP)p->try_alloc();
if ( ! result )
return E_TMOUT;
*p_blf = result;
return E_OK;
}
 
#ifdef CYGFUN_KERNEL_THREADS_TIMER
CYG_UIT_FUNC_INLINE
ER
tget_blf ( VP *p_blf, ID mpfid, TMO tmout )
{
Cyg_Mempool_Fixed *p;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
CYG_UIT_PARAMCHECK_PTR( p_blf );
CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
// do this now for the case when no sleeping actually occurs
Cyg_Thread *self = Cyg_Thread::self();
self->set_wake_reason( Cyg_Thread::TIMEOUT );
VP result;
if ( TMO_FEVR == tmout )
result = p->alloc();
else if ( TMO_POL == tmout )
result = p->try_alloc();
else
result = p->alloc(
Cyg_Clock::real_time_clock->current_value() +
(cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
if ( ! result )
CYG_UITRON_FAIL_RETURN_SELF( self );
*p_blf = result;
return E_OK;
}
#endif // CYGFUN_KERNEL_THREADS_TIMER
 
CYG_UIT_FUNC_INLINE
ER
rel_blf ( ID mpfid, VP blf )
{
Cyg_Mempool_Fixed *p;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
CYG_UIT_PARAMCHECK_PTR( blf );
cyg_bool result = p->free( (cyg_uint8 *)blf );
if ( ! result )
return E_PAR;
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
ref_mpf ( T_RMPF *pk_rmpf, ID mpfid )
{
Cyg_Mempool_Fixed *p;
Cyg_Mempool_Status stat;
CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
CYG_UIT_PARAMCHECK_PTR( pk_rmpf );
 
p->get_status( CYG_MEMPOOL_STAT_WAITING|
CYG_MEMPOOL_STAT_TOTALFREE|
CYG_MEMPOOL_STAT_TOTALALLOCATED|
CYG_MEMPOOL_STAT_BLOCKSIZE, stat );
 
pk_rmpf->exinf = NADR;
pk_rmpf->wtsk = stat.waiting;
 
pk_rmpf->frbcnt = stat.totalfree / stat.blocksize;
// these two are "implementation dependent" ie. eCos only
pk_rmpf->numbcnt = stat.totalallocated / stat.blocksize;
pk_rmpf->bsize = stat.blocksize;
 
return E_OK;
}
#endif // 0 < CYG_UITRON_NUM( MEMPOOLFIXED )
#endif // CYGPKG_UITRON_MEMPOOLFIXED
 
// - Time Management Functions
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
CYG_UIT_FUNC_INLINE
ER
set_tim ( SYSTIME *pk_tim )
{
CYG_UIT_PARAMCHECK_PTR( pk_tim );
Cyg_Clock::real_time_clock->set_value(
CYG_UITRON_TIME_UIT_TO_SYS64( *pk_tim ) );
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
get_tim ( SYSTIME *pk_tim )
{
CYG_UIT_PARAMCHECK_PTR( pk_tim );
*pk_tim = CYG_UITRON_TIME_SYS_TO_UIT64(
Cyg_Clock::real_time_clock->current_value() );
return E_OK;
}
#endif // CYGVAR_KERNEL_COUNTERS_CLOCK
 
 
#ifdef CYGFUN_KERNEL_THREADS_TIMER
CYG_UIT_FUNC_INLINE
ER
dly_tsk ( DLYTIME dlytim )
{
CYG_UIT_PARAMCHECK( 0 <= dlytim, E_PAR );
CYG_UITRON_CHECK_DISPATCH_ENABLED();
if ( 0 >= dlytim )
return E_OK;
Cyg_Thread *self = Cyg_Thread::self();
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
self->delay( CYG_UITRON_TIME_UIT_TO_SYS64( dlytim ) );
if ( Cyg_Thread::DONE != self->get_wake_reason() )
CYG_UITRON_FAIL_RETURN_SELF( self );
return E_OK;
}
#endif // CYGFUN_KERNEL_THREADS_TIMER
 
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
#ifdef CYGPKG_UITRON_CYCLICS
#if 0 < CYG_UITRON_NUM( CYCLICS )
CYG_UIT_FUNC_INLINE
ER
def_cyc ( HNO cycno, T_DCYC *pk_dcyc )
{
// pk_dcyc->cycatr is ignored
// The only relevant attribute is TA_HLNG/TA_ASM.
// This can be ignored as assembler routines are defined to be
// more conservative with registers than the procedure call standard.
cyg_tick_count t;
Cyg_Timer *p;
CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
CYG_UIT_PARAMCHECK( NULL != pk_dcyc, E_PAR );
#endif
if( NADR == pk_dcyc ) {
p->~Cyg_Timer();
return E_OK;
}
CYG_UIT_PARAMCHECK( 0 == (pk_dcyc->cycact & ~TCY_ON), E_PAR );
CYG_UIT_PARAMCHECK( 0 < pk_dcyc->cyctim, E_PAR );
t = CYG_UITRON_TIME_UIT_TO_SYS64( pk_dcyc->cyctim );
p->initialize(
Cyg_Clock::real_time_clock,
(cyg_alarm_fn *)pk_dcyc->cychdr,
(CYG_ADDRWORD)pk_dcyc->exinf,
Cyg_Clock::real_time_clock->current_value() + t,
t,
pk_dcyc->cycact);
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
act_cyc ( HNO cycno, UINT cycact )
{
Cyg_Timer *p;
CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
CYG_UIT_PARAMCHECK( 0 == (cycact & ~(TCY_ON | TCY_INI)), E_PAR );
p->activate(cycact);
return E_OK;
}
 
 
CYG_UIT_FUNC_INLINE
ER
ref_cyc ( T_RCYC *pk_rcyc, HNO cycno )
{
Cyg_Timer *p;
cyg_tick_count t;
CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
CYG_UIT_PARAMCHECK_PTR( pk_rcyc );
 
pk_rcyc->exinf = (VP)p->get_data();
Cyg_Scheduler::lock();
t = p->get_trigger() - Cyg_Clock::real_time_clock->current_value();
Cyg_Scheduler::unlock();
pk_rcyc->lfttim = CYG_UITRON_TIME_SYS_TO_UIT64( t );
pk_rcyc->cycact = (UINT)p->is_enabled();
return E_OK;
}
#endif // 0 < CYG_UITRON_NUM( CYCLICS )
#endif // CYGPKG_UITRON_CYCLICS
 
#ifdef CYGPKG_UITRON_ALARMS
#if 0 < CYG_UITRON_NUM( ALARMS )
CYG_UIT_FUNC_INLINE
ER
def_alm ( HNO almno, T_DALM *pk_dalm )
{
Cyg_Timer *p;
cyg_tick_count t, now;
CYG_UITRON_CHECK_AND_GETHDLR( ALARMS, almno, p );
#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
CYG_UIT_PARAMCHECK( NULL != pk_dalm, E_PAR );
#endif
if( NADR == pk_dalm ) {
p->~Cyg_Timer();
return E_OK;
}
 
CYG_UIT_PARAMCHECK( 0 == (pk_dalm->tmmode & ~TTM_REL), E_PAR );
CYG_UIT_PARAMCHECK( 0 < pk_dalm->almtim, E_PAR );
 
// make the time arithmetic safe without locking
now = Cyg_Clock::real_time_clock->current_value();
t = CYG_UITRON_TIME_UIT_TO_SYS64( pk_dalm->almtim );
if( TTM_REL & pk_dalm->tmmode )
t += now;
 
CYG_UIT_PARAMCHECK( now < t, E_PAR );
 
p->initialize(Cyg_Clock::real_time_clock,
(cyg_alarm_fn *)pk_dalm->almhdr,
(CYG_ADDRWORD)pk_dalm->exinf,
t, 0, Cyg_Timer::ENABLE);
 
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
ref_alm ( T_RALM *pk_ralm, HNO almno )
{
Cyg_Timer *p;
cyg_tick_count t;
 
CYG_UITRON_CHECK_AND_GETHDLR( ALARMS, almno, p );
CYG_UIT_PARAMCHECK_PTR( pk_ralm );
CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
 
Cyg_Scheduler::lock();
t = p->get_trigger() - Cyg_Clock::real_time_clock->current_value();
Cyg_Scheduler::unlock();
pk_ralm->exinf = (VP)p->get_data();
pk_ralm->lfttim = CYG_UITRON_TIME_SYS_TO_UIT64( t );
return E_OK;
}
#endif // 0 < CYG_UITRON_NUM( ALARMS )
#endif // CYGPKG_UITRON_ALARMS
 
#endif // CYGVAR_KERNEL_COUNTERS_CLOCK
// - System Management Functions
CYG_UIT_FUNC_INLINE
ER
get_ver ( T_VER *pk_ver )
{
CYG_UIT_PARAMCHECK_PTR( pk_ver );
 
pk_ver->maker = CYGNUM_UITRON_VER_MAKER;
pk_ver->id = CYGNUM_UITRON_VER_ID;
pk_ver->spver = CYGNUM_UITRON_VER_SPVER;
pk_ver->prver = CYGNUM_UITRON_VER_PRVER;
pk_ver->prno[0] = CYGNUM_UITRON_VER_PRNO_0;
pk_ver->prno[1] = CYGNUM_UITRON_VER_PRNO_1;
pk_ver->prno[2] = CYGNUM_UITRON_VER_PRNO_2;
pk_ver->prno[3] = CYGNUM_UITRON_VER_PRNO_3;
pk_ver->cpu = CYGNUM_UITRON_VER_CPU;
pk_ver->var = CYGNUM_UITRON_VER_VAR;
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
ref_sys ( T_RSYS *pk_rsys )
{
CYG_UIT_PARAMCHECK_PTR( pk_rsys );
if ( ! Cyg_Interrupt::interrupts_enabled() )
// CPU is locked
pk_rsys->sysstat = TSS_LOC;
else
pk_rsys->sysstat =
(0 == cyg_uitron_dis_dsp_old_priority) ? TSS_TSK : TSS_DDSP;
return E_OK;
}
 
CYG_UIT_FUNC_INLINE
ER
ref_cfg ( T_RCFG *pk_rcfg )
{
CYG_UIT_PARAMCHECK_PTR( pk_rcfg );
// no details here yet
return E_OK;
}
 
#if 0 // NOT SUPPORTED
ER def_svc ( FN s_fncd, T_DSVC *pk_dsvc );
ER def_exc ( UINT exckind, T_DEXC *pk_dexc );
#endif
// - Network Support Functions
#if 0 // NOT SUPPORTED
ER nrea_dat ( INT *p_reasz, VP dstadr, NODE srcnode, VP srcadr,
INT datsz );
ER nwri_dat ( INT *p_wrisz, NODE dstnode, VP dstadr, VP srcadr,
INT datsz );
ER nget_nod ( NODE *p_node );
ER nget_ver ( T_VER *pk_ver, NODE node );
#endif
 
// ========================================================================
 
#endif // CYGPKG_UITRON
 
#endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW
 
#endif // CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
//EOF uit_func.inl
/v2_0/doc/uitron.sgml
0,0 → 1,1385
<!-- {{{ Banner -->
 
<!-- =============================================================== -->
<!-- -->
<!-- uitron.sgml -->
<!-- -->
<!-- uITRON Compatibility -->
<!-- -->
<!-- =============================================================== -->
<!-- ####COPYRIGHTBEGIN#### -->
<!-- -->
<!-- =============================================================== -->
<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -->
<!-- This material may be distributed only subject to the terms -->
<!-- and conditions set forth in the Open Publication License, v1.0 -->
<!-- or later (the latest version is presently available at -->
<!-- http://www.opencontent.org/openpub/) -->
<!-- Distribution of the work or derivative of the work in any -->
<!-- standard (paper) book form is prohibited unless prior -->
<!-- permission obtained from the copyright holder -->
<!-- =============================================================== -->
<!-- -->
<!-- ####COPYRIGHTEND#### -->
<!-- =============================================================== -->
<!-- #####DESCRIPTIONBEGIN#### -->
<!-- -->
<!-- ####DESCRIPTIONEND#### -->
<!-- =============================================================== -->
 
<!-- }}} -->
 
<part id="compat-uitron">
<title>&micro;ITRON</title>
<CHAPTER id="compat-uitron-microitron-api">
<TITLE><!-- <xref> -->&micro;ITRON API</TITLE>
<SECT1 id="compat-uitron-introduction">
<TITLE><!-- <index></index> -->Introduction to &micro;ITRON</TITLE>
<PARA>The <!-- <index></index> -->&micro;ITRON specification
defines a highly flexible operating system architecture designed
specifically for application in embedded systems. The specification addresses
features which are common to the majority of processor architectures and
deliberately avoids virtualization which would adversely impact
real-time performance. The &micro;ITRON specification
may be implemented on many hardware platforms and provides significant
advantages by reducing the effort involved in understanding and
porting application software to new processor architectures. </PARA>
<PARA>Several revisions of the &micro;ITRON specification exist.
In this release, <EMPHASIS>eCos</EMPHASIS> supports the
&micro;ITRON version 3.02 specification, with complete
&ldquo;Standard functionality&rdquo; (level S), plus many
&ldquo;Extended&rdquo; (level E) functions. The definitive
reference on &micro;ITRON is Dr. Sakamura&rsquo;s book:
<CITETITLE>&micro;ITRON 3.0, An Open and Portable Real-Time Operating
System for Embedded Systems</CITETITLE>.
The book can be purchased from the IEEE Press, and
an ASCII version of the standard can be found online at
<ulink url="http://www.itron.gr.jp/">http://www.itron.gr.jp/</ulink>.
The old address
<ulink url="http://tron.um.u-tokyo.ac.jp/TRON/ITRON/">
http://tron.um.u-tokyo.ac.jp/TRON/ITRON/</ulink>
still exists as a mirror site. </PARA>
</SECT1>
<SECT1 id="compat-uitron-over-ecos">
<TITLE><!-- <index></index> -->&micro;ITRON and <EMPHASIS>eCos</EMPHASIS></TITLE>
<PARA>The <EMPHASIS>eCos</EMPHASIS> kernel implements the functionality
used by the &micro;ITRON compatibility subsystem.
The configuration of the kernel influences the behavior of &micro;ITRON
programs.</PARA>
<PARA>In particular, the default configuration has time slicing
(also known as round-robin scheduling) switched on; this means that
a task can be moved from <varname>RUN</varname> state
to <varname>READY</varname> state at any time, in
order that one of its peers may run. This is not strictly conformant
to the &micro;ITRON specification, which
states that timeslicing may be implemented by periodically issuing
a <literal>rot_rdq(0)</literal> call from
within a periodic task or cyclic handler; otherwise it is expected
that a task runs until it is pre-empted in consequence of synchronization
or communication calls it makes, or the effects of an interrupt
or other external event on a higher priority task cause that task
to become <varname>READY</varname>. To disable timeslicing
functionality in the kernel and &micro;ITRON
compatibility environment, please disable the
<LITERAL>CYGSEM_KERNEL_SCHED_TIMESLICE</LITERAL>
configuration option in the kernel package. A description of kernel
scheduling is in <xref linkend="kernel-overview">. </PARA>
<PARA>For another example, the semantics of task queueing when waiting
on a synchronization object depend solely on the way the underlying
kernel is configured. As discussed above, the multi-level queue
scheduler is the only one which is &micro;ITRON
compliant, and it queues waiting tasks in FIFO order. Future releases
of that scheduler might be configurable to support priority ordering
of task queues. Other schedulers might be different again: for example
the bitmap scheduler can be used with the &micro;ITRON
compatibility layer, even though it only allows one task at each
priority and as such is not &micro;ITRON
compliant, but it supports only priority ordering of task queues.
So which queueing scheme is supported is not really a property of
the &micro;ITRON compatibility layer; it
depends on the kernel. </PARA>
<PARA>In this version of the &micro;ITRON
compatibility layer, the calls to disable and enable scheduling
and interrupts (<FUNCTION>dis_dsp()</FUNCTION>,
<FUNCTION>ena_dsp()</FUNCTION>, <FUNCTION>loc_cpu()</FUNCTION>
and <FUNCTION>unl_cpu()</FUNCTION>)
call underlying kernel functions; in particular, the <FUNCTION>xxx_dsp()</FUNCTION> functions
lock the scheduler entirely, which prevents dispatching of DSRs; functions
implemented by DSRs include clock counters and alarm timers. Thus time &ldquo;stops&rdquo; while
dispatching is disabled with <FUNCTION>dis_dsp()</FUNCTION>. </PARA>
<PARA>Like all parts of the <EMPHASIS>eCos</EMPHASIS> system, the
detailed semantics of the &micro;ITRON layer
are dependent on its configuration and the configuration of other components
that it uses. The &micro;ITRON configuration
options are all defined in the file <filename>pkgconf/uitron.h</filename>,
and can be set using the configuration tool or editing the
<filename>.ecc</filename>
file in your build directory by hand. </PARA>
<PARA>An important configuration option for the &micro;ITRON
compatibility layer is &ldquo;Option: Return Error Codes for Bad Params&rdquo;
(
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
), which allows a lot of the error
checking code in the &micro;ITRON compatibility layer to
be removed. Of course this leaves a program open to undetected errors,
so it should only be used once an application is fully debugged and
tested. Its benefits include reduced code size and faster execution.
However, it affects the API significantly, in that with this option
enabled, bad calls do not return errors, but cause an assert
failure (if that is itself enabled) or malfunction internally. There
is discussion in more detail about this in each section below.</PARA>
<PARA>We now give a brief description of the &micro;ITRON
functions which are implemented in this release. Note that all C
and C&plus;&plus; source files should have the following <literal>#include</literal> statement: </PARA>
<PROGRAMLISTING>#include &lt;cyg/compat/uitron/uit_func.h&gt;</PROGRAMLISTING>
</SECT1>
<SECT1 id="compat-uitron-task-management-functions">
<TITLE><!-- <index></index> -->Task Management Functions</TITLE>
<PARA>The following functions are fully supported in this release: </PARA>
<PROGRAMLISTING>ER <FUNCTION>sta_tsk</FUNCTION>(
ID <EMPHASIS>tskid,</EMPHASIS>
INT <EMPHASIS>stacd</EMPHASIS> )</programlisting>
<programlisting>
void <FUNCTION>ext_tsk</FUNCTION>( void )</programlisting>
<programlisting>
void <FUNCTION>exd_tsk</FUNCTION>( void )</programlisting>
<programlisting>
ER <FUNCTION>dis_dsp</FUNCTION>( void )</programlisting>
<programlisting>
ER <FUNCTION>ena_dsp</FUNCTION>( void )</programlisting>
<programlisting>
ER <FUNCTION>chg_pri</FUNCTION>(
ID <EMPHASIS>tskid,</EMPHASIS>
PRI <EMPHASIS>tskpri</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>rot_rdq</FUNCTION>(
PRI <EMPHASIS>tskpri</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>get_tid</FUNCTION>(
ID *<EMPHASIS>p_tskid</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>ref_tsk</FUNCTION>(
T_RTSK *<EMPHASIS>pk_rtsk,</EMPHASIS>
ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>ter_tsk</FUNCTION>(
ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>rel_wai</FUNCTION>(
ID <EMPHASIS>tskid</EMPHASIS> )</PROGRAMLISTING>
<PARA>The following two functions are supported in this release,
when enabled with the configuration option
<LITERAL>CYGPKG_UITRON_TASKS_CREATE_DELETE</LITERAL>
with some restrictions:</PARA>
<PROGRAMLISTING>ER <FUNCTION>cre_tsk</FUNCTION>(
ID <EMPHASIS>tskid,</EMPHASIS>
T_CTSK *<EMPHASIS>pk_ctsk</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>del_tsk</FUNCTION>(
ID <EMPHASIS>tskid</EMPHASIS> )</PROGRAMLISTING>
<PARA>These functions are restricted as follows:</PARA>
<PARA>Because of the static initialization facilities provided for
system objects, a task is allocated stack space statically in the
configuration. So while tasks can be created and deleted, the same
stack space is used for that task (task ID number) each time. Thus
the stack size (pk_ctsk-&gt;stksz) requested in <FUNCTION>cre_tsk()</FUNCTION> is
checked for being less than that which was statically allocated,
and otherwise ignored. This ensures that the new task will have
enough stack to run. For this reason <FUNCTION>del_tsk()</FUNCTION> does
not in any sense free the memory that was in use for the task's
stack. </PARA>
<PARA>The task attributes (pk_ctsk-&gt;tskatr) are
ignored; current versions of <EMPHASIS>eCos</EMPHASIS> do not need
to know whether a task is written in assembler or C/C&plus;&plus; so
long as the procedure call standard appropriate to the CPU is followed.</PARA>
<PARA>Extended information (pk_ctsk-&gt;exinf) is
ignored.</PARA>
<SECT2>
<TITLE>Error checking</TITLE>
<PARA>For all these calls, an invalid task id (tskid) (less than
1 or greater than the number of configured tasks) only returns E_ID
when bad params return errors (
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
is enabled, see above).</PARA>
<PARA>Similarly, the following conditions are only checked for,
and only return errors if
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
is enabled:</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>pk_crtk in
<FUNCTION>cre_tsk()</FUNCTION>
is a valid pointer, otherwise return E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>ter_tsk()</FUNCTION>
or
<FUNCTION>rel_wai()</FUNCTION>
on the calling task returns E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA>the CPU is not locked already in
<FUNCTION>dis_dsp()</FUNCTION>
and
<FUNCTION>ena_dsp()</FUNCTION>
; returns E_CTX</PARA>
</LISTITEM>
<LISTITEM>
<PARA>priority level in
<FUNCTION>chg_pri()</FUNCTION>
and
<FUNCTION>rot_rdq()</FUNCTION>
is checked for validity, E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>return value pointer in
<FUNCTION>get_tid()</FUNCTION>
and
<FUNCTION>ref_tsk()</FUNCTION>
is a valid pointer, or E_PAR</PARA>
</LISTITEM>
</ITEMIZEDLIST>
<PARA>The following conditions are checked for, and return
error codes if appropriate, regardless of the setting of
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
:</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>When create and delete functions
<FUNCTION>cre_tsk()</FUNCTION>
and
<FUNCTION>del_tsk()</FUNCTION>
are supported, all calls which use a valid task ID number check
that the task exists; if not, E_NOEXS is returned</PARA>
</LISTITEM>
<LISTITEM>
<PARA>When supported,
<FUNCTION>cre_tsk()</FUNCTION>
: the task must not already exist; otherwise E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA>When supported,
<FUNCTION>cre_tsk()</FUNCTION>
: the requested stack size must not be larger than that statically
configured for the task; see the configuration options
&ldquo;Static initializers&rdquo;, and &ldquo;Default stack size&rdquo;.
Else E_NOMEM</PARA>
</LISTITEM>
<LISTITEM>
<PARA>When supported,
<FUNCTION>del_tsk()</FUNCTION>
: the underlying
<EMPHASIS>eCos</EMPHASIS>
thread must not be running - this would imply either a bug or some
program bypassing the
&micro;ITRON compatibility layer and manipulating the thread directly.
E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>sta_tsk()</FUNCTION>
: the task must be dormant, else E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>ter_tsk()</FUNCTION>
: the task must not be dormant, else E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>chg_pri()</FUNCTION>
: the task must not be dormant, else E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>rel_wai()</FUNCTION>
: the task must be in
<varname>WAIT</varname> or <varname>WAIT-SUSPEND</varname>
state, else E_OBJ</PARA>
</LISTITEM>
</ITEMIZEDLIST>
</SECT2>
</SECT1>
<SECT1 id="compat-uitron-task-dependent-synch-functions">
<TITLE><!-- <index></index> -->Task-Dependent Synchronization Functions</TITLE>
<PARA>These functions are fully supported in this release: </PARA>
<PROGRAMLISTING>ER <FUNCTION>sus_tsk</FUNCTION>(
ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>rsm_tsk</FUNCTION>(
ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>frsm_tsk</FUNCTION>(
ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>slp_tsk</FUNCTION>( void )</programlisting>
<programlisting>
ER <FUNCTION>tslp_tsk</FUNCTION>(
TMO <EMPHASIS>tmout</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>wup_tsk</FUNCTION>(
ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>can_wup</FUNCTION>(
INT *<EMPHASIS>p_wupcnt,</EMPHASIS> ID <EMPHASIS>tskid</EMPHASIS> )</PROGRAMLISTING>
<SECT2>
<TITLE>Error checking</TITLE>
<PARA>The following conditions are only checked for, and only return
errors if
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
is enabled (see the configuration option &ldquo;Return Error Codes for Bad
Params&rdquo;):</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>invalid tskid; less than 1 or greater than
<LITERAL>CYGNUM_UITRON_TASKS</LITERAL>
returns E_ID</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>wup_tsk()</FUNCTION>
,
<FUNCTION>sus_tsk()</FUNCTION>
,
<FUNCTION>rsm_tsk()</FUNCTION>
,
<FUNCTION>frsm_tsk()</FUNCTION>
on the calling task returns E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA>dispatching is enabled in
<FUNCTION>tslp_tsk()</FUNCTION>
and
<FUNCTION>slp_tsk()</FUNCTION>
, or E_CTX</PARA>
</LISTITEM>
<LISTITEM>
<PARA>tmout must be positive, otherwise E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>return value pointer in
<FUNCTION>can_wup()</FUNCTION>
is a valid pointer, or E_PAR</PARA>
</LISTITEM>
</ITEMIZEDLIST>
<PARA>The following conditions are checked for, and can
return error codes, regardless of the setting of
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>:
</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>When create and delete functions
<FUNCTION>cre_tsk()</FUNCTION>
and
<FUNCTION>del_tsk()</FUNCTION>
are supported, all calls which use a valid task ID number check
that the task exists; if not, E_NOEXS is returned</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>sus_tsk()</FUNCTION>
: the task must not be dormant, else E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>frsm/rsm_tsk()</FUNCTION>
: the task must be suspended, else E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>tslp/slp_tsk()</FUNCTION>
: return codes E_TMOUT, E_RLWAI and E_DLT
are returned depending on the reason for terminating the sleep</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>wup_tsk()</FUNCTION>
and
<FUNCTION>can_wup()</FUNCTION>
: the task must not be dormant, or E_OBJ is returned</PARA>
</LISTITEM>
</ITEMIZEDLIST>
</SECT2>
</SECT1>
<SECT1 id="compat-uitron-sync-and-comm-functions">
<TITLE><!-- <index></index> --> Synchronization and Communication Functions</TITLE>
<PARA>These functions are fully supported in this release: </PARA>
<PROGRAMLISTING>ER <FUNCTION>sig_sem</FUNCTION>(
ID <EMPHASIS>semid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>wai_sem</FUNCTION>(
ID <EMPHASIS>semid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>preq_sem</FUNCTION>(
ID <EMPHASIS>semid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>twai_sem</FUNCTION>(
ID <EMPHASIS>semid,</EMPHASIS> TMO <EMPHASIS>tmout</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>ref_sem</FUNCTION>(
T_RSEM *<EMPHASIS>pk_rsem ,</EMPHASIS> ID <EMPHASIS>semid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>set_flg</FUNCTION>(
ID <EMPHASIS>flgid,</EMPHASIS> UINT <EMPHASIS>setptn</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>clr_flg</FUNCTION>(
ID <EMPHASIS>flgid,</EMPHASIS> UINT <EMPHASIS>clrptn</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>wai_flg</FUNCTION>(
UINT *<EMPHASIS>p_flgptn,</EMPHASIS> ID <EMPHASIS>flgid ,</EMPHASIS>
UINT <EMPHASIS>waiptn ,</EMPHASIS> UINT <EMPHASIS>wfmode</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>pol_flg</FUNCTION>(
UINT *<EMPHASIS>p_flgptn,</EMPHASIS> ID <EMPHASIS>flgid ,</EMPHASIS>
UINT <EMPHASIS>waiptn ,</EMPHASIS> UINT <EMPHASIS>wfmode</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>twai_flg</FUNCTION>(
UINT *<EMPHASIS>p_flgptn</EMPHASIS> ID <EMPHASIS>flgid ,</EMPHASIS>
UINT <EMPHASIS>waiptn ,</EMPHASIS> UINT <EMPHASIS>wfmode,</EMPHASIS> TMO <EMPHASIS>tmout</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>ref_flg</FUNCTION>(
T_RFLG *<EMPHASIS>pk_rflg,</EMPHASIS> ID <EMPHASIS>flgid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>snd_msg</FUNCTION>(
ID <EMPHASIS>mbxid,</EMPHASIS> T_MSG <EMPHASIS>*pk_msg</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>rcv_msg</FUNCTION>(
T_MSG **<EMPHASIS>ppk_msg,</EMPHASIS> ID <EMPHASIS>mbxid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>prcv_msg</FUNCTION>(
T_MSG **<EMPHASIS>ppk_msg,</EMPHASIS> ID <EMPHASIS>mbxid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>trcv_msg</FUNCTION>(
T_MSG **<EMPHASIS>ppk_msg,</EMPHASIS> ID <EMPHASIS>mbxid ,</EMPHASIS> TMO <EMPHASIS>tmout</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>ref_mbx</FUNCTION>(
T_RMBX *<EMPHASIS>pk_rmbx,</EMPHASIS> ID <EMPHASIS>mbxid</EMPHASIS> )</PROGRAMLISTING>
<PARA>The following functions are supported in this release (with
some restrictions) if enabled with the appropriate configuration
option for the object type (for example
<LITERAL>CYGPKG_UITRON_SEMAS_CREATE_DELETE</LITERAL>):
</PARA>
<PROGRAMLISTING>ER <FUNCTION>cre_sem</FUNCTION>(
ID <EMPHASIS>semid,</EMPHASIS> T_CSEM *<EMPHASIS>pk_csem</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>del_sem</FUNCTION>(
ID <EMPHASIS>semid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>cre_flg</FUNCTION>(
ID <EMPHASIS>flgid,</EMPHASIS> T_CFLG *<EMPHASIS>pk_cflg</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>del_flg</FUNCTION>(
ID <EMPHASIS>flgid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>cre_mbx</FUNCTION>(
ID <EMPHASIS>mbxid,</EMPHASIS> T_CMBX *<EMPHASIS>pk_cmbx</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>del_mbx</FUNCTION>(
ID <EMPHASIS>mbxid</EMPHASIS> )</PROGRAMLISTING>
<PARA>In general the queueing order when waiting on a synchronization
object depends on the underlying kernel configuration. The multi-level
queue scheduler is required for strict &micro;ITRON
conformance and it queues tasks in FIFO order, so requests to create
an object with priority queueing of tasks (<literal>pk_cxxx-&gt;xxxatr = TA_TPRI</literal>)
are rejected with E_RSATR. Additional undefined bits in
the attributes fields must be zero. </PARA>
<PARA>In general, extended information (pk_cxxx-&gt;exinf)
is ignored. </PARA>
<PARA>For semaphores, the initial semaphore count (pk_csem-&gt;isemcnt)
is supported; the new semaphore's count is set. The maximum
count is not supported, and is not in fact defined in type pk_csem. </PARA>
<PARA>For flags, multiple tasks are allowed to wait. Because single
task waiting is a subset of this, the W bit (TA_WMUL) of
the flag attributes is ignored; all other bits must be zero. The
initial flag value is supported. </PARA>
<PARA>For mailboxes, the buffer count is defined statically by kernel
configuration option
<LITERAL>CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE</LITERAL>;
therefore the buffer count field is not supported and is not in
fact defined in type pk_cmbx. Queueing of messages is FIFO
ordered only, so TA_MPRI (in pk_cmbx-&gt;mbxatr)
is not supported. </PARA>
<SECT2>
<TITLE>Error checking</TITLE>
<PARA>The following conditions are only checked for, and only return
errors if
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
is enabled:</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>invalid object id; less than 1 or greater than
<LITERAL>CYGNUM_UITRON_TASKS/SEMAS/MBOXES</LITERAL>
as appropriate returns E_ID</PARA>
</LISTITEM>
<LISTITEM>
<PARA>dispatching is enabled in any call which can sleep, or
E_CTX</PARA>
</LISTITEM>
<LISTITEM>
<PARA>tmout must be positive, otherwise E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>pk_cxxx pointers in
<FUNCTION>cre_xxx()</FUNCTION>
must be valid pointers, or E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>return value pointer in
<FUNCTION>ref_xxx()</FUNCTION>
is valid pointer, or E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>flag wait pattern must be non-zero, and mode must be valid,
or E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>return value pointer in flag wait calls is a valid pointer,
or E_PAR</PARA>
</LISTITEM>
</ITEMIZEDLIST>
<PARA>The following conditions are checked for, and can return error
codes, regardless of the setting of
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
:</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>When create and delete functions
<FUNCTION>cre_xxx()</FUNCTION>
and
<FUNCTION>del_xxx()</FUNCTION>
are supported, all calls which use a valid object ID number check
that the object exists. If not, E_NOEXS is returned.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In create functions
<FUNCTION>cre_xxx()</FUNCTION>
, when supported, if the object already exists, then E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In any call which can sleep, such as
<FUNCTION>twai_sem()</FUNCTION>
: return codes E_TMOUT, E_RLWAI, E_DLT
or of course E_OK are returned depending on the reason
for terminating the sleep</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In polling functions such as
<FUNCTION>preq_sem()</FUNCTION>
return codes E_TMOUT or E_OK are returned depending
on the state of the synchronization object</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In creation functions, the attributes must be compatible
with the selected underlying kernel configuration: in
<FUNCTION>cre_sem()</FUNCTION>
<literal>pk_csem-&gt;sematr</literal>
must be equal to
<literal>TA_TFIFO</literal>
else E_RSATR.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In
<FUNCTION>cre_flg()</FUNCTION>
<literal>pk_cflg-&gt;flgatr</literal>
must be either
<varname>TA_WMUL</varname>
or
<varname>TA_WSGL</varname>
else <varname>E_RSATR</varname>.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In
<FUNCTION>cre_mbx()</FUNCTION>
<LITERAL>pk_cmbx-&gt;mbxatr</LITERAL>
must be
<LITERAL>TA_TFIFO &plus; TA_MFIFO</LITERAL>
else E_RSATR.</PARA>
</LISTITEM>
</ITEMIZEDLIST>
</SECT2>
</SECT1>
<SECT1 id="compat-uitron-extended-sync-comm-functions">
<TITLE><!-- <index></index> -->Extended Synchronization and Communication Functions</TITLE>
<PARA>None of these functions are supported in this release. </PARA>
</SECT1>
<SECT1 id="compat-uitron-interrupt-management-functions">
<TITLE><!-- <index></index> -->Interrupt management functions</TITLE>
<PARA>These functions are fully supported in this release:</PARA>
<PROGRAMLISTING>void <FUNCTION> ret_int</FUNCTION>( void )
</programlisting>
<programlisting>
ER <FUNCTION>loc_cpu</FUNCTION>( void )
</programlisting>
<programlisting>
ER <FUNCTION>unl_cpu</FUNCTION>( void )
</programlisting>
<programlisting>
ER <FUNCTION>dis_int</FUNCTION>(
UINT <EMPHASIS>eintno</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>ena_int</FUNCTION>(
UINT <EMPHASIS>eintno</EMPHASIS> )
</programlisting>
<programlisting>
void <FUNCTION>ret_wup</FUNCTION>(
ID <EMPHASIS>tskid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>iwup_tsk</FUNCTION>(
ID <EMPHASIS>tskid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>isig_sem</FUNCTION>(
ID <EMPHASIS>semid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>iset_flg</FUNCTION>(
ID <EMPHASIS>flgid ,</EMPHASIS>
UID<EMPHASIS> setptn</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>isend_msg</FUNCTION>(
ID <EMPHASIS>mbxid ,</EMPHASIS>
T_MSG<EMPHASIS> *pk_msg</EMPHASIS> )</PROGRAMLISTING>
<PARA>Note that <FUNCTION>ret_int()</FUNCTION> and
the <FUNCTION>ret_wup()</FUNCTION> are implemented
as macros, containing a &ldquo;return&rdquo; statement.</PARA>
<PARA>Also note that <FUNCTION>ret_wup()</FUNCTION> and
the <FUNCTION>ixxx_yyy()</FUNCTION> style functions
will only work when called from an ISR whose associated DSR is <FUNCTION>cyg_uitron_dsr()</FUNCTION>,
as specified in include file <filename>&lt;cyg/compat/uitron/uit_ifnc.h&gt;</filename>,
which defines the <FUNCTION>ixxx_yyy()</FUNCTION> style
functions also.</PARA>
<PARA>If you are writing interrupt handlers more in the
<EMPHASIS>eCos</EMPHASIS> style, with separate ISR and DSR routines both of
your own devising, do not use these special functions from a DSR: use plain
<FUNCTION>xxx_yyy()</FUNCTION> style functions (with no &lsquo;i&rsquo; prefix)
instead, and do not call any &micro;ITRON functions from the ISR at
all.</PARA>
<PARA>The following functions are not supported in this release: </PARA>
<PROGRAMLISTING>ER <FUNCTION>def_int</FUNCTION>(
UINT <EMPHASIS>dintno,</EMPHASIS>
T_DINT *<EMPHASIS>pk_dint</EMPHASIS> )</programlisting>
<programlisting>
ER <FUNCTION>chg_iXX</FUNCTION>(
UINT <EMPHASIS>iXXXX</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>ref_iXX</FUNCTION>(
UINT * <EMPHASIS>p_iXXXX</EMPHASIS> )</PROGRAMLISTING>
<PARA>These unsupported functions are all Level C (CPU dependent).
Equivalent functionality is available via other <EMPHASIS>eCos</EMPHASIS>-specific
APIs. </PARA>
<SECT2>
<TITLE>Error checking</TITLE>
<PARA>The following conditions are only checked for, and only return
errors if
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
is enabled:</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA><FUNCTION>loc/unl_cpu()</FUNCTION>
: these must only be called in a
&micro;ITRON task context, else E_CTX.</PARA>
</LISTITEM>
<LISTITEM>
<PARA><FUNCTION>dis/ena_int()</FUNCTION>
: the interrupt number must be in range as specified by the platform
HAL in qustion, else E_PAR.</PARA>
</LISTITEM>
</ITEMIZEDLIST>
</SECT2>
</SECT1>
<SECT1 id="compat-uitron-memory-pool-mgmt-functions">
<TITLE><!-- <index></index> --> Memory pool Management Functions</TITLE>
<PARA>These functions are fully supported in this release: </PARA>
<PROGRAMLISTING>ER <FUNCTION>get_blf</FUNCTION>(
VP *<EMPHASIS>p_blf,</EMPHASIS> ID <EMPHASIS>mpfid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>pget_blf</FUNCTION>(
VP *<EMPHASIS>p_blf,</EMPHASIS> ID <EMPHASIS>mpfid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>tget_blf</FUNCTION>(
VP *<EMPHASIS>p_blf,</EMPHASIS> ID <EMPHASIS>mpfid,</EMPHASIS> TMO <EMPHASIS>tmout</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>rel_blf</FUNCTION>(
ID <EMPHASIS>mpfid,</EMPHASIS> VP <EMPHASIS>blf</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>ref_mpf</FUNCTION>(
T_RMPF *<EMPHASIS>pk_rmpf,</EMPHASIS> ID <EMPHASIS>mpfid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>get_blk</FUNCTION>(
VP *<EMPHASIS>p_blk,</EMPHASIS> ID <EMPHASIS>mplid,</EMPHASIS> INT <EMPHASIS>blksz</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>pget_blk</FUNCTION>(
VP *<EMPHASIS>p_blk,</EMPHASIS> ID <EMPHASIS>mplid,</EMPHASIS> INT <EMPHASIS>blksz</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>tget_blk</FUNCTION>(
VP *<EMPHASIS>p_blk,</EMPHASIS> ID <EMPHASIS>mplid,</EMPHASIS> INT <EMPHASIS>blksz,</EMPHASIS> TMO <EMPHASIS>tmout</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>rel_blk</FUNCTION>(
ID <EMPHASIS>mplid,</EMPHASIS> VP <EMPHASIS>blk</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>ref_mpl</FUNCTION>(
T_RMPL *<EMPHASIS>pk_rmpl,</EMPHASIS> ID <EMPHASIS>mplid )
</EMPHASIS></programlisting>
 
<PARA>Note that of the memory provided for a particular pool to
manage in the static initialization of the memory pool objects,
some memory will be used to manage the pool itself. Therefore the
number of blocks * the blocksize will be less than the total
memory size. </PARA>
<PARA>The following functions are supported in this release, when
enabled with
<LITERAL>CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE</LITERAL>
or
<LITERAL>CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE</LITERAL>
as appropriate, with some restrictions: </PARA>
<PROGRAMLISTING>ER <FUNCTION>cre_mpl</FUNCTION>(
ID <EMPHASIS>mplid,</EMPHASIS> T_CMPL *<EMPHASIS>pk_cmpl</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>del_mpl</FUNCTION>(
ID <EMPHASIS>mplid</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>cre_mpf</FUNCTION>(
ID <EMPHASIS>mpfid,</EMPHASIS> T_CMPF *<EMPHASIS>pk_cmpf</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>del_mpf</FUNCTION>(
ID <EMPHASIS>mpfid</EMPHASIS> )</PROGRAMLISTING>
<PARA>Because of the static initialization facilities provided for
system objects, a memory pool is allocated a region of memory to
manage statically in the configuration. So while memory pools can
be created and deleted, the same area of memory is used for that
memory pool (memory pool ID number) each time. The requested variable pool
size (pk_cmpl-&gt;mplsz) or the number of fixed-size
blocks (pk_cmpf-&gt;mpfcnt) times the block size
(pk_cmpf-&gt;blfsz) are checked for fitting within
the statically allocated memory area, so if a create call succeeds,
the resulting pool will be at least as large as that requested.
For this reason <FUNCTION>del_mpl()</FUNCTION> and <FUNCTION>del_mpf()</FUNCTION> do
not in any sense free the memory that was managed by the deleted
pool for use by other pools; it may only be managed by a pool of
the same object id. </PARA>
<PARA>For both fixed and variable memory pools, the queueing order
when waiting on a synchronization object depends on the underlying
kernel configuration. The multi-level queue scheduler is required
for strict &micro;ITRON conformance and
it queues tasks in FIFO order, so requests to create an object with
priority queueing of tasks (pk_cxxx-&gt;xxxatr = TA_TPRI)
are rejected with E_RSATR. Additional undefined bits in
the attributes fields must be zero. </PARA>
<PARA>In general, extended information (pk_cxxx-&gt;exinf)
is ignored. </PARA>
<SECT2>
<TITLE>Error checking</TITLE>
<PARA>The following conditions are only checked for, and only return
errors if
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
is enabled:</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>invalid object id; less than 1 or greater than
<LITERAL>CYGNUM_UITRON_MEMPOOLVAR/MEMPOOLFIXED</LITERAL>
as appropriate returns E_ID</PARA>
</LISTITEM>
<LISTITEM>
<PARA>dispatching is enabled in any call which can sleep, or
E_CTX</PARA>
</LISTITEM>
<LISTITEM>
<PARA>tmout must be positive, otherwise E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>pk_cxxx pointers in
<FUNCTION>cre_xxx()</FUNCTION>
must be valid pointers, or E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>return value pointer in
<FUNCTION>ref_xxx()</FUNCTION>
is a valid pointer, or E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>return value pointers in get block routines is a valid
pointer, or E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>blocksize request in get variable block routines is greater
than zero, or E_PAR</PARA>
</LISTITEM>
</ITEMIZEDLIST>
<PARA>The following conditions are checked for, and can return error
codes, regardless of the setting of
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>:
</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>When create and delete functions
<FUNCTION>cre_xxx()</FUNCTION>
and
<FUNCTION>del_xxx()</FUNCTION>
are supported, all calls which use a valid object ID number check
that the object exists. If not, E_NOEXS is returned.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>When create functions
<FUNCTION>cre_xxx()</FUNCTION>
are supported, if the object already exists, then E_OBJ</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In any call which can sleep, such as
<FUNCTION>get_blk()</FUNCTION>
: return codes E_TMOUT, E_RLWAI, E_DLT
or of course E_OK are returned depending on the reason
for terminating the sleep</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In polling functions such as
<FUNCTION>pget_blk()</FUNCTION>
return codes E_TMOUT or E_OK are returned depending
on the state of the synchronization object</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In creation functions, the attributes must be compatible
with the selected underlying kernel configuration: in
<FUNCTION>cre_mpl()</FUNCTION>
<LITERAL>pk_cmpl-&gt;mplatr</LITERAL>
must be equal to
<LITERAL>TA_TFIFO</LITERAL>
else E_RSATR.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In
<FUNCTION>cre_mpf()</FUNCTION>
<LITERAL>pk_cmpf-&gt;mpfatr</LITERAL>
must be equal to
<LITERAL>TA_TFIFO</LITERAL>
else E_RSATR.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In creation functions, the requested size of the memory
pool must not be larger than that statically configured for the
pool else E_RSATR; see the configuration option
&ldquo;Option: Static initializers&rdquo;.
In
<FUNCTION>cre_mpl()</FUNCTION>
<LITERAL>pk_cmpl-&gt;mplsz</LITERAL>
is the field of interest</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In
<FUNCTION>cre_mpf()</FUNCTION>
the product of
<LITERAL>pk_cmpf-&gt;blfsz</LITERAL>
and
<LITERAL>pk_cmpf-&gt;mpfcnt</LITERAL>
must be smaller than the memory statically configured for the pool
else E_RSATR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>In functions which return memory to the pool
<FUNCTION>rel_blk()</FUNCTION>
and
<FUNCTION>rel_blf()</FUNCTION>
, if the free fails, for example because the memory did not come
from that pool originally, then E_PAR is returned</PARA>
</LISTITEM>
</ITEMIZEDLIST>
</SECT2>
</SECT1>
<SECT1 id="compat-uitron-time-mgmt-functions">
<TITLE><!-- <index></index> -->Time Management Functions</TITLE>
<PARA>These functions are fully supported in this release: </PARA>
<PROGRAMLISTING>ER <FUNCTION>set_tim</FUNCTION>(
SYSTIME *<EMPHASIS>pk_tim</EMPHASIS> )</PROGRAMLISTING>
<CAUTION>
<PARA> Setting the time may cause erroneous operation of the
kernel, for example a task performing a wait with a
time-out may never awaken.</PARA>
</CAUTION>
<PROGRAMLISTING>ER <FUNCTION>get_tim</FUNCTION>(
SYSTIME *<EMPHASIS>pk_tim</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>dly_tsk</FUNCTION>(
DLYTIME <EMPHASIS>dlytim</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>def_cyc</FUNCTION>(
HNO <EMPHASIS>cycno,</EMPHASIS> T_DCYC *<EMPHASIS>pk_dcyc</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>act_cyc</FUNCTION>(
HNO <EMPHASIS>cycno,</EMPHASIS> UINT <EMPHASIS>cycact</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>ref_cyc</FUNCTION>(
T_RCYC *<EMPHASIS>pk_rcyc,</EMPHASIS> HNO <EMPHASIS>cycno</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>def_alm</FUNCTION>(
HNO <EMPHASIS>almno,</EMPHASIS> T_DALM *<EMPHASIS>pk_dalm</EMPHASIS> )
</programlisting>
<programlisting>
ER <FUNCTION>ref_alm</FUNCTION>(
T_RALM *<EMPHASIS>pk_ralm,</EMPHASIS> HNO <EMPHASIS>almno</EMPHASIS> )
</programlisting>
<programlisting>
void <FUNCTION>ret_tmr</FUNCTION>( void )</programlisting>
<sect2>
<title>Error checking</title>
<PARA>The following conditions are only checked for, and only return
errors if
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
is enabled:</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>invalid handler number; less than 1 or greater than
<LITERAL>CYGNUM_UITRON_CYCLICS/ALARMS</LITERAL>
as appropriate, or E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>dispatching is enabled in
<FUNCTION>dly_tsk()</FUNCTION>
, or E_CTX</PARA>
</LISTITEM>
<LISTITEM>
<PARA>dlytim must be positive or zero, otherwise E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>return value pointer in
<FUNCTION>ref_xxx()</FUNCTION>
is a valid pointer, or E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>params within pk_dalm and pk_dcyc must
be valid, or E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>cycact in
<FUNCTION>act_cyc()</FUNCTION>
must be valid, or E_PAR</PARA>
</LISTITEM>
<LISTITEM>
<PARA>handler must be defined in
<FUNCTION>ref_xxx()</FUNCTION>
and
<FUNCTION>act_cyc()</FUNCTION>
, or E_NOEXS</PARA>
</LISTITEM>
<LISTITEM>
<PARA>parameter pointer must be a good pointer in
<FUNCTION>get_tim()</FUNCTION>
and
<FUNCTION>set_tim()</FUNCTION>
, otherwise E_PAR is returned</PARA>
</LISTITEM>
</ITEMIZEDLIST>
<PARA>The following conditions are checked for, and can return
error codes, regardless of the setting of
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
:</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA><FUNCTION>dly_tsk()</FUNCTION>
: return code E_RLWAI is returned depending on the reason
for terminating the sleep</PARA>
</LISTITEM>
</ITEMIZEDLIST>
</sect2>
</SECT1>
<SECT1 id="compat-uitron-system-mgmt-functions">
<TITLE><!-- <index></index> --> System Management Functions</TITLE>
<PARA>These functions are fully supported in this release:
</PARA>
<PROGRAMLISTING>ER <FUNCTION>get_ver</FUNCTION>(
T_VER *<EMPHASIS>pk_ver</EMPHASIS> )
</PROGRAMLISTING>
<PROGRAMLISTING>ER <FUNCTION>ref_sys</FUNCTION>(
T_RSYS *<EMPHASIS>pk_rsys</EMPHASIS> )
</PROGRAMLISTING>
<PROGRAMLISTING>ER <FUNCTION>ref_cfg</FUNCTION>(
T_RCFG *<EMPHASIS>pk_rcfg</EMPHASIS> )
</PROGRAMLISTING>
<PARA>Note that the information returned by each of these calls
may be configured to match the user's own versioning system,
and the values supplied by the default configuration may be inappropriate. </PARA>
<PARA>These functions are not supported in this release: </PARA>
<PROGRAMLISTING>ER <FUNCTION>def_svc</FUNCTION>(
FN <EMPHASIS>s_fncd,</EMPHASIS>
T_DSVC *<EMPHASIS>pk_dsvc</EMPHASIS> )
</PROGRAMLISTING>
<PROGRAMLISTING>ER <FUNCTION>def_exc</FUNCTION>(
UINT <EMPHASIS>exckind,</EMPHASIS>
T_DEXC *<EMPHASIS>pk_dexc</EMPHASIS> )
</PROGRAMLISTING>
<SECT2>
<TITLE>Error checking</TITLE>
<PARA>The following conditions are only checked for, and
only return errors if
<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
is enabled: </PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>return value pointer in all calls is a valid
pointer, or E_PAR</PARA>
</LISTITEM>
</ITEMIZEDLIST>
</SECT2>
</SECT1>
<SECT1 id="compat-uitron-network-support-functions">
<TITLE><!-- <index></index> --> Network Support Functions</TITLE>
<PARA>None of these functions are supported in this release.
</PARA>
</SECT1>
<SECT1 id="compat-uitron-configuration-faq">
<TITLE><!-- <index></index> -->&micro;ITRON Configuration FAQ</TITLE>
<PARA><EMPHASIS>Q: How are &micro;ITRON objects created?</EMPHASIS>
</PARA>
<PARA>
For each type of uITRON object (tasks, semaphores, flags, mboxes, mpf, mpl)
these two quantities are controlled by configuration:
</PARA>
<ITEMIZEDLIST>
<LISTITEM><PARA>
The <EMPHASIS>maximum</EMPHASIS> number of this type of object.
</PARA></LISTITEM>
<LISTITEM><PARA>
The number of these objects which exist <EMPHASIS>initially</EMPHASIS>.
</PARA></LISTITEM>
</ITEMIZEDLIST>
<PARA>
This is assuming that for the relevant object type,
<EMPHASIS>create</EMPHASIS> and <EMPHASIS>delete</EMPHASIS>
operations are enabled; enabled is the default. For example, the option
<LITERAL>CYGPKG_UITRON_MBOXES_CREATE_DELETE</LITERAL>
controls whether the functions
<FUNCTION>cre_mbx()</FUNCTION>
and
<FUNCTION>del_mbx()</FUNCTION>
exist in the API. If not, then the maximum number of
mboxes is the same as the initial number of mboxes, and so on for all
&micro;ITRON object types.
</PARA>
<PARA>
Mboxes have no initialization, so there are only a few, simple
configuration options:
</PARA>
<ITEMIZEDLIST>
<LISTITEM><PARA>
<LITERAL>CYGNUM_UITRON_MBOXES</LITERAL>
is the total number of mboxes that you can have in the
system. By default this is 4, so you can use mboxes 1,2,3 and 4. You
cannot create mboxes outside this range; trying to
<FUNCTION>cre_mbx(5,...)</FUNCTION>
will return an error.
</PARA></LISTITEM>
<LISTITEM><PARA>
<LITERAL>CYGNUM_UITRON_MBOXES_INITIALLY</LITERAL>
is the number of mboxes created
automatically for you, during startup. By default this is 4, so all 4
mboxes exist already, and an attempt to create one of these
eg. <FUNCTION>cre_mbx(3,...)</FUNCTION>
will return an error because the mbox in quesion already
exists. You can delete a pre-existing mbox, and then re-create it.
</PARA></LISTITEM>
</ITEMIZEDLIST>
<PARA>
If you change
<LITERAL>CYGNUM_UITRON_MBOXES_INITIALLY</LITERAL>,
for example to 0, no mboxes
are created automatically for you during startup. Any attempt to use an
mbox without creating it will return E_NOEXS because the mbox does not
exist. You can create an mbox, say <FUNCTION>cre_mbx(3,...)</FUNCTION>
and then use it, say
<FUNCTION>snd_msg(3,&amp;foo)</FUNCTION>, and all will be well.
</PARA>
<PARA><EMPHASIS>Q: How are &micro;ITRON objects initialized?</EMPHASIS>
</PARA>
<PARA>
Some object types have optional initialization. Semaphores are an
example. You could have
<LITERAL>CYGNUM_UITRON_SEMAS</LITERAL>=10 and
<LITERAL>CYGNUM_UITRON_SEMAS_INITIALLY</LITERAL>=5
which means you can use semaphores 1-5
straight off, but you must create semaphores 6-10 before you can use them.
If you decide not to initialize semaphores, semaphores 1-5 will have an
initial count of zero. If you decide to initialize them, you must supply
a dummy initializer for semaphores 6-10 also. For example,
in terms of the configuration output in
<filename>pkgconf/uitron.h</filename>:
</PARA>
<PROGRAMLISTING>
#define CYGDAT_UITRON_SEMA_INITIALIZERS \
CYG_UIT_SEMA( 1 ), \
CYG_UIT_SEMA( 0 ), \
CYG_UIT_SEMA( 0 ), \
CYG_UIT_SEMA( 99 ), \
CYG_UIT_SEMA( 1 ), \
CYG_UIT_SEMA_NOEXS, \
CYG_UIT_SEMA_NOEXS, \
CYG_UIT_SEMA_NOEXS, \
CYG_UIT_SEMA_NOEXS, \
CYG_UIT_SEMA_NOEXS
</PROGRAMLISTING>
<PARA>
Semaphore 1 will have initial count 1, semaphores 2 and 3 will be zero,
number 4 will be 99 initially, 5 will be one and numbers 6 though 10 do not
exist initially.
</PARA>
<PARA>
Aside: this is how the definition of the symbol would appear in the
configuration header file <filename>pkgconf/uitron.h</filename> &mdash;
unfortunately editing such a long, multi-line definition is somewhat
cumbersome in the GUI config tool in current releases. The macros
<LITERAL>CYG_UIT_SEMA()</LITERAL>
&mdash; to create a semaphore initializer &mdash; and
<LITERAL>CYG_UIT_SEMA_NOEXS</LITERAL>
&mdash; to invoke a dummy initializer &mdash;
are provided in in the environment to help with this. Similar macros are
provided for other object types. The resulting #define symbol is used in
the context of a C++ array initializer, such as:
<PROGRAMLISTING>
Cyg_Counting_Semaphore2 cyg_uitron_SEMAS[ CYGNUM_UITRON_SEMAS ] = {
CYGDAT_UITRON_SEMA_INITIALIZERS
};
</PROGRAMLISTING>
which is eventually macro-processed to give
<PROGRAMLISTING>
Cyg_Counting_Semaphore2 cyg_uitron_SEMAS[ 10 ] = {
Cyg_Counting_Semaphore2( ( 1 ) ),
Cyg_Counting_Semaphore2( ( 0 ) ),
Cyg_Counting_Semaphore2( ( 0 ) ),
Cyg_Counting_Semaphore2( ( 99 ) ),
Cyg_Counting_Semaphore2( ( 1 ) ),
Cyg_Counting_Semaphore2(0),
Cyg_Counting_Semaphore2(0),
Cyg_Counting_Semaphore2(0),
Cyg_Counting_Semaphore2(0),
Cyg_Counting_Semaphore2(0),
};
</PROGRAMLISTING>
so you can see how it is necessary to include the dummy entries in that
definition, otherwise the resulting code will not compile correctly.
</PARA>
<PARA>
If you choose
<LITERAL>CYGNUM_UITRON_SEMAS_INITIALLY</LITERAL>=0
it is meaningless to initialize them, for they must be created and so
initialized then, before use.
</PARA>
<PARA><EMPHASIS>Q: What about &micro;ITRON tasks?</EMPHASIS>
</PARA>
<PARA>
Some object types require initialization. Tasks are an example of this.
You must provide a task with a priority, a function to enter when the task
starts, a name (for debugging purposes), and some memory to use for the stack.
For example (again in terms of the resulting
definitions in <filename>pkgconf/uitron.h</filename>):
</PARA>
<PROGRAMLISTING>
#define CYGNUM_UITRON_TASKS 4 // valid task ids are 1,2,3,4
#define CYGNUM_UITRON_TASKS_INITIALLY 4 // they all exist at start
 
#define CYGDAT_UITRON_TASK_EXTERNS \
extern "C" void startup( unsigned int ); \
extern "C" void worktask( unsigned int ); \
extern "C" void lowtask( unsigned int ); \
static char stack1[ CYGNUM_UITRON_STACK_SIZE ], \
stack2[ CYGNUM_UITRON_STACK_SIZE ], \
stack3[ CYGNUM_UITRON_STACK_SIZE ], \
stack4[ CYGNUM_UITRON_STACK_SIZE ];
 
#define CYGDAT_UITRON_TASK_INITIALIZERS \
CYG_UIT_TASK("main task", 8, startup, &amp;stack1, sizeof( stack1 )), \
CYG_UIT_TASK("worker 2" , 9, worktask, &amp;stack2, sizeof( stack2 )), \
CYG_UIT_TASK("worker 3" , 9, worktask, &amp;stack3, sizeof( stack3 )), \
CYG_UIT_TASK("low task" ,20, lowtask, &amp;stack4, sizeof( stack4 )), \
 
</PROGRAMLISTING>
<PARA>
So this example has all four tasks statically configured to exist, ready to
run, from the start of time. The &ldquo;main task&rdquo; runs a routine
called <FUNCTION>startup()</FUNCTION> at priority 8. Two
&ldquo;worker&rdquo; tasks run both a priority 9, and a &ldquo;low
priority&rdquo; task runs at priority 20 to do useful non-urgent background
work.
</PARA>
<screen>
Task ID | Exists at | Function | Priority | Stack | Stack
number | startup | entry | | address | size
--------+-----------+----------+----------+---------+----------
1 | Yes | startup | 8 | &amp;stack1 | CYGNUM...
2 | Yes | worktask | 9 | &amp;stack2 | CYGNUM...
3 | Yes | worktask | 9 | &amp;stack3 | CYGNUM...
4 | Yes | lowtask | 20 | &amp;stack4 | CYGNUM...
--------+-----------+----------+----------+---------+----------
</screen>
<PARA><EMPHASIS>Q: How can I create &micro;ITRON tasks in the program?</EMPHASIS>
</PARA>
<PARA>
You must provide free slots in the task table in which to create new tasks,
by configuring the number of tasks existing initially to be smaller than
the total.
For a task ID which does not initially exist, it will be told what routine
to call, and what priority it is, when the task is created. But you must
still set aside memory for the task to use for its stack, and give it a
name during initialization. For example:
</PARA>
 
<PROGRAMLISTING>
#define CYGNUM_UITRON_TASKS 4 // valid task ids are 1-4
#define CYGNUM_UITRON_TASKS_INITIALLY 1 // only task #1 exists
 
#define CYGDAT_UITRON_TASK_EXTERNS \
extern "C" void startup( unsigned int ); \
static char stack1[ CYGNUM_UITRON_STACK_SIZE ], \
stack2[ CYGNUM_UITRON_STACK_SIZE ], \
stack3[ CYGNUM_UITRON_STACK_SIZE ], \
stack4[ CYGNUM_UITRON_STACK_SIZE ];
 
#define CYGDAT_UITRON_TASK_INITIALIZERS \
CYG_UIT_TASK( "main", 8, startup, &amp;stack1, sizeof( stack1 ) ), \
CYG_UIT_TASK_NOEXS( "slave", &amp;stack2, sizeof( stack2 ) ), \
CYG_UIT_TASK_NOEXS( "slave2", &amp;stack3, sizeof( stack3 ) ), \
CYG_UIT_TASK_NOEXS( "slave3", &amp;stack4, sizeof( stack4 ) ), \
 
</PROGRAMLISTING>
<PARA>
So tasks numbered 2,3 and 4 have been given their stacks during startup,
though they do not yet exist in terms of <FUNCTION>cre_tsk()</FUNCTION> and
<FUNCTION>del_tsk()</FUNCTION> so you can create tasks 2&ndash;4 at
runtime.
</PARA>
<screen>
Task ID | Exists at | Function | Priority | Stack | Stack
number | startup | entry | | address | size
--------+-----------+----------+----------+---------+----------
1 | Yes | startup | 8 | &amp;stack1 | CYGNUM...
2 | No | N/A | N/A | &amp;stack2 | CYGNUM...
3 | No | N/A | N/A | &amp;stack3 | CYGNUM...
4 | No | N/A | N/A | &amp;stack4 | CYGNUM...
--------+-----------+----------+----------+---------+----------
</screen>
<PARA>
(you must have at least one task at startup in order that the system can
actually run; this is not so for other uITRON object types)
</PARA>
<PARA><EMPHASIS>Q: Can I have different stack sizes for &micro;ITRON tasks?</EMPHASIS>
</PARA>
<PARA>
Simply set aside different amounts of memory for each task to use for its
stack. Going back to a typical default setting for the &micro;ITRON tasks,
the definitions in <filename>pkgconf/uitron.h</filename> might look like this:
</PARA>
<PROGRAMLISTING>
#define CYGDAT_UITRON_TASK_EXTERNS \
extern "C" void task1( unsigned int ); \
extern "C" void task2( unsigned int ); \
extern "C" void task3( unsigned int ); \
extern "C" void task4( unsigned int ); \
static char stack1[ CYGNUM_UITRON_STACK_SIZE ], \
stack2[ CYGNUM_UITRON_STACK_SIZE ], \
stack3[ CYGNUM_UITRON_STACK_SIZE ], \
stack4[ CYGNUM_UITRON_STACK_SIZE ];
#define CYGDAT_UITRON_TASK_INITIALIZERS \
CYG_UIT_TASK( "t1", 1, task1, &amp;stack1, CYGNUM_UITRON_STACK_SIZE ), \
CYG_UIT_TASK( "t2", 2, task2, &amp;stack2, CYGNUM_UITRON_STACK_SIZE ), \
CYG_UIT_TASK( "t3", 3, task3, &amp;stack3, CYGNUM_UITRON_STACK_SIZE ), \
CYG_UIT_TASK( "t4", 4, task4, &amp;stack4, CYGNUM_UITRON_STACK_SIZE )
 
</PROGRAMLISTING>
<PARA>
Note that
<LITERAL>CYGNUM_UITRON_STACK_SIZE</LITERAL>
is used to control the size of the stack
objects themselves, and to tell the system what size stack is being provided.
</PARA>
<PARA>
Suppose instead stack sizes of 2000, 1000, 800 and 800 were required:
this could be achieved by using the GUI config tool to edit these
options, or editting the <filename>.ecc</filename> file to get these
results in <filename>pkgconf/uitron.h</filename>:
</PARA>
<PROGRAMLISTING>
#define CYGDAT_UITRON_TASK_EXTERNS \
extern "C" void task1( unsigned int ); \
extern "C" void task2( unsigned int ); \
extern "C" void task3( unsigned int ); \
extern "C" void task4( unsigned int ); \
static char stack1[ 2000 ], \
stack2[ 1000 ], \
stack3[ 800 ], \
stack4[ 800 ];
#define CYGDAT_UITRON_TASK_INITIALIZERS \
CYG_UIT_TASK( "t1", 1, task1, &amp;stack1, sizeof( stack1 ) ), \
CYG_UIT_TASK( "t2", 2, task2, &amp;stack2, sizeof( stack2 ) ), \
CYG_UIT_TASK( "t3", 3, task3, &amp;stack3, sizeof( stack3 ) ), \
CYG_UIT_TASK( "t4", 4, task4, &amp;stack4, sizeof( stack4 ) )
</PROGRAMLISTING>
<PARA>
Note that the sizeof() operator has been used to tell the system what size
stacks are provided, rather than quoting a number (which is difficult for
maintenance) or the symbol
<LITERAL>CYGNUM_UITRON_STACK_SIZE</LITERAL>
(which is wrong).
</PARA>
<PARA>
We recommend using (if available in your release) the stacksize symbols
provided in the architectural HAL for your target, called
<LITERAL>CYGNUM_HAL_STACK_SIZE_TYPICAL</LITERAL>
and
<LITERAL>CYGNUM_HAL_STACK_SIZE_MINIMUM</LITERAL>.
So a better (more portable) version of the above might be:
</PARA>
<PROGRAMLISTING>
#define CYGDAT_UITRON_TASK_EXTERNS \
extern "C" void task1( unsigned int ); \
extern "C" void task2( unsigned int ); \
extern "C" void task3( unsigned int ); \
extern "C" void task4( unsigned int ); \
static char stack1[ CYGNUM_HAL_STACK_SIZE_TYPICAL + 1200 ], \
stack2[ CYGNUM_HAL_STACK_SIZE_TYPICAL + 200 ], \
stack3[ CYGNUM_HAL_STACK_SIZE_TYPICAL ], \
stack4[ CYGNUM_HAL_STACK_SIZE_TYPICAL ];
 
#define CYGDAT_UITRON_TASK_INITIALIZERS \
CYG_UIT_TASK( "t1", 1, task1, &amp;stack1, sizeof( stack1 ) ), \
CYG_UIT_TASK( "t2", 2, task2, &amp;stack2, sizeof( stack2 ) ), \
CYG_UIT_TASK( "t3", 3, task3, &amp;stack3, sizeof( stack3 ) ), \
CYG_UIT_TASK( "t4", 4, task4, &amp;stack4, sizeof( stack4 ) )
</PROGRAMLISTING>
</SECT1>
</CHAPTER>
</part>
/v2_0/ChangeLog
0,0 → 1,873
2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
 
* cdl/uitron.cdl: Update doc link.
 
2002-05-27 Jesper Skov <jskov@redhat.com>
 
* cdl/uitron.cdl: Don't build C tests when C++ options selected.
 
2002-05-22 Nick Garnett <nickg@redhat.com>
 
* doc/uitron.sgml: Fixed dangling xref.
 
2002-02-19 Mark Salter <msalter@redhat.com>
 
* doc/uitron.sgml: Fixed typos and such.
 
2002-02-14 Hugo Tyson <hmt@redhat.com>
 
* doc/uitron.sgml: General polishing... Tidied up broken emPHAsis
on closing parentheses of function lists. Reduced line length of
same to fit real paper, I hope. Added LITERAL tags all over
config option mentions.
 
New stuff... Added a whole new section "[u]ITRON Configuration
FAQ" based on some email answers I have given in the past in
support of customers.
 
2002-02-13 Hugo Tyson <hmt@redhat.com>
 
* doc/uitron.sgml: NEW FILE: Make id tags qualified with
compat-uitron- and add a couple of tags; tidy up formatting of
some function listings; correct comment on using functions in your
own DSRs and ISRs.
 
2002-01-24 Jesper Skov <jskov@redhat.com>
 
* include/uit_func.inl (ena_int, dis_int): Wrap
HAL_MASK_INTERRUPT/HAL_UNMASK_INTERRUPT in interrupt
disable/restore pairs.
* tests/testintr.cxx (detach_isr, attach_isr): Change order of
mask/unmask and disable/restore.
 
2001-04-30 Jonathan Larmour <jlarmour@redhat.com>
 
* src/uit_objs.cxx: Workaround xscale tools preprocessor bug
by avoiding determining the stack size with the preprocessor.
* cdl/tasks.cdl (CYGDAT_UITRON_TASK_EXTERNS and
CYGDAT_UITRON_TASK_INITIALISERS): Ditto
 
2001-04-21 Bart Veer <bartv@redhat.com>
 
* tests/testintr.cxx (task1):
Disable one of the tests on the synthetic target, it requires
consistent cpu timing that cannot be guaranteed.
 
2000-11-01 Jesper Skov <jskov@redhat.com>
 
* include/uit_func.inl: CYG_SCHED_UNIQUE_PRIORITIES changed to
CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
 
2000-09-13 Jonathan Larmour <jlarmour@redhat.com>
 
* include/uit_objs.hxx (CYG_UITRON_OBJS_INIT_PRIORITY): Define
with correct priority now.
 
2000-08-03 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* include/uit_func.inl (ref_mpf): Compute used blocks from
bytes used / blocks size rather than now obsolete blockcount member
 
2000-07-04 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* include/uit_func.inl: Update all memory pool related functions to
reflect the new interface to memory pools, and that they come from
the new CYGPKG_MEMALLOC package
 
* cdl/uitron.cdl: CYGPKG_UITRON_MEMPOOLFIXED and
CYGPKG_UITRON_MEMPOOLVAR require the CYGPKG_MEMALLOC package
 
* include/uit_objs.hxx: Update includes - memory pool implementations
are now in CYGPKG_MEMALLOC
 
2000-06-15 Gary Thomas <gthomas@redhat.com>
 
* include/uit_ifnc.h (CYGPRI_UITRON_SET_RETCODE): Always return
'HANDLED'. This fixes some confusion when interrupt chaining.
 
2000-05-15 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_ifnc.h (cyg_uitron_dsr): make this be extern "C"
always; it went wrong when uitron funcs are inline or C++.
 
* src/uit_ifnc.cxx (CYGIMP_UITRON_INLINE_FUNCS): When [re]defining
this, match what CDL defined. Warnings--;
 
2000-05-08 Jesper Skov <jskov@redhat.com>
 
* tests/testintr.cxx (attach_isr, detach_isr): Don't check for
clean vector after a detach when chaining is enabled.
 
2000-03-28 Jesper Skov <jskov@redhat.com>
 
* tests/testintr.cxx: Synchronize with clock before making timer
measurement.
 
2000-03-28 John Dallaway <jld@cygnus.co.uk>
 
* cdl/uitron.cdl:
 
Adjust documentation URLs.
 
2000-03-22 Jesper Skov <jskov@redhat.com>
 
* include/uit_ifnc.h (ret_int): Fix compiler warning.
 
2000-03-13 Jesper Skov <jskov@redhat.com>
 
* tests/testintr.cxx: Don't try to disable clock on PowerPC.
 
2000-03-03 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/testintr.cxx (task1): Only test ena_int() and dis_int()
for E_PAR if CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS.
 
2000-02-28 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_func.h: add ena_int() and dis_int().
 
* include/uit_func.inl (dis_int): New function added.
(ena_int): New function added.
 
* tests/testintr.cxx (task1): Add a test of ena_int() and
dis_int(); easiest done here because we have an interrupt number -
for the clock - in our hands here already for the rest of the
test.
 
2000-02-02 Jesper Skov <jskov@redhat.com>
 
* tests/testintr.cxx: Don't output DELAYLOCKSCHED quite so often
on synthetic target.
 
2000-01-31 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/testintr.cxx (CHECK_TID): Test that get_tid() returns 0 in
ISR context ie. non-task portion.
 
* include/uit_func.inl (get_tid): Check the sched lock for
non-task portions, ie. ISR/DSR will have the scheduler locked.
 
2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
* compat/uitron/current/cdl/uitron.cdl
 
Adjust help URLs in line with new doc layout.
 
2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
* compat/uitron/current/cdl/uitron.cdl
 
Adjust help URLs in line with new doc layout.
 
2000-01-28 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* tests/testintr.cxx (DELAYLOCKSCHED): When in long testing loops,
occasionally output a message to show the test is still alive
 
2000-01-26 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/pkgconf/uitron.h: Add new option
CYGSEM_UITRON_TIME_IS_MILLISECONDS to control just what it says.
 
* include/uit_func.inl (CYG_UITRON_TIME_UIT_TO_SYS32): et al; new
macros optionally to convert to/from milliSeconds if option
CYGSEM_UITRON_TIME_IS_MILLISECONDS is set.
 
* src/uit_func.cxx: Initialize Cyg_Clock::converter type objects
if the time unit is set to milliSeconds.
 
* cdl/uitron.cdl: Add new option
CYGSEM_UITRON_TIME_IS_MILLISECONDS to control just what it says.
 
Add an include of the kernel config file to the generated
pkgconf/uitron.h: tests at the very least need it! This is a
correct thing to do because the kernel config defines a lot of the
semantics of the uITRON layer, as well as being needed for
backward compatibility.
 
Also add uit_ifnc.cxx to the files that need compiling. Due to
the previous screwup, no testing has been applied to the uITRON
system under CDL, because it thought the kernel was absent, so
this had not been detected. Doh.
 
2000-01-25 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/testintr.cxx (cyg_start): externC addded.
 
2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
 
* cdl/*.cdl: Add descriptions to a number of options &c which were
lacking same, also tidied up other typos as noticed en passant.
 
1999-11-09 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* src/uit_objs.cxx: Make the stack size failsafe be tested against
the minimum stack size, not the typical one.
 
1999-11-03 John Dallaway <jld@cygnus.co.uk>
 
* cdl/uitron.cdl: Define tests.
 
1999-10-07 John Dallaway <jld@cygnus.co.uk>
 
* cdl/uitron.cdl: Specify radio buttons using CDL interfaces.
 
1999-09-06 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* include/uit_objs.hxx (CYG_UITRON_OBJS_INIT_PRIORITY): Revert the
below change - we may still be shipping antiquated compilers to
customers. Sigh.
 
1999-09-02 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_objs.hxx (CYG_UITRON_OBJS_INIT_PRIORITY): Enable
using init priority on uitron objects, now that the compilers all
support it fully. AFAI can tell from a quite broad experiment.
 
1999-09-01 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/testintr.cxx (attach_isr): Make it all work: my chosen
default interrupt "level" of 0 means make no interrupts on the
tx39 ;-( oh well. Made the whole test simulator-friendly ie. much
shorter, made the output more friendly to me.
 
1999-08-26 Hugo Tyson <hmt@cygnus.co.uk>
 
* cdl/uitron.cdl (CYGNUM_UITRON_ISR_ACTION_QUEUESIZE): add a
"default_value 32" - ooops.
 
1999-08-26 Hugo Tyson <hmt@cygnus.co.uk>
 
* cdl/uitron.cdl: Add configury for lovely new interrupt-safe
functions: just "try immediate execution" [is the sched lock one?]
and queue size.
 
* include/pkgconf/uitron.h: Add configury for lovely new
interrupt-safe functions: just "try immediate execution" [ie. if
the sched lock is one] and queue size.
 
* include/uit_ifnc.inl: Respond to general configury wrt the
presence of semas, flags, mboxes: only define the ixxx_yyy()
function if the corresponding xxx_yyy() func exists. Remove the
static definitions of the configuration symbols.
 
* src/uit_ifnc.cxx: Respond to general configury wrt the presence
of semas, flags, mboxes: the functions called may not exist!
 
1999-08-25 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_ifnc.h: New file. Prototypes of interrupt-safe
ixxx_yyy() style functions as a porting/backwards-compatibility
aid. Prototype of a suitable DSR to mate with an ISR that uses
them too.
 
* include/uit_ifnc.inl: New file. Bodies for possible inlining of
the ixxx_yyy() style functions; organized much like the standard
uITRON functions.
 
* src/uit_ifnc.cxx: New file. Implementation of the DSR provided,
plus concrete instantiations of the ixxx_yyy() style functions.
 
* tests/testintr.cxx: New file. Test for the ixxx_yyy() functions
newly provided above. Rather unpleasant: it is necessary to break
type-safety to get access to the kernel's interrupt object that
drives the realtime clock. Perhaps a neater way will follow.
 
* tests/PKGconf.mak (TESTS): Add new testcase testintr.cxx
* src/PKGconf.mak (COMPILE): Add new source file uit_ifnc.cxx
 
1999-08-17 John Dallaway <jld@cygnus.co.uk>
 
* cdl/uitron.cdl: Implement radio buttons using
"FIXME radio" hack in description field for now.
 
1999-07-30 John Dallaway <jld@cygnus.co.uk>
 
* cdl/uitron.cdl: Tidy display string capitalisation.
 
1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/testcx7.cxx: Include new stackmon header.
 
1999-05-20 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/testcx7.cxx (task1): Add some statistics dumping about
stack usage; since this is quite a long and arduous test. This
just helps en passant with testing the interrupt stack work that's
been happening recently. C++ only, so not for test7.
 
1999-05-17 Hugo Tyson <hmt@masala.cygnus.co.uk>
 
* include/uit_func.inl (ter_tsk): Only up the priority of the
killee if priorities are not unique or we are not already
elevated. This is to prevent asserts with the bitmap scheduler.
(chg_pri): Support a level X feature, pri zero => reset to the
thread's initial priority.
 
1999-05-14 Hugo Tyson <hmt@masala.cygnus.co.uk>
 
* include/uit_objs.hxx: object array declaration macro now
contains constructor priority ordering rune; if 0'd out pending
99r1 compiler cutover.
 
1999-04-23 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/testcx7.cxx: T2_MALLOC definition; only make it smaller
than the main consumer malloc if coaleasing is enabled, otherwise
the mempool cannot allocate blocks for the consumer for next time.
Fixes PR 18817 - only a random perm disable coalescence.
 
* tests/test7.c: Ditto.
 
1999-04-15 John Dallaway <jld@cygnus.co.uk>
 
* include/pkgconf/uitron.h: Tidy display string capitalization.
 
1999-04-09 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_func.inl (dis_dsp): Remove bad old code which used
to lock the scheduler to implement dis_dsp() and ena_dsp() - which
also stopped the clock, for example. Instead change the calling
thread's priority to 0 internally so that it cannot be preempted
by uITRON threads at least, whose priorities are 1--N. Same
applies to loc/unl_cpu(). Save the "real" priority in a static,
and take notice of it everywhere relevant, such as thread and
system state inquiries, changing (our own) priority, checking for
dispatch enabled in sleeping calls, and so on.
 
* src/uit_func.cxx: New variable cyg_uitron_dis_dsp_old_priority
for holding the "real" priority of a thread whilst we change our
priority to zero (the highest) to prevent dispatching in dis_dsp()
or loc_cpu().
 
* include/uit_func.inl (get_tid): Return 0 for the task id if not
in a uITRON thread, this is better conformance to the spec.
 
1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
 
* src/uit_objs.cxx:
Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
CYGNUM_HAL_MINIMUM_STACK_SIZE.
 
1999-02-23 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* tests/test1.c, tests/test2.c, tests/test3.c, tests/test4.c,
tests/test5.c, tests/test6.c, tests/test7.c, tests/test8.c,
tests/test9.c, tests/testcxx.cxx, tests/testcx2.cxx,
tests/testcx3.cxx, tests/testcx4.cxx, tests/testcx5.cxx,
tests/testcx6.cxx, tests/testcx7.cxx, tests/testcx8.cxx,
tests/testcx9.cxx:
Change all non-applicable cases to use CYG_TEST_NA rather than
CYG_TEST_PASS/CYG_TEST_EXIT
 
1999-02-22 Hugo Tyson <hmt@cygnus.co.uk>
 
* src/uit_objs.cxx: Eeeek! Previous fix was bogus: the override
was too late in the file to take effect. The declaration of the
objects (including stacks) is moved to below the override CPP
runes.
 
1999-02-12 Hugo Tyson <hmt@cygnus.co.uk>
 
* src/uit_objs.cxx (CYG_UITRON_DECL):
Override CYGNUM_UITRON_STACK_SIZE if CYGNUM_HAL_MINIMUM_STACK_SIZE
demands it.
 
* include/pkgconf/uitron.h (CYGNUM_UITRON_STACK_SIZE):
Document that this option can be overridden by HALs demands.
 
1999-02-02 Jesper Skov <jskov@cygnus.co.uk>
PR 18968
* tests/test2.c (task1):
* tests/testcx2.cxx (task1):
Reduce run time on SIM.
 
1999-01-26 Jesper Skov <jskov@cygnus.co.uk>
PR 18788
* tests/test4.c (task1):
* tests/testcx4.cxx (task1):
Extend timeouts when running on HW to avoid failures due to
overhead of GDB interaction.
 
1999-01-25 Jesper Skov <jskov@cygnus.co.uk>
PR 18576
* include/pkgconf/uitron.h (CYGDAT_UITRON_SEMA_INITIALIZERS):
Let default initializers have values that don't cause tests to
fail.
 
1998-11-25 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_func.inl (del_xxx &c):
Make error returns more consistent; E_NOEXS rather than E_OBJ if
the object disappeared during a race.
 
1998-11-19 Hugo Tyson <hmt@cygnus.co.uk>
 
* src/uit_func.cxx (SET_UP_PTRS):
PR 17999; work around codegen bug on tx39 with -Os.
The code is better with the fix regardless, so it's got no
downside. Explicitly condition whether to run a follow-on loop
rather than letting the for-loop sort it out itself.
 
1998-11-16 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/testcx7.cxx (check_waitstate):
Add a routine to check the reported waiting state of the synch
object in question, and call it as necessary. This only added to
the C++ version of the test for enhanced coverage, in case the
enquiry call perturbs the object state; having both versions
present is better. This checks a very recent fix to
kernel...thread.cxx (1998-10-27).
 
1998-10-21 Hugo Tyson <hmt@cygnus.co.uk>
 
* src/uit_func.cxx:
Provide weakly named dummies for task[1-4], which are the defaults
referred to by the task array, so that the uITRON system can be
initialized even when no uITRON tasks have been provided (so long
as no other changes to the task init configury have been made)
This does not pollute the namespace, for these are weak symbols.
Changing them to cyg_uitron_task... would be possible, but it
carries the false implication that those are cygnus names, when
they are really entirely up to the user.
 
* tests/test[123456789].c:
* tests/testcxx.cxx:
* tests/testcx[23456789].cxx:
Undo the previous change: remove dummies for task[1-4] when we
decide not to test anything, they will be provided with weak names
regardles in src/uit_func.cxx.
 
1998-10-20 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/test[123456789].c:
* tests/testcxx.cxx:
* tests/testcx[23456789].cxx:
Provide dummies for task[1-4] when we decide not to test anything,
to encourage correct linking.
 
1998-10-16 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/testcx*.cxx (cyg_start):
[all the C++ tests]
changed cyg_start to externC so that it truly does override the
default one; this is needed for handling the "I cannot test in
this configuration" failures. Of course the C ones were C to
start with.
1998-10-16 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/test[123456789].c:
* tests/testcxx.cxx:
* tests/testcx[23456789].cxx:
All tests are now much more self-configuring wrt turning off
if there are no uITRON objects of the right type to manipulate.
The huge (50-line) #if statement is arranged the way it is so that
clauses checking on each feature can be pasted in and out easily.
So yes, the "&& 1" at the end has a purpose.
Here for the record is a table of feature versus test-used-in:
tsk :: 1 2 3 4 5 6 7 8 9
sem :: 2 3 5 6 7 8
flg :: 2 5 6 7
mbx :: 2 5 6 7
mpl :: 2 5 7 9
mpf :: 2 5 7 9
alm :: 4
cyc :: 4
 
 
1998-10-16 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/test9.c:
* tests/testcx9.cxx:
New tests, test create and delete of memory pools
 
1998-10-15 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/pkgconf/uitron.h:
Add configury for create/delete of memory pools.
Tidy up naming of initializer macros to use for non-existent
(initially) uITRON objects.
Improve comments in CDL-- info fields.
* include/uit_func.h:
Add prototypes for cre/del_mpf/mpl().
 
* include/uit_func.inl:
Implement cre/del_mpf/mpl().
 
* src/uit_objs.cxx:
Support CYG_UIT_MEMPOOLFIXED_NOEXS/CYG_UIT_MEMPOOLVAR_NOEXS(...)
mempool construction macros for non-existent (initially) mempools.
Rename _NONE construction macros to _NOEXS which will make a lot
more sense to uITRON folks.
 
1998-10-14 Hugo Tyson <hmt@masala.cygnus.co.uk>
 
* include/pkgconf/uitron.h:
Add configury for create/delete of tasks.
* include/uit_func.h:
Add prototypes for cre/del_tsk(); correct comment in exd_tsk().
* include/uit_func.inl:
Implement cre/del_tsk() and complete exd_tsk().
Improve NULL/NADR checking on other cre/del calls.
 
* src/uit_func.cxx (cyg_uitron_start):
Deal better with start tasks stuff, for task create/delete.
 
* src/uit_objs.cxx:
Support CYG_UIT_TASK_NONE(...) task constructor for those tasks
which do not initially exist
 
* tests/PKGconf.mak:
Add new tests test8.c, testcx[678].cxx to the build.
 
* tests/test6.c:
Tidy comments, untabify.
* tests/test7.c:
Tidy comments, untabify, test creation with NADR record pointer.
No impact from the new cre/del_tsk() functionality on test7, since
a task may only be deleted when it is dormant, so deletion is NOT
another way out of a waiting state.
* tests/test8.c:
New test, tests cre_tsk() and del_tsk() and exd_tsk() ie. the
creation and deletion of tasks.
 
* tests/testcx6.cxx:
* tests/testcx7.cxx:
* tests/testcx8.cxx:
New tests, C++ versions of tests 6, 7, and 8.
 
1998-10-09 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/test7.c:
Test interactions with deleting objects (as applicable) and
killing, signalling and the like. Also test killing the task
after other treatments more generically.
 
* tests/test6.c (task1):
Change "N/A:" to "N/A" in the exit message when we didn't actually
do any testing due to create/delete being disabled for all object
types.
 
1998-10-08 Hugo Tyson <hmt@masala.cygnus.co.uk>
 
In general, these changes are to support create/delete of uITRON
objects; this requires that an object can be destroyed whilst
there are threads waiting on it, and that they shall be awoken
with a specific return code E_DLT. The implementation uses an
array of pointers in addition to the array of objects: ptrs[N]
should either be NULL or &objs[N] in this version. That
restriction is not checked, in order that in future, true dynamic
allocation can be used, and ptrs[N] could point anywhere. The
implications of this are mainly in the area of getting the
addresses of objects, via the ptr array or from the object array?
The config of whether there is a ptr array is per object type.
 
* include/pkgconf/uitron.h:
Configury of the existence or not of create/delete for object
type: initially only SEMAS, MBOXES, FLAGS.
Configury of the number of objects created initially, if cre/del
are enabled.
 
* tests/test6.c:
* tests/test7.c:
* tests/PKGconf.mak:
Two new test programs (duh!): test6 tests create and delete of
SEMAS, MBOXES, FLAGS explicitly, for bad params handling, ability
to use after deletion and recreation &c &c. test7 tests the
semantics of sleeping on some synchronization primitive, permed
with suspension, signalling, killing, releasing and so forth.
Both will migrate into C++ versions also in future.
 
* include/uit_func.h:
Enable cre/del_{mbx,flg,sem} prototypes.
 
* include/uit_func.inl:
Implement cre/del_{mbx,flg,sem} depending on configury, and handle
the pointer arrays generally in other client routines.
 
* include/uit_objs.hxx:
Define the pointer arrays for access to created objects.
 
* include/uit_type.h:
Enable definitions of the structures used in create calls.
* src/uit_func.cxx:
Initialization code for the pointer arrays, akin to the task
startup code.
 
* src/uit_objs.cxx:
Instantiate the pointer arrays themselves.
 
 
1998-09-25 Bart Veer <bartv@cygnus.co.uk>
 
* include/pkgconf/uitron.h:
PR 17482: added #ifdef protection. If CYGPKG_UITRON_MEMPOOLFIXED
is not defined then the contained option
CYGNUM_UITRON_MEMPOOLFIXED may not be defined either. Ditto for
CYGNUM_UITRON_MEMPOOLVAR which suffers from the same problem.
And ditto for CYGPKG_UITRON_SEMAS
 
1998-09-20 Mark Galassi <rosalia@cygnus.com>
 
* include/pkgconf/uitron.h: added one or two CDL doc strings.
 
Tue Sep 15 19:12:28 1998 David Moore <dsm@keema.cygnus.co.uk>
 
* include/pkgconf/uitron.h: Cleaned up comments.
 
1998-09-12 Mark Galassi <rosalia@cygnus.com>
small changes to the descriptive information in the uITRON CDL
 
1998-09-12 Mark Galassi <rosalia@cygnus.com>
 
* include/pkgconf/uitron.h: small editing of the description
fields: renamed things like <name> to NAME, so that it does not
confuse SGML when incorporated into the documentation.
Also added various "doc" fields to the CFG_DATA comments.
 
Wed Sep 9 18:36:15 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_func.inl:
* include/uit_objs.hxx:
* src/uit_objs.cxx:
Condition features on CYGPKG_UITRON_SEMAS [for example] as well as
0 < CYG_UITRON_NUM( SEMAS ) so that we get warning free
compilation with no semas enabled. Ditto for flags, mboxes,
mempools fixed and variable, alarms and cyclics.
* include/pkgconf/uitron.h:
Add a couple of requires statements from cyclics and alarms on the
kernel clock.
Also change some grammar after review.
Add an option (actually a pair, makes it better documentation IMO)
to require strict semantics from the kernel setup.
Add an option to control the optional sema initializer; it was
omitted since the editor way of configury used a #if 0.
Fri Sep 4 17:54:29 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/pkgconf/uitron.h:
Remove redundant and now unnecessary defs of CYGPKG_UITRON.
 
Wed Sep 2 19:06:17 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_func.inl:
Memory pools and message boxes and flags
and cnt_sem2-type semaphores now all have absolute timeouts
instead of relative ones in the timely wait functions.
We add in the current time here first.
 
Wed Sep 2 16:45:40 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/pkgconf/uitron.h (CYGDAT_UITRON_TASK_INITIALIZERS):
Use the new kernel thread initializer with priority and thread
name in it.
 
* include/uit_func.inl:
* include/uit_objs.hxx:
* src/uit_func.cxx (cyg_uitron_start):
* src/uit_objs.cxx:
Our tasks are now Cyg_Threads rather than a derived class.
Original priorities of tasks are held in an array. An accessor
macro is used for the off-by-one nature of uitron IDs. The array
of original priorities is set up in cyg_uitron_start(), and
created in uit_objs.cxx.
Wed Sep 2 15:15:26 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/pkgconf/uitron.h:
Comment more strongly in the 'description' that the number of
initializers better match the number of things specified.
 
Tue Sep 1 19:00:02 1998 Hugo Tyson <hmt@masala.cygnus.co.uk>
 
* include/uit_objs.hxx:
Do not include <cyg/kernel/kernel.h>; it is deprecated.
Instead, include only kernel headers that are needed.
 
* include/uit_func.inl (ref_sys):
Use new kernel function Cyg_Interrupt::interrupts_enabled()
instead of a state variable. Tidy up associated code.
Include kernel headers that are needed because they were not
included in uit_objs.hxx for tidiness.
 
* src/uit_func.cxx:
Elide state variable that used to be used for tracking interrupt
enabledness state.
 
* tests/testcx5.cxx (task1):
* tests/test5.c (task1):
Test interrupt enable and disable stuff, and status reporting.
 
Tue Sep 1 15:12:29 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_func.inl (ref_mpf):
Change comment "ECC" to "eCos".
 
1998-08-28 Bart Veer <bartv@cygnus.co.uk>
 
* include/uit_func.inl:
* tests/test1.c, tests/test2.c, tests/test3.c, tests/test4.c,
tests/test5.c, tests/testcxx.cxx, tests/testcx2.cxx,
tests/testcx3.cxx, tests/testcx4.cxx, tests/testcx5.cxx:
 
Updated for new kernel configuration option symbol names
 
 
Fri Aug 28 09:21:55 1998 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* src/uit_func.cxx (cyg_uitron_start):
Remove call to Cyg_Scheduler::start() and adjust comments to
explain where to call it from
 
* tests/test1.c, tests/test2.c, tests/test3.c, tests/test4.c,
tests/test5.c, tests/testcxx.cxx, tests/testcx2.cxx,
tests/testcx3.cxx, tests/testcx4.cxx, tests/testcx5.cxx:
Change the normal entry point at the top to be cyg_package_start()
under the new startup scheme. This overrides the default package
configuration and ensure cyg_uitron_start() gets called.
Change the "default" entry point at the bottom (when the test is
N/A for some reason) to cyg_start() under the new startup scheme.
Wed Aug 26 18:20:47 1998 Hugo Tyson <hmt@masala.cygnus.co.uk>
 
* include/pkgconf/uitron.h:
Initial version of cdl control statements for config options.
All very groovy, and looking good IMO.
A few FIX-MEs remain, no big deal.
 
Mon Aug 24 19:05:52 1998 Hugo Tyson <hmt@masala.cygnus.co.uk>
 
* include/pkgconf/uitron.h:
Change the names of config options to helpful, positive sense, and
tidy some of the names for inclusion in the GUI tool. Clean up
the namespace too.
* include/uit_func.h:
* include/uit_func.inl:
* src/uit_func.cxx:
* src/uit_objs.cxx:
Configure according to new option names and object construction
macros. Simple changes but widespread.
 
* tests/test[12345].c:
* tests/testcx[x2345].cxx:
Configure according to new option names.
Make it main( void ) to avoid a warning.
 
Fri Aug 21 18:45:16 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/testcx4.cxx (task1):
* tests/test4.c (task1):
* include/uit_func.inl (def_alm):
Tidy the alarm and timer funcs in the course of fixing a kernel
bug actually. Test the functionality affected by the kernel
change a bit more.
Thu Aug 20 14:33:36 1998 Hugo Tyson <hmt@masala.cygnus.co.uk>
 
* include/uit_func.inl (ref_alm):
Elide an unused variable following the previous change.
 
Mon Aug 17 15:45:07 1998 Hugo Tyson <hmt@masala.cygnus.co.uk>
 
* include/pkgconf/uitron.h:
Add the config option CYGSEM_UITRON_PARAMS_CHECK_NADR_ONLY.
* tests/testcxx.cxx:
* tests/testcx2.cxx:
* tests/testcx4.cxx:
Avoid testing with NULL as a bad parameter when only NADR is
checked. (NADR does not cast to any-pointer in C++ so we don't
test it in these programs) Check for NADR various places as well
as NULL.
* tests/test1.c (task1):
* tests/test2.c (task1):
* tests/test4.c (task1):
Avoid testing with NULL as a bad parameter when only NADR is
checked. Check for NADR various places as well as NULL, and test
NADR as a bad param as well as NULL.
 
 
Mon Aug 17 14:45:30 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_func.inl:
PR# 16536: Check for dormant tasks various places; E_OBJ
must be returned. All this error checking rather bloats the code,
unfortunately.
* tests/testcxx.cxx:
* tests/test1.c:
Test the new checks above.
 
Fri Aug 14 17:41:35 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
* include/uit_func.inl ([t]wai/pol_flg):
Check for zero in a wait-for-flag operation; such a wait can never
be awakened, and so should return E_PAR.
 
* tests/testcx2.cxx (task1):
* tests/test2.c (task1):
Test the above new checking.
 
Fri Jul 24 17:12:54 1998 Hugo Tyson <hmt@masala.cygnus.co.uk>
 
PR#15865
* include/uit_func.inl: return a bool (strictly 1 or 0) for wtsk
rather than -1 or zero as the spec implies.
ref_flg() ref_sem() only affected.
 
Fri Jul 24 13:26:51 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
PR#16531
* include/uit_func.inl: return E_OBJ when (force)resuming a
non-suspended task.
* tests/test1.c: test for that error code.
* tests/testcxx.cxx: test for that error code.
 
Fri Jul 24 13:02:46 1998 Hugo Tyson <hmt@cygnus.co.uk>
 
* Changelog: Initial ChangeLog entry.
 
 
//===========================================================================
//####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####
//===========================================================================
/v2_0/src/uit_objs.cxx
0,0 → 1,382
//===========================================================================
//
// uit_objs.cxx
//
// uITRON static objects
//
//===========================================================================
//####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-03-13
// Purpose: uITRON static system objects
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#include <pkgconf/uitron.h> // uITRON setup CYGNUM_UITRON_SEMAS
// CYGPKG_UITRON et al
 
#ifdef CYGPKG_UITRON
 
#include <cyg/compat/uitron/uit_objs.hxx>
// declarations of the objects
// we define below, and everything
// we need to specify them.
 
#include <cyg/hal/hal_arch.h> // for CYGNUM_HAL_STACK_SIZE_MINIMUM
 
// ------------------------------------------------------------------------
// Mboxes have no initializer.
#ifdef CYGPKG_UITRON_MBOXES
#if 0 < CYGNUM_UITRON_MBOXES
Cyg_Mbox CYG_UITRON_DECL( MBOXES );
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
Cyg_Mbox *CYG_UITRON_DECL_PTRS( MBOXES );
#endif
#endif
#endif // CYGPKG_UITRON_MBOXES
 
// ------------------------------------------------------------------------
// Flags have no initializer.
#ifdef CYGPKG_UITRON_FLAGS
#if 0 < CYGNUM_UITRON_FLAGS
Cyg_Flag CYG_UITRON_DECL( FLAGS );
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
Cyg_Flag *CYG_UITRON_DECL_PTRS( FLAGS );
#endif
#endif
#endif // CYGPKG_UITRON_FLAGS
 
// ------------------------------------------------------------------------
// Semaphores have an optional initializer.
#ifdef CYGPKG_UITRON_SEMAS
#if (0 < CYGNUM_UITRON_SEMAS) || \
defined( CYGDAT_UITRON_SEMA_INITIALIZERS )
 
#ifndef CYGNUM_UITRON_SEMAS
#error You must define CYGNUM_UITRON_SEMAS
#endif
 
Cyg_Counting_Semaphore2 CYG_UITRON_DECL( SEMAS )
 
#ifdef CYGDAT_UITRON_SEMA_INITIALIZERS
// a Macro to ease the construction:
#define CYG_UIT_SEMA( _count_ ) Cyg_Counting_Semaphore2( (cyg_count32)(_count_) )
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
#define CYG_UIT_SEMA_NOEXS Cyg_Counting_Semaphore2( (cyg_count32) 0 )
#endif
= {
CYGDAT_UITRON_SEMA_INITIALIZERS
}
#undef CYG_UIT_SEMA
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
#undef CYG_UIT_SEMA_NOEXS
#endif
#endif // do we have initializers?
; // the end of the declaration, with or without initializer
 
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
Cyg_Counting_Semaphore2 *CYG_UITRON_DECL_PTRS( SEMAS );
#endif
#endif
#endif // CYGPKG_UITRON_SEMAS
 
// ------------------------------------------------------------------------
// tasks MUST be initialized, you must have some.
#ifndef CYGDAT_UITRON_TASK_EXTERNS
#error You must define CYGDAT_UITRON_TASK_EXTERNS
#endif
#ifndef CYGDAT_UITRON_TASK_INITIALIZERS
#error You must define CYGDAT_UITRON_TASK_INITIALIZERS
#endif
#ifndef CYGNUM_UITRON_TASKS
#error You must define CYGNUM_UITRON_TASKS
#endif
 
// a Macro to ease the construction:
// "name", priority, proc, stackbase, stacksize
#define CYG_UIT_TASK( _name_, _prio_, _func_, _sb_, _ss_ ) \
Cyg_Thread( \
(CYG_ADDRWORD)(_prio_), \
(_func_), \
(CYG_ADDRWORD)0, \
_name_, \
(CYG_ADDRESS)(_sb_), \
(cyg_ucount32)(_ss_) )
 
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
#define CYG_UIT_TASK_NOEXS( _name_, _sb_, _ss_ ) \
Cyg_Thread( \
(CYG_ADDRWORD)(CYG_SCHED_DEFAULT_INFO), \
(cyg_thread_entry *)(0), \
(CYG_ADDRWORD)0, \
_name_, \
(CYG_ADDRESS)(_sb_), \
(cyg_ucount32)(_ss_) )
#endif
 
// FIXME: Xscale tools currently in use have a preprocessor bug causing
// the below #ifs to be misinterpreted. Therefore a *temporary*
// workaround is included to define a MAX macro, and change
// CYGDAT_UITRON_TASK_EXTERNS and CYGDAT_UITRON_TASK_INITIALISERS in
// the CDL to use it.
#ifdef XSCALECPPFIXEDSOMETIME
 
#ifdef CYGNUM_HAL_STACK_SIZE_MINIMUM
# ifdef CYGNUM_UITRON_STACK_SIZE
# if CYGNUM_UITRON_STACK_SIZE < CYGNUM_HAL_STACK_SIZE_MINIMUM
 
// then override the configured stack size
# undef CYGNUM_UITRON_STACK_SIZE
# define CYGNUM_UITRON_STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
 
# endif // CYGNUM_UITRON_STACK_SIZE < CYGNUM_HAL_STACK_SIZE_MINIMUM
# endif // CYGNUM_UITRON_STACK_SIZE
#endif // CYGNUM_HAL_STACK_SIZE_MINIMUM
 
#else
#define MAX(_x_,_y_) ((_x_) > (_y_) ? (_x_) : (_y_))
#endif
 
// declare the symbols used in the initializer
CYGDAT_UITRON_TASK_EXTERNS
 
Cyg_Thread CYG_UITRON_DECL( TASKS ) =
{
CYGDAT_UITRON_TASK_INITIALIZERS
};
 
#undef CYG_UIT_TASK
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
#undef CYG_UIT_TASK_NOEXS
#endif
 
#ifdef CYGIMP_THREAD_PRIORITY
// An ancillary array of priorities, for managing the "original" prio
cyg_priority
cyg_uitron_task_initial_priorities[ CYG_UITRON_NUM( TASKS ) ];
#endif
 
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
Cyg_Thread *CYG_UITRON_DECL_PTRS( TASKS );
#endif
 
// ------------------------------------------------------------------------
// fixed memory pools MUST be initialized, IF you have some.
#ifdef CYGPKG_UITRON_MEMPOOLFIXED
#if (0 < CYGNUM_UITRON_MEMPOOLFIXED) || \
defined (CYGDAT_UITRON_MEMPOOLFIXED_INITIALIZERS) || \
defined (CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS)
 
#ifndef CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS
#error You must define CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS
#endif
#ifndef CYGDAT_UITRON_MEMPOOLFIXED_INITIALIZERS
#error You must define CYGDAT_UITRON_MEMPOOLFIXED_INITIALIZERS
#endif
#ifndef CYGNUM_UITRON_MEMPOOLFIXED
#error You must define CYGNUM_UITRON_MEMPOOLFIXED
#endif
 
// declare the symbols used in the initializer
CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS
 
// a Macro to ease the construction: addr, size, blocksize
#define CYG_UIT_MEMPOOLFIXED( _a_, _s_, _bs_ ) Cyg_Mempool_Fixed( \
(cyg_uint8 *)(_a_), (cyg_int32)(_s_), (CYG_ADDRWORD)(_bs_) )
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
// note that this just picks a suitable size for the initialization, which
// should not be too inefficient
#define CYG_UIT_MEMPOOLFIXED_NOEXS( _a_, _s_ ) Cyg_Mempool_Fixed( \
(cyg_uint8 *)(_a_), (cyg_int32)(_s_), (CYG_ADDRWORD) ((~7)&((_s_)/2)) )
#endif
 
Cyg_Mempool_Fixed CYG_UITRON_DECL( MEMPOOLFIXED ) =
{
CYGDAT_UITRON_MEMPOOLFIXED_INITIALIZERS
};
#undef CYG_UIT_MEMPOOLFIXED
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
#undef CYG_UIT_MEMPOOLFIXED_NOEXS
#endif
 
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
Cyg_Mempool_Fixed *CYG_UITRON_DECL_PTRS( MEMPOOLFIXED );
#endif
#endif // do we have fixed memory pools at all?
#endif // CYGPKG_UITRON_MEMPOOLFIXED
 
// ------------------------------------------------------------------------
// variable memory pools MUST be initialized, IF you have some.
#ifdef CYGPKG_UITRON_MEMPOOLVAR
#if (0 < CYGNUM_UITRON_MEMPOOLVAR) || \
defined (CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS) || \
defined (CYGDAT_UITRON_MEMPOOLVAR_EXTERNS)
 
#ifndef CYGDAT_UITRON_MEMPOOLVAR_EXTERNS
#error You must define CYGDAT_UITRON_MEMPOOLVAR_EXTERNS
#endif
#ifndef CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS
#error You must define CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS
#endif
#ifndef CYGNUM_UITRON_MEMPOOLVAR
#error You must define CYGNUM_UITRON_MEMPOOLVAR
#endif
 
// declare the symbols used in the initializer
CYGDAT_UITRON_MEMPOOLVAR_EXTERNS
 
// a Macro to ease the construction: addr, size
#define CYG_UIT_MEMPOOLVAR( _a_, _s_ ) Cyg_Mempool_Variable( \
(cyg_uint8 *)(_a_),(cyg_int32)(_s_))
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
#define CYG_UIT_MEMPOOLVAR_NOEXS( _a_, _s_ ) Cyg_Mempool_Variable( \
(cyg_uint8 *)(_a_),(cyg_int32)(_s_))
#endif
 
Cyg_Mempool_Variable CYG_UITRON_DECL( MEMPOOLVAR ) =
{
CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS
};
#undef CYG_UIT_MEMPOOLVAR
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
#undef CYG_UIT_MEMPOOLVAR_NOEXS
#endif
 
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
Cyg_Mempool_Variable *CYG_UITRON_DECL_PTRS( MEMPOOLVAR );
#endif
#endif // do we have variable memory pools at all?
#endif // CYGPKG_UITRON_MEMPOOLVAR
 
// ------------------------------------------------------------------------
// Cyclic alarm handlers might be initialized, if you have some.
//
#ifdef CYGPKG_UITRON_CYCLICS
#if (0 < CYGNUM_UITRON_CYCLICS) || \
defined( CYGDAT_UITRON_CYCLIC_EXTERNS ) || \
defined( CYGDAT_UITRON_CYCLIC_INITIALIZERS )
 
#ifndef CYGNUM_UITRON_CYCLICS
#error You must define CYGNUM_UITRON_CYCLICS
#endif
 
#if defined( CYGDAT_UITRON_CYCLIC_INITIALIZERS ) || \
defined( CYGDAT_UITRON_CYCLIC_EXTERNS )
 
#ifndef CYGDAT_UITRON_CYCLIC_INITIALIZERS
#error You must define CYGDAT_UITRON_CYCLIC_INITIALIZERS
#endif
#ifndef CYGDAT_UITRON_CYCLIC_EXTERNS
#error You must define CYGDAT_UITRON_CYCLIC_EXTERNS
#endif
 
// declare the symbols used in the initializer
CYGDAT_UITRON_CYCLIC_EXTERNS
 
#endif // have externs or initializers
 
Cyg_Timer CYG_UITRON_DECL( CYCLICS )
 
#ifdef CYGDAT_UITRON_CYCLIC_INITIALIZERS
 
#error *** CYCLIC INITIALIZERS ARE NOT SUPPORTED IN THIS RELEASE***
 
// a Macro to ease the construction: proc, arg, time
#define CYG_UIT_CYCLIC( ... ) Cyg_Timer()
= {
CYGDAT_UITRON_CYCLIC_INITIALIZERS
}
#undef CYG_UIT_CYCLIC
#endif // do we have initializers?
; // the end of the declaration, with or without initializer
 
#endif // do we have cyclic alarms at all?
#endif // CYGPKG_UITRON_CYCLICS
 
// ------------------------------------------------------------------------
// Oneshot alarm handlers might be initialized, if you have some.
//
#ifdef CYGPKG_UITRON_ALARMS
#if (0 < CYGNUM_UITRON_ALARMS) || \
defined( CYGDAT_UITRON_ALARM_EXTERNS ) || \
defined( CYGDAT_UITRON_ALARM_INITIALIZERS )
 
#ifndef CYGNUM_UITRON_ALARMS
#error You must define CYGNUM_UITRON_ALARMS
#endif
 
#if defined( CYGDAT_UITRON_ALARM_INITIALIZERS ) || \
defined( CYGDAT_UITRON_ALARM_EXTERNS )
 
#ifndef CYGDAT_UITRON_ALARM_INITIALIZERS
#error You must define CYGDAT_UITRON_ALARM_INITIALIZERS
#endif
#ifndef CYGDAT_UITRON_ALARM_EXTERNS
#error You must define CYGDAT_UITRON_ALARM_EXTERNS
#endif
 
// declare the symbols used in the initializer
CYGDAT_UITRON_ALARM_EXTERNS
 
#endif // have externs or initializers
 
Cyg_Timer CYG_UITRON_DECL( ALARMS )
 
#ifdef CYGDAT_UITRON_ALARM_INITIALIZERS
 
#error *** ALARM INITIALIZERS ARE NOT SUPPORTED IN THIS RELEASE***
 
// a Macro to ease the construction: proc, arg, time
#define CYG_UIT_ALARM( ... ) Cyg_Timer()
= {
CYGDAT_UITRON_ALARM_INITIALIZERS
}
#undef CYG_UIT_ALARM
#endif // do we have initializers?
; // the end of the declaration, with or without initializer
 
#endif // do we have oneshot alarms at all?
#endif // CYGPKG_UITRON_ALARMS
 
// ------------------------------------------------------------------------
#endif // CYGPKG_UITRON
 
// EOF uit_objs.cxx
/v2_0/src/uit_ifnc.cxx
0,0 → 1,140
//===========================================================================
//
// uit_ifnc.cxx
//
// uITRON compatibility functions
//
//===========================================================================
//####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-03-13
// Purpose: uITRON compatibility functions for use in ISRs
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#include <pkgconf/uitron.h> // uITRON setup CYGNUM_UITRON_SEMAS
// CYGPKG_UITRON et al
 
#ifdef CYGPKG_UITRON
 
// invoke the inline function definition to create static C linkage
// functions here:
#define CYGIMP_UITRON_INLINE_FUNCS 1
#include <cyg/compat/uitron/uit_func.h>
 
// Now ensure that we create *outline* funcs for the ixxx_yyy() functions
// here, with C names or whatever, as required.
 
#undef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
#undef CYGIMP_UITRON_INLINE_FUNCS
#undef CYG_UIT_FUNC_EXTERN_BEGIN
#undef CYG_UIT_FUNC_EXTERN_END
 
#ifdef CYGIMP_UITRON_CPP_OUTLINE_FUNCS
#define CYG_UIT_FUNC_EXTERN_BEGIN extern "C++" {
#define CYG_UIT_FUNC_EXTERN_END }
#else
#define CYG_UIT_FUNC_EXTERN_BEGIN extern "C" {
#define CYG_UIT_FUNC_EXTERN_END }
#endif
 
// Get extern C prototypes (or whatever uit_func.h above did)
#include <cyg/compat/uitron/uit_ifnc.h>
 
#undef CYG_UIT_FUNC_INLINE
#define CYG_UIT_FUNC_INLINE /* blank */
#define CYGPRI_UITRON_FUNCS_HERE_AND_NOW
#include <cyg/compat/uitron/uit_ifnc.inl>
 
volatile int cyg_uit_dsr_actions_head = 0;
volatile int cyg_uit_dsr_actions_tail = 0;
 
Cyg_Uit_Action::action
cyg_uit_dsr_actions[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
 
ID
cyg_uit_dsr_act_ids[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
 
CYG_ADDRWORD
cyg_uit_dsr_act_a1s[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
 
void
cyg_uitron_dsr( unsigned int vector, unsigned int count, unsigned int data )
{
while ( cyg_uit_dsr_actions_tail != cyg_uit_dsr_actions_head ) {
switch ( cyg_uit_dsr_actions[ cyg_uit_dsr_actions_tail ] ) {
case Cyg_Uit_Action::WUP_TSK:
(void)wup_tsk( cyg_uit_dsr_act_ids[ cyg_uit_dsr_actions_tail ] );
break;
#ifdef CYGPKG_UITRON_SEMAS
#if 0 < CYG_UITRON_NUM( SEMAS )
case Cyg_Uit_Action::SIG_SEM:
(void)sig_sem( cyg_uit_dsr_act_ids[ cyg_uit_dsr_actions_tail ] );
break;
#endif // 0 < CYG_UITRON_NUM( SEMAS )
#endif // CYGPKG_UITRON_SEMAS
#ifdef CYGPKG_UITRON_FLAGS
#if 0 < CYG_UITRON_NUM( FLAGS )
case Cyg_Uit_Action::SET_FLG:
(void)set_flg( cyg_uit_dsr_act_ids[ cyg_uit_dsr_actions_tail ],
(UINT)cyg_uit_dsr_act_a1s[ cyg_uit_dsr_actions_tail ] );
break;
#endif // 0 < CYG_UITRON_NUM( FLAGS )
#endif // CYGPKG_UITRON_FLAGS
#ifdef CYGPKG_UITRON_MBOXES
#if 0 < CYG_UITRON_NUM( MBOXES )
case Cyg_Uit_Action::SND_MSG:
(void)snd_msg( cyg_uit_dsr_act_ids[ cyg_uit_dsr_actions_tail ],
(T_MSG *)cyg_uit_dsr_act_a1s[ cyg_uit_dsr_actions_tail ] );
break;
#endif // 0 < CYG_UITRON_NUM( MBOXES )
#endif // CYGPKG_UITRON_MBOXES
default:
CYG_FAIL( "enum Cyg_Uit_Action out of range!" );
}
cyg_uit_dsr_actions_tail =
CYGNUM_UITRON_ISR_ACTION_QUEUEMASK & (1+cyg_uit_dsr_actions_tail);
}
}
 
#endif // CYGPKG_UITRON
 
// EOF uit_ifnc.cxx
/v2_0/src/uit_func.cxx
0,0 → 1,192
//===========================================================================
//
// uit_func.cxx
//
// uITRON compatibility functions
//
//===========================================================================
//####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-03-13
// Purpose: uITRON compatibility functions
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
 
#include <pkgconf/uitron.h> // uITRON setup CYGNUM_UITRON_SEMAS
// CYGPKG_UITRON et al
 
#ifdef CYGPKG_UITRON
 
// invoke the inline function definition to create static C linkage
// functions here:
#define CYGPRI_UITRON_FUNCS_HERE_AND_NOW
#include <cyg/compat/uitron/uit_func.h>
 
cyg_uint32 cyg_uitron_dis_dsp_old_priority = 0;
 
// ------------------------------------------------------------------------
// STARTUP
// this routine is outside the uITRON specification; call it from
// cyg_start(), cyg_package_start(), cyg_prestart() or cyg_user_start()
// to start the uITRON tasks and scheduler.
 
#if CYGNUM_UITRON_START_TASKS < 0
#error CYGNUM_UITRON_START_TASKS should be >= 0
#endif
 
#if CYGNUM_UITRON_START_TASKS == 0
#define START_TASKS CYGNUM_UITRON_TASKS
#else
#define START_TASKS CYGNUM_UITRON_START_TASKS
#endif
 
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
#if START_TASKS > CYGNUM_UITRON_TASKS_INITIALLY
#undef START_TASKS
#define START_TASKS CYGNUM_UITRON_TASKS_INITIALLY
#endif
#endif
 
#if START_TASKS > CYGNUM_UITRON_TASKS
#undef START_TASKS
#define START_TASKS CYGNUM_UITRON_TASKS
#endif
 
#if START_TASKS <= 0
#error Number of uITRON tasks to start initially must be >= 0
#endif
 
 
#define SET_UP_PTRS( _which_ ) CYG_MACRO_START \
for ( i = 0; \
(i < CYGNUM_UITRON_ ## _which_ ## _INITIALLY) && \
(i < CYGNUM_UITRON_ ## _which_ ) ; \
i++ ) { \
CYG_UITRON_PTRS( _which_ )[ i ] = CYG_UITRON_OBJS( _which_ ) + i; \
} \
if ( (CYGNUM_UITRON_ ## _which_ ## _INITIALLY) \
< (CYGNUM_UITRON_ ## _which_) ) \
for ( /* i as is */; i < CYGNUM_UITRON_ ## _which_ ; i++ ) { \
CYG_UITRON_PTRS( _which_ )[ i ] = NULL; \
} \
CYG_MACRO_END
 
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
#ifdef CYGSEM_UITRON_TIME_IS_MILLISECONDS
Cyg_Clock::converter uit_clock_to_system;
Cyg_Clock::converter uit_clock_from_system;
#endif
#endif
 
void cyg_uitron_start( void )
{
cyg_int32 i;
 
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
#ifdef CYGSEM_UITRON_TIME_IS_MILLISECONDS
// initialize the clock converters
Cyg_Clock::real_time_clock->
get_other_to_clock_converter( 1000000, &uit_clock_to_system );
Cyg_Clock::real_time_clock->
get_clock_to_other_converter( 1000000, &uit_clock_from_system );
#endif
#endif
 
for ( i = 0; i < START_TASKS; i++ ) {
#ifdef CYGIMP_THREAD_PRIORITY
// save the initial priority in our private array
cyg_uitron_task_initial_priorities[ i ] =
cyg_uitron_TASKS[ i ].get_priority();
#endif
// and awaken the task:
cyg_uitron_TASKS[ i ].resume();
}
for ( /* i as is */; i < CYGNUM_UITRON_TASKS; i++ ) {
#ifdef CYGIMP_THREAD_PRIORITY
// save the initial priority in our private array
cyg_uitron_task_initial_priorities[ i ] =
cyg_uitron_TASKS[ i ].get_priority();
#endif
// but ensure the task state is dormant.
cyg_uitron_TASKS[ i ].kill();
}
 
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
SET_UP_PTRS( TASKS );
#endif
#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
SET_UP_PTRS( SEMAS );
#endif
#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
SET_UP_PTRS( MBOXES );
#endif
#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
SET_UP_PTRS( FLAGS );
#endif
#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
SET_UP_PTRS( MEMPOOLFIXED );
#endif
#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
SET_UP_PTRS( MEMPOOLVAR );
#endif
}
 
// These allow programs to link when cyg_uitron_start() is called
// (often because of CYGSEM_START_UITRON_COMPATIBILITY from infra,
// though we define these regardless just in case)
// even when there is no interest in uITRON and so the tasks are
// not externally defined; the reference to cyg_uitron_start()
// ensures the tasks array et al are still included...
extern "C" {
void task1( unsigned int arg ) CYGBLD_ATTRIB_WEAK;
void task2( unsigned int arg ) CYGBLD_ATTRIB_WEAK;
void task3( unsigned int arg ) CYGBLD_ATTRIB_WEAK;
void task4( unsigned int arg ) CYGBLD_ATTRIB_WEAK;
}
 
void task1( unsigned int arg ) {}
void task2( unsigned int arg ) {}
void task3( unsigned int arg ) {}
void task4( unsigned int arg ) {}
 
#endif // CYGPKG_UITRON
 
// EOF uit_func.cxx

powered by: WebSVN 2.1.0

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