SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
copyrights:
- Copyright (C) 2021 embedded brains GmbH & Co. KG
enabled-by: true
functional-type: action
links:
- role: interface-function
uid: ../if/entry-remove
post-conditions:
- name: Status
states:
- name: Ok
test-code: |
T_rsc_success( ctx->status );
text: |
The return status of ${../if/entry-remove:/name} shall be
${../../status/if/successful:/name}.
- name: InvAddr
test-code: |
T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
text: |
The return status of ${../if/entry-remove:/name} shall be
${../../status/if/invalid-address:/name}.
- name: IncStat
test-code: |
T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
text: |
The return status of ${../if/entry-remove:/name} shall be
${../../status/if/incorrect-state:/name}.
- name: InvId
test-code: |
T_rsc( ctx->status, RTEMS_INVALID_ID );
text: |
The return status of ${../if/entry-remove:/name} shall be
${../../status/if/invalid-id:/name}.
- name: CalledFromISR
test-code: |
T_rsc( ctx->status, RTEMS_CALLED_FROM_ISR );
text: |
The return status of ${../if/entry-remove:/name} shall be
${../../status/if/called-from-isr:/name}.
- name: Unsat
test-code: |
T_rsc( ctx->status, RTEMS_UNSATISFIED );
text: |
The return status of ${../if/entry-remove:/name} shall be
${../../status/if/unsatisfied:/name}.
test-epilogue: null
test-prologue: null
- name: Disabled
states:
- name: Nop
test-code: |
if ( !ctx->interrupt_occurred ) {
T_eq( ctx->enabled_before, ctx->enabled_after );
}
text: |
The enabled status of the interrupt vector specified by
${../if/entry-remove:/params[0]/name} shall not be modified by the
${../if/entry-remove:/name} call.
- name: 'Yes'
test-code: |
if ( ctx->attributes.can_disable ) {
T_false( ctx->enabled_after );
}
text: |
The interrupt vector specified by ${../if/entry-remove:/params[0]/name}
shall be disabled.
- name: Maybe
test-code: |
/* The comment of pre-condition ``CanDisable`` for the ``Yes`` state. */
if ( ctx->attributes.can_disable ) {
T_false( ctx->enabled_after );
}
text: |
The interrupt vector specified by ${../if/entry-remove:/params[0]/name}
may be disabled.
- name: 'No'
test-code: |
/* The comment of pre-condition ``CanDisable`` for the ``Yes`` state. */
if ( ctx->attributes.can_disable ) {
T_false( ctx->enabled_after );
}
text: |
The interrupt vector specified by ${../if/entry-remove:/params[0]/name}
shall not be disabled.
test-epilogue: null
test-prologue: null
- name: Installed
states:
- name: 'No'
test-code: |
ctx->visited_entries = 0;
sc = rtems_interrupt_handler_iterate(
ctx->test_vector,
VisitInstalledNo,
ctx
);
T_rsc_success( sc );
if ( ctx->other_installed && ctx->third_installed ) {
expected_entries = 2;
} else if ( ctx->other_installed ) {
expected_entries = 1;
} else {
expected_entries = 0;
}
T_eq_u32( ctx->visited_entries, expected_entries );
if ( expected_entries > 0 ) {
ctx->entry_counter = 0;
bsp_interrupt_handler_dispatch_unchecked( ctx->test_vector );
T_eq_u32( ctx->entry_counter, 0 );
} else {
rtems_interrupt_entry *first;
first = bsp_interrupt_dispatch_table[
bsp_interrupt_dispatch_index( ctx->test_vector )
];
T_null( first );
}
text: |
The entry referenced by ${../if/entry-remove:/params[1]/name} shall not
be installed at the interrupt vector specified by
${../if/entry-remove:/params[0]/name}.
- name: Nop
test-code: |
ctx->visited_entries = 0;
sc = rtems_interrupt_handler_iterate(
ctx->test_vector,
VisitInstalledNop,
ctx
);
T_rsc_success( sc );
if ( ctx->installed && ctx->other_installed && ctx->third_installed ) {
expected_entries = 3;
} else if ( ctx->installed && ctx->other_installed ) {
expected_entries = 2;
} else if ( ctx->installed || ctx->other_installed ) {
expected_entries = 1;
} else {
expected_entries = 0;
}
T_eq_u32( ctx->visited_entries, expected_entries );
if ( ctx->installed ) {
ctx->entry_counter = 0;
bsp_interrupt_handler_dispatch_unchecked( ctx->test_vector );
T_eq_u32( ctx->entry_counter, 1 );
}
text: |
The entries installed at the interrupt vector specified by
${../if/entry-remove:/params[0]/name} shall not be modified by the
${../if/entry-remove:/name} call.
test-epilogue: null
test-prologue: |
rtems_status_code sc;
uint32_t expected_entries;
pre-conditions:
- name: Vector
states:
- name: Valid
test-code: |
ctx->vector = ctx->test_vector;
text: |
While the ${../if/entry-remove:/params[0]/name} parameter is
associated with an interrupt vector.
- name: Invalid
test-code: |
ctx->vector = BSP_INTERRUPT_VECTOR_COUNT;
text: |
While the ${../if/entry-remove:/params[0]/name} parameter is
not associated with an interrupt vector.
test-epilogue: null
test-prologue: null
- name: Entry
states:
- name: Obj
test-code: |
ctx->entry = &ctx->entry_obj;
text: |
While the ${../if/entry-remove:/params[1]/name} parameter references an
object of type ${../if/entry:/name}.
- name: 'Null'
test-code: |
ctx->entry = NULL;
text: |
While the ${../if/entry-remove:/params[1]/name} parameter is equal to
${/c/if/null:/name}.
test-epilogue: null
test-prologue: null
- name: Routine
states:
- name: Valid
test-code: |
rtems_interrupt_entry_initialize(
&ctx->entry_obj,
EntryRoutine,
&entry_arg,
info
);
text: |
While the handler routine of the entry referenced by the
${../if/entry-install:/params[1]/name} parameter is valid.
- name: 'Null'
test-code: |
rtems_interrupt_entry_initialize(
&ctx->entry_obj,
NULL,
&entry_arg,
info
);
text: |
While the handler routine of the entry referenced by the
${../if/entry-install:/params[1]/name} parameter is equal to
${/c/if/null:/name}.
test-epilogue: null
test-prologue: null
- name: EntryObj
states:
- name: Installed
test-code: |
ctx->installed = true;
text: |
While the entry referenced by the ${../if/entry-install:/params[1]/name}
parameter is installed at the interrupt vector specified by the
${../if/entry-remove:/params[0]/name} parameter.
- name: Match
test-code: |
ctx->installed = false;
ctx->other_installed = true;
ctx->match = true;
text: |
While the entry referenced by the ${../if/entry-install:/params[1]/name}
parameter not installed at the interrupt vector specified by the
${../if/entry-remove:/params[0]/name} parameter,
while the entry referenced by the ${../if/entry-install:/params[1]/name}
has a handler routine and argument pair which is equal to the handler
routine and argument pair of an entry installed at the interrupt vector
specified by the ${../if/entry-remove:/params[0]/name} parameter.
- name: NoMatch
test-code: |
ctx->installed = false;
ctx->other_installed = true;
ctx->match = false;
text: |
While the entry referenced by the ${../if/entry-install:/params[1]/name}
parameter not installed at the interrupt vector specified by the
${../if/entry-remove:/params[0]/name} parameter,
while the entry referenced by the ${../if/entry-install:/params[1]/name}
has a handler routine and argument pair which is not equal to the handler
routine and argument pairs of all entries installed at the interrupt
vector specified by the ${../if/entry-remove:/params[0]/name} parameter.
test-epilogue: null
test-prologue: null
- name: Init
states:
- name: 'Yes'
test-code: |
ctx->initialized = true;
text: |
While the service is initialized.
- name: 'No'
test-code: |
ctx->initialized = false;
text: |
While the service is not initialized.
test-epilogue: null
test-prologue: null
- name: ISR
states:
- name: 'Yes'
test-code: |
ctx->isr = true;
text: |
While ${../if/entry-remove:/name} is called from within interrupt
context.
- name: 'No'
test-code: |
ctx->isr = false;
text: |
While ${../if/entry-remove:/name} is not called from within interrupt
context.
test-epilogue: null
test-prologue: null
- name: CanDisable
states:
- name: 'Yes'
test-code: |
/*
* This pre-condition depends on the attributes of an interrupt vector.
* For the validation test of ${../if/entry-remove:/name} a testable
* interrupt vector is determined by GetTestableInterruptVector(). The
* implementation of ${../if/entry-remove:/name} uses
* ${../if/vector-disable:/name} which is validated separately in detail.
*/
text: |
While the interrupt vector associated with the
${../if/entry-remove:/params[0]/name} parameter can be disabled.
- name: Maybe
test-code: |
/* See comment for ``Yes`` state */
text: |
While the interrupt vector associated with the
${../if/entry-remove:/params[0]/name} parameter may be disabled.
- name: 'No'
test-code: |
/* See comment for ``Yes`` state */
text: |
While the interrupt vector associated with the
${../if/entry-remove:/params[0]/name} parameter cannot be disabled.
test-epilogue: null
test-prologue: null
- name: First
states:
- name: 'Yes'
test-code: |
ctx->first = true;
text: |
While the entry referenced by the ${../if/entry-remove:/params[1]/name}
parameter is installed as the first entry at the interrupt vector
specified by the ${../if/entry-remove:/params[0]/name} parameter.
- name: 'No'
test-code: |
ctx->first = false;
text: |
While the entry referenced by the ${../if/entry-remove:/params[1]/name}
parameter is installed as not the first entry at the interrupt vector
specified by the ${../if/entry-remove:/params[0]/name} parameter.
test-epilogue: null
test-prologue: null
- name: Last
states:
- name: 'Yes'
test-code: |
ctx->last = true;
text: |
While the entry referenced by the ${../if/entry-remove:/params[1]/name}
parameter is installed as the last entry at the interrupt vector
specified by the ${../if/entry-remove:/params[0]/name} parameter.
- name: 'No'
test-code: |
ctx->last = false;
text: |
While the entry referenced by the ${../if/entry-remove:/params[1]/name}
parameter is installed as not the last entry at the interrupt vector
specified by the ${../if/entry-remove:/params[0]/name} parameter.
test-epilogue: null
test-prologue: null
rationale: null
references: []
requirement-type: functional
skip-reasons: {}
test-action: |
if ( ctx->installed ) {
ctx->entry = &ctx->entry_obj;
if ( ctx->first && ctx->last ) {
Install( ctx, &ctx->entry_obj, EntryRoutine, &entry_arg );
} else if ( ctx->first ) {
ctx->other_installed = true;
Install( ctx, &ctx->entry_obj, EntryRoutine, &entry_arg );
Install( ctx, &ctx->other_entry, OtherRoutine, &other_arg );
} else if ( ctx->last ) {
ctx->other_installed = true;
Install( ctx, &ctx->other_entry, OtherRoutine, &other_arg );
Install( ctx, &ctx->entry_obj, EntryRoutine, &entry_arg );
} else {
ctx->other_installed = true;
ctx->third_installed = true;
Install( ctx, &ctx->other_entry, OtherRoutine, &other_arg );
Install( ctx, &ctx->entry_obj, EntryRoutine, &entry_arg );
Install( ctx, &ctx->third_entry, ThirdRoutine, &third_arg );
}
} else if ( ctx->other_installed ) {
ctx->entry = &ctx->entry_obj;
if ( ctx->match ) {
Install( ctx, &ctx->other_entry, EntryRoutine, &entry_arg );
} else {
Install( ctx, &ctx->other_entry, OtherRoutine, &other_arg );
}
}
if ( ctx->isr ) {
CallWithinISR( Action, ctx );
} else {
Action( ctx );
}
test-brief: null
test-cleanup: |
rtems_status_code sc;
if ( ctx->third_installed ) {
sc = rtems_interrupt_entry_remove( ctx->test_vector, &ctx->third_entry );
T_rsc_success( sc );
}
if ( ctx->other_installed ) {
sc = rtems_interrupt_entry_remove( ctx->test_vector, &ctx->other_entry );
T_rsc_success( sc );
}
if ( ctx->installed && ctx->status != RTEMS_SUCCESSFUL ) {
sc = rtems_interrupt_entry_remove( ctx->test_vector, ctx->entry );
T_rsc_success( sc );
}
test-context:
- brief: |
If this member is true, then the service was initialized during setup.
description: null
member: |
bool initialized_during_setup
- brief: |
If this member is true, then an interrupt occurred.
description: null
member: |
bool interrupt_occurred
- brief: |
This member provides a counter incremented by EntryRoutine().
description: null
member: |
uint32_t entry_counter;
- brief: |
This member provides another ${../if/entry:/name} object.
description: null
member: |
rtems_interrupt_entry other_entry
- brief: |
If this member is true, then another entry was installed.
description: null
member: |
bool other_installed
- brief: |
This member provides a third ${../if/entry:/name} object.
description: null
member: |
rtems_interrupt_entry third_entry
- brief: |
If this member is true, then a third entry was installed.
description: null
member: |
bool third_installed
- brief: |
If this member is true, then the entry is installed.
description: null
member: |
bool installed
- brief: |
If this member is true, then the entry is installed as the first entry.
description: null
member: |
bool first
- brief: |
If this member is true, then the entry is installed as the last entry.
description: null
member: |
bool last
- brief: |
If this member is true, then the entry matches with another installed
entry.
description: null
member: |
bool match
- brief: |
This member provides the vector number of a testable interrupt vector.
description: null
member: |
rtems_vector_number test_vector
- brief: |
If this member is true, then the testable interrupt vector was enabled at
the test case begin.
description: null
member: |
bool test_vector_was_enabled
- brief: |
This member provides the attributes of the testable interrupt vector.
description: null
member: |
rtems_interrupt_attributes attributes
- brief: |
If this member is true, then the service shall be initialized.
description: null
member: |
bool initialized
- brief: |
If this member is true, then ${../if/entry-remove:/name} shall be called
from within interrupt context.
description: null
member: |
bool isr
- brief: |
This member contains the enabled status before the
${../if/entry-remove:/name} call.
description: null
member: |
bool enabled_before
- brief: |
This member contains the enabled status after the
${../if/entry-remove:/name} call.
description: null
member: |
bool enabled_after
- brief: |
This member provides the count of visited entries.
description: null
member: |
uint32_t visited_entries
- brief: |
This member provides the ${../if/entry:/name} object.
description: null
member: |
rtems_interrupt_entry entry_obj
- brief: |
This member specifies if the ${../if/entry-remove:/params[0]/name}
parameter value.
description: null
member: |
rtems_vector_number vector
- brief: |
This member specifies if the ${../if/entry-remove:/params[1]/name}
parameter value.
description: null
member: |
rtems_interrupt_entry *entry;
- brief: |
This member contains the return value of the ${../if/entry-remove:/name}
call.
description: null
member: |
rtems_status_code status
test-context-support: null
test-description: null
test-header: null
test-includes:
- rtems/irq-extension.h
- bsp/irq-generic.h
test-local-includes:
- tx-support.h
test-prepare: |
ctx->interrupt_occurred = false;
ctx->installed = false;
ctx->other_installed = false;
ctx->third_installed = false;
test-setup:
brief: null
code: |
rtems_status_code sc;
ctx->initialized_during_setup = bsp_interrupt_is_initialized();
ctx->test_vector = GetTestableInterruptVector( NULL );
ctx->test_vector_was_enabled = false;
(void) rtems_interrupt_vector_is_enabled(
ctx->test_vector,
&ctx->test_vector_was_enabled
);
sc = rtems_interrupt_get_attributes( ctx->test_vector, &ctx->attributes );
T_rsc_success( sc );
description: null
test-stop: null
test-support: |
typedef ${.:/test-context-type} Context;
static char entry_arg;
static char other_arg;
static char third_arg;
static const char info[] = "Info";
static void Install(
Context *ctx,
rtems_interrupt_entry *entry,
rtems_interrupt_handler routine,
void *arg
)
{
rtems_status_code sc;
rtems_interrupt_entry_initialize(
entry,
routine,
arg,
info
);
sc = rtems_interrupt_entry_install(
ctx->test_vector,
RTEMS_INTERRUPT_SHARED,
entry
);
T_rsc_success( sc );
}
static void OtherRoutine( void *arg )
{
Context *ctx;
rtems_status_code sc;
(void) arg;
ctx = T_fixture_context();
sc = rtems_interrupt_vector_disable( ctx->test_vector );
T_rsc_success( sc );
ctx->interrupt_occurred = true;
}
static void ThirdRoutine( void *arg )
{
T_eq_ptr( arg, &third_arg );
OtherRoutine( NULL );
}
static void EntryRoutine( void *arg )
{
Context *ctx;
ctx = T_fixture_context();
++ctx->entry_counter;
T_eq_ptr( arg, &entry_arg );
OtherRoutine( NULL );
}
static void Action( void *arg )
{
Context *ctx;
rtems_status_code sc;
ctx = arg;
sc = rtems_interrupt_vector_is_enabled(
ctx->test_vector,
&ctx->enabled_before
);
T_rsc_success( sc );
bsp_interrupt_set_handler_unique(
BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
ctx->initialized
);
ctx->status = rtems_interrupt_entry_remove( ctx->vector, ctx->entry );
bsp_interrupt_set_handler_unique(
BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
ctx->initialized_during_setup
);
sc = rtems_interrupt_vector_is_enabled(
ctx->test_vector,
&ctx->enabled_after
);
T_rsc_success( sc );
}
static void VisitInstalledNo(
void *arg,
const char *entry_info,
rtems_option options,
rtems_interrupt_handler handler_routine,
void *handler_arg
)
{
Context *ctx;
uint32_t visited_entries;
ctx = arg;
visited_entries = ctx->visited_entries;
T_eq_u32( options, RTEMS_INTERRUPT_SHARED );
T_eq_ptr( entry_info, info );
if ( visited_entries == 0 ) {
T_eq_ptr( handler_routine, ctx->other_entry.handler );
T_eq_ptr( handler_arg, ctx->other_entry.arg );
} else if ( visited_entries == 1 ) {
T_eq_ptr( handler_routine, ctx->third_entry.handler );
T_eq_ptr( handler_arg, ctx->third_entry.arg );
}
ctx->visited_entries = visited_entries + 1;
}
static void VisitInstalledNop(
void *arg,
const char *entry_info,
rtems_option options,
rtems_interrupt_handler handler_routine,
void *handler_arg
)
{
Context *ctx;
uint32_t visited_entries;
ctx = arg;
visited_entries = ctx->visited_entries;
T_eq_u32( options, RTEMS_INTERRUPT_SHARED );
T_eq_ptr( entry_info, info );
if ( visited_entries == 0 ) {
if ( ctx->installed && ctx->first ) {
T_eq_ptr( handler_routine, ctx->entry_obj.handler );
T_eq_ptr( handler_arg, ctx->entry_obj.arg );
} else {
T_eq_ptr( info, ctx->other_entry.info );
T_eq_ptr( handler_routine, ctx->other_entry.handler );
T_eq_ptr( handler_arg, ctx->other_entry.arg );
}
} else if ( visited_entries == 1 ) {
if (
ctx->installed && ( ( !ctx->first && ctx->last ) ||
( !ctx->first && !ctx->last ) )
) {
T_eq_ptr( handler_routine, ctx->entry_obj.handler );
T_eq_ptr( handler_arg, ctx->entry_obj.arg );
} else {
T_eq_ptr( handler_routine, ctx->other_entry.handler );
T_eq_ptr( handler_arg, ctx->other_entry.arg );
}
} else if ( visited_entries == 2 ) {
if ( ctx->installed && !ctx->first && ctx->last ) {
T_eq_ptr( handler_routine, ctx->entry_obj.handler );
T_eq_ptr( handler_arg, ctx->entry_obj.arg );
} else {
T_eq_ptr( handler_routine, ctx->third_entry.handler );
T_eq_ptr( handler_arg, ctx->third_entry.arg );
}
}
ctx->visited_entries = visited_entries + 1;
}
test-target: testsuites/validation/tc-intr-entry-remove.c
test-teardown:
brief: null
code: |
if ( ctx->test_vector_was_enabled ) {
(void) rtems_interrupt_vector_enable( ctx->test_vector );
}
description: null
text: ${.:text-template}
transition-map:
- enabled-by: true
post-conditions:
Status: Ok
Disabled:
- if:
pre-conditions:
First: 'Yes'
Last: 'Yes'
then-specified-by: CanDisable
- else: Nop
Installed: 'No'
pre-conditions:
Vector:
- Valid
Entry:
- Obj
Routine:
- Valid
EntryObj:
- Installed
Init:
- 'Yes'
ISR:
- 'No'
CanDisable: all
First: all
Last: all
- enabled-by: true
post-conditions:
Status: Unsat
Disabled: Nop
Installed: N/A
pre-conditions:
Vector:
- Valid
Entry:
- Obj
Routine:
- Valid
EntryObj:
- Match
- NoMatch
Init:
- 'Yes'
ISR:
- 'No'
CanDisable: all
First: N/A
Last: N/A
- enabled-by: true
post-conditions:
Status: InvAddr
Disabled: Nop
Installed: N/A
pre-conditions:
Vector:
- Valid
Entry:
- 'Null'
Routine: N/A
EntryObj: N/A
Init: all
ISR: all
CanDisable: all
First: N/A
Last: N/A
- enabled-by: true
post-conditions:
Status: InvAddr
Disabled: N/A
Installed: N/A
pre-conditions:
Vector:
- Invalid
Entry:
- 'Null'
Routine: N/A
EntryObj: N/A
Init: all
ISR: all
CanDisable: N/A
First: N/A
Last: N/A
- enabled-by: true
post-conditions:
Status: IncStat
Disabled: Nop
Installed: N/A
pre-conditions:
Vector:
- Valid
Entry:
- Obj
Routine: all
EntryObj: N/A
Init:
- 'No'
ISR: all
CanDisable: all
First: N/A
Last: N/A
- enabled-by: true
post-conditions:
Status: IncStat
Disabled: N/A
Installed: N/A
pre-conditions:
Vector:
- Invalid
Entry:
- Obj
Routine: all
EntryObj: N/A
Init:
- 'No'
ISR: all
CanDisable: N/A
First: N/A
Last: N/A
- enabled-by: true
post-conditions:
Status: InvAddr
Disabled: Nop
Installed: N/A
pre-conditions:
Vector:
- Valid
Entry:
- Obj
Routine:
- 'Null'
EntryObj: N/A
Init:
- 'Yes'
ISR: all
CanDisable: all
First: N/A
Last: N/A
- enabled-by: true
post-conditions:
Status: InvAddr
Disabled: N/A
Installed: N/A
pre-conditions:
Vector:
- Invalid
Entry:
- Obj
Routine:
- 'Null'
EntryObj: N/A
Init:
- 'Yes'
CanDisable: N/A
ISR: all
First: N/A
Last: N/A
- enabled-by: true
post-conditions:
Status: InvId
Disabled: N/A
Installed: N/A
pre-conditions:
Vector:
- Invalid
Entry:
- Obj
Routine:
- Valid
EntryObj: N/A
Init:
- 'Yes'
ISR: all
CanDisable: N/A
First: N/A
Last: N/A
- enabled-by: true
post-conditions:
Status: CalledFromISR
Disabled: Nop
Installed: Nop
pre-conditions:
Vector:
- Valid
Entry:
- Obj
Routine:
- Valid
EntryObj:
- Installed
Init:
- 'Yes'
ISR:
- 'Yes'
CanDisable: all
First: all
Last: all
- enabled-by: true
post-conditions:
Status: CalledFromISR
Disabled: Nop
Installed: N/A
pre-conditions:
Vector:
- Valid
Entry:
- Obj
Routine:
- Valid
EntryObj:
- Match
- NoMatch
Init:
- 'Yes'
ISR:
- 'Yes'
CanDisable: all
First: N/A
Last: N/A
type: requirement