microkernel: deprecate task IRQs
This mechanism does not add enough value to the kernel to be worth maintaining it. Drivers that need deferred processing of interrupts can simply define their own task and have the interrupt handler release an event that the task waits on. The API is marked as deprecated and it is removed from unit test coverage as well as the documentation. Change-Id: Ib87b91cb41e9b6d7fdf0dc62b240a531b6a8889f Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
38b202e810
commit
a83f895dd5
18 changed files with 7 additions and 1965 deletions
|
@ -16,4 +16,3 @@ nanokernel applications.
|
|||
microkernel_memory
|
||||
microkernel_synchronization
|
||||
microkernel_data
|
||||
microkernel_task_irqs.rst
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
.. _microkernel_task_irqs:
|
||||
|
||||
Interrupt Services
|
||||
##################
|
||||
|
||||
Concepts
|
||||
********
|
||||
|
||||
The microkernel's :dfn:`task IRQ` objects allow interrupts to be serviced
|
||||
by tasks, rather than only by interrupt service routines (ISRs). These allow
|
||||
a microkernel project to have both task-level device drivers and interrupt-level
|
||||
device drivers.
|
||||
|
||||
Any number of task IRQs can be defined in a microkernel system. Each task IRQ
|
||||
has a numeric identifier that uniquely identifies it. These identifiers range
|
||||
from 0 to N-1, where N is the total number of task IRQs in the system.
|
||||
|
||||
A task that wants to service interrupts from a device must first allocate a
|
||||
task IRQ and bind it to the device's interrupt source by specifying the IRQ
|
||||
and interrupt priority level assigned to that device by the system designer.
|
||||
Once a task IRQ has been allocated by a task, it cannot be used by other
|
||||
tasks; this prevents other tasks from interfering with the proper processing
|
||||
of interrupts from that device.
|
||||
|
||||
When an interrupt is generated by the device, the kernel runs an ISR that
|
||||
masks the interrupt and signals the occurrence of the interrupt to the
|
||||
associated task IRQ. The task can then use the task IRQ to recognize that
|
||||
an interrupt has occurred and take action to service the interrupt. At some
|
||||
point during interrupt servicing, the task must instruct the task IRQ to
|
||||
acknowledge the interrupt; this causes the kernel to unmask the interrupt so
|
||||
that future interrupts can be detected.
|
||||
|
||||
Purpose
|
||||
*******
|
||||
|
||||
Use a task IRQ when the work required to process an interrupt cannot be done
|
||||
in an ISR -- either because it takes a long time, or because it requires the
|
||||
processing routine to block.
|
||||
|
||||
Usage
|
||||
*****
|
||||
|
||||
Configuring Task IRQs
|
||||
=====================
|
||||
|
||||
Set the :option:`MAX_NUM_TASK_IRQS` configuration option to specify the number
|
||||
of task IRQs allowed in the project.
|
||||
|
||||
The default value of zero for this option disables task IRQs.
|
||||
|
||||
.. note::
|
||||
Unlike most other microkernel object types, task-level IRQs are defined
|
||||
as a group using a configuration option, rather than as individual
|
||||
public objects in an MDEF or private objects in a source file.
|
||||
|
||||
|
||||
Example: Allocating a Task IRQ
|
||||
==============================
|
||||
|
||||
This code associates a task IRQ with interrupts generated by a device.
|
||||
Interrupts from that device are then enabled so they can be processed
|
||||
using the task IRQ.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define FOO_DEVICE 2 /* device "foo" uses task IRQ object 2 */
|
||||
#define FOO_IRQ 37 /* device "foo" uses IRQ 37 */
|
||||
#define FOO_PRIO 3 /* device "foo" uses interrupt priority 3 */
|
||||
#define FOO_IRQ_FLAGS 0 /* device "foo" IRQ flags. Unused on non-x86 */
|
||||
|
||||
if (task_irq_alloc(FOO_DEVICE, FOO_IRQ, FOO_PRIO, FOO_IRQ_FLAGS) ==
|
||||
INVALID_VECTOR) {
|
||||
/* The task IRQ or the interrupt source is not available */
|
||||
printf("Task IRQ allocation failed!");
|
||||
}
|
||||
|
||||
Example: Servicing Interrupts using a Task IRQ
|
||||
==============================================
|
||||
|
||||
This code allows a task to wait for an interrupt from a device,
|
||||
acknowledge the interrupt, and take the necessary steps to service it.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
task_irq_wait(FOO_DEVICE, TICKS_UNLIMITED);
|
||||
|
||||
/* Device interrupt is now masked */
|
||||
/* Do pre-acknowledgement device processing (if any) */
|
||||
|
||||
task_irq_ack(FOO_DEVICE);
|
||||
|
||||
/* Device interrupt is now unmasked */
|
||||
/* Do post-acknowledgement device processing (if any) */
|
||||
|
||||
The steps required to service a device are device-specific. In some cases
|
||||
all processing may need to be completed before the interrupt is acknowledged,
|
||||
while in other cases no processing at all should be done until the interrupt
|
||||
is acknowledged. Some devices may require processing both before and after
|
||||
acknowledgement.
|
||||
|
||||
|
||||
APIs
|
||||
****
|
||||
|
||||
Task IRQ APIs provided by :file:`microkernel.h`
|
||||
===============================================
|
||||
|
||||
:cpp:func:`task_irq_alloc()`
|
||||
Bind a task IRQ to a device and enable interrupts.
|
||||
|
||||
:cpp:func:`task_irq_ack()`
|
||||
Acknowledge an interrupt and re-enable the interrupt.
|
||||
|
||||
:cpp:func:`task_irq_wait()`
|
||||
Wait for an interrupt to occur within a specified time period.
|
|
@ -53,7 +53,7 @@ extern "C" {
|
|||
* @return assigned interrupt vector if successful, INVALID_VECTOR if not
|
||||
*/
|
||||
extern uint32_t task_irq_alloc(kirq_t irq_obj, uint32_t irq, uint32_t priority,
|
||||
uint32_t flags);
|
||||
uint32_t flags) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -65,7 +65,7 @@ extern uint32_t task_irq_alloc(kirq_t irq_obj, uint32_t irq, uint32_t priority,
|
|||
*
|
||||
* @return N/A
|
||||
*/
|
||||
extern void task_irq_ack(kirq_t irq_obj);
|
||||
extern void task_irq_ack(kirq_t irq_obj) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief Wait for task IRQ to signal an interrupt.
|
||||
|
@ -85,7 +85,8 @@ extern void task_irq_ack(kirq_t irq_obj);
|
|||
* @a timeout = TICKS_NONE.
|
||||
* @sa TICKS_NONE, TICKS_UNLIMITED
|
||||
*/
|
||||
extern int task_irq_wait(kirq_t irq_obj, int32_t timeout);
|
||||
extern int task_irq_wait(kirq_t irq_obj, int32_t timeout)
|
||||
__attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
@ -95,4 +96,4 @@ extern int task_irq_wait(kirq_t irq_obj, int32_t timeout);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* TASK_IRQ_H */
|
||||
#endif /* TASK_IRQ_H */
|
||||
|
|
|
@ -10,7 +10,5 @@ CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
|
|||
|
||||
CONFIG_SYS_POWER_MANAGEMENT=y
|
||||
|
||||
CONFIG_MAX_NUM_TASK_IRQS=2
|
||||
|
||||
CONFIG_NUM_IRQS=43
|
||||
CONFIG_SW_ISR_TABLE_DYNAMIC=y
|
||||
|
|
|
@ -10,9 +10,7 @@ CONFIG_NUM_TIMER_PACKETS=16
|
|||
CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
|
||||
|
||||
CONFIG_SYS_POWER_MANAGEMENT=y
|
||||
|
||||
CONFIG_MAX_NUM_TASK_IRQS=2
|
||||
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_FLOAT=y
|
||||
CONFIG_SSE=y
|
||||
CONFIG_FP_SHARING=y
|
||||
|
|
|
@ -8,6 +8,5 @@ CONFIG_NUM_COMMAND_PACKETS=64
|
|||
CONFIG_NUM_TIMER_PACKETS=16
|
||||
CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
|
||||
CONFIG_SYS_POWER_MANAGEMENT=y
|
||||
CONFIG_MAX_NUM_TASK_IRQS=2
|
||||
CONFIG_NUM_IRQS=43
|
||||
CONFIG_SW_ISR_TABLE_DYNAMIC=y
|
||||
|
|
|
@ -9,5 +9,4 @@ CONFIG_NUM_COMMAND_PACKETS=64
|
|||
CONFIG_NUM_TIMER_PACKETS=16
|
||||
CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
|
||||
CONFIG_SYS_POWER_MANAGEMENT=y
|
||||
CONFIG_MAX_NUM_TASK_IRQS=2
|
||||
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
|
|
|
@ -61,10 +61,6 @@ static pfunc func_array[] = {
|
|||
(pfunc)task_mem_map_alloc,
|
||||
(pfunc)_task_mem_map_free,
|
||||
#ifdef TEST_max
|
||||
/* task device interrupt functions */
|
||||
(pfunc)task_irq_alloc,
|
||||
(pfunc)task_irq_wait,
|
||||
(pfunc)task_irq_ack,
|
||||
/* semaphore functions */
|
||||
(pfunc)isr_sem_give,
|
||||
(pfunc)task_sem_give,
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
MDEF_FILE = prj.mdef
|
||||
KERNEL_TYPE = micro
|
||||
BOARD ?= qemu_x86
|
||||
CONF_FILE = prj_$(ARCH).conf
|
||||
|
||||
include ${ZEPHYR_BASE}/Makefile.inc
|
|
@ -1,58 +0,0 @@
|
|||
Title: Task Level Interrupt Handling
|
||||
|
||||
Description:
|
||||
|
||||
This test exercises the APIs of the task level interrupt handling feature.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Building and Running Project:
|
||||
|
||||
This microkernel project outputs to the console. It can be built and executed
|
||||
on QEMU as follows:
|
||||
|
||||
make qemu
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Troubleshooting:
|
||||
|
||||
Problems caused by out-dated project information can be addressed by
|
||||
issuing one of the following commands then rebuilding the project:
|
||||
|
||||
make clean # discard results of previous builds
|
||||
# but keep existing configuration info
|
||||
or
|
||||
make pristine # discard results of previous builds
|
||||
# and restore pre-defined configuration info
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Sample Output:
|
||||
|
||||
Starting task level interrupt handling tests
|
||||
===================================================================
|
||||
IRQ object 0 using IRQ8 allocated
|
||||
IRQ object 1 using IRQ14 allocated
|
||||
|
||||
IRQ object 2 using IRQ32 allocated
|
||||
IRQ object 3 using IRQ34 allocated
|
||||
|
||||
Generating interrupts for all allocated IRQ objects...
|
||||
Received event for IRQ object 0
|
||||
Received event for IRQ object 1
|
||||
Received event for IRQ object 2
|
||||
Received event for IRQ object 3
|
||||
|
||||
Attempt to allocate an IRQ object that
|
||||
is already allocated by another task...
|
||||
Re-allocation of IRQ object 3 prevented
|
||||
|
||||
Attempt to allocate an IRQ that
|
||||
is already allocated by another task...
|
||||
Re-allocation of IRQ34 prevented
|
||||
|
||||
Attempt to free an IRQ object...
|
||||
IRQ object 2 freed
|
||||
===================================================================
|
||||
PROJECT EXECUTION SUCCESSFUL
|
|
@ -1,14 +0,0 @@
|
|||
% Application : kernel task level device interrupt test
|
||||
|
||||
% TASK NAME PRIO ENTRY STACK GROUPS
|
||||
% ===================================================
|
||||
TASK MONITORTASK 10 MonitorTaskEntry 1024 [EXE]
|
||||
TASK tTaskAMain 11 taskAMain 1024 [EXE]
|
||||
TASK tTaskBMain 12 taskBMain 1024 [EXE]
|
||||
TASK tRegisterWait 13 registerWait 1024 [EXE]
|
||||
|
||||
% SEMA NAME
|
||||
% =================
|
||||
SEMA SEM_TASKDONE
|
||||
SEMA SEM_TASKFAIL
|
||||
SEMA SEM_RDY
|
|
@ -1,6 +0,0 @@
|
|||
# Let stack canaries use non-random number generator.
|
||||
# This option is NOT to be used in production code.
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_SW_ISR_TABLE_DYNAMIC=y
|
||||
CONFIG_MAX_NUM_TASK_IRQS=5
|
||||
CONFIG_NUM_IRQS=4
|
|
@ -1,5 +0,0 @@
|
|||
# Let stack canaries use non-random number generator.
|
||||
# This option is NOT to be used in production code.
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
|
||||
CONFIG_MAX_NUM_TASK_IRQS=5
|
|
@ -1,3 +0,0 @@
|
|||
ccflags-y += -I${srctree}/tests/include
|
||||
|
||||
obj-y = main.o raise_int.o test_device.o
|
|
@ -1,147 +0,0 @@
|
|||
/* main.c - main testing module */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DESCRIPTION
|
||||
* This file contains the main testing module that invokes all the tests.
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <tc_util.h>
|
||||
|
||||
/* One of the task IRQ objects will not be allocated */
|
||||
#define NUM_TASK_IRQS CONFIG_MAX_NUM_TASK_IRQS - 1
|
||||
|
||||
#define NUM_TEST_TASKS 3 /* # of test tasks to monitor */
|
||||
|
||||
/* # ticks to wait for test completion */
|
||||
#define TIMEOUT (60 * sys_clock_ticks_per_sec)
|
||||
|
||||
static ksem_t resultSems[] = { SEM_TASKDONE, SEM_TASKFAIL, ENDLIST };
|
||||
static ksem_t rdySem = SEM_RDY;
|
||||
|
||||
#define NUM_OBJECTS 4
|
||||
extern uint32_t irq_vectors[NUM_OBJECTS];
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Entry point for taskA
|
||||
*
|
||||
* This routine signals "task done" or "task fail", based on the return code of
|
||||
* taskA.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
void taskAMain(void)
|
||||
{
|
||||
extern int taskA(ksem_t semRdy);
|
||||
task_sem_give(resultSems[taskA(rdySem)]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Entry point for taskB
|
||||
*
|
||||
* This routine signals "task done" or "task fail", based on the return code of
|
||||
* taskB.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
void taskBMain(void)
|
||||
{
|
||||
extern int taskB(ksem_t semRdy);
|
||||
task_sem_give(resultSems[taskB(rdySem)]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Wait for devices to be registered and generate SW ints
|
||||
*
|
||||
* This routine waits for the tasks to indicate the IRQ objects are allocated and
|
||||
* then generates SW interrupts for all IRQs. Signals "task done" if all task
|
||||
* indicated the IRQs are allocated or signals "task fail"if not.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
void registerWait(void)
|
||||
{
|
||||
extern void raiseInt(uint8_t id);
|
||||
int tasksDone;
|
||||
int irq_obj;
|
||||
|
||||
/* Wait for the 2 tasks to finish registering their IRQ objects*/
|
||||
|
||||
for (tasksDone = 0; tasksDone < NUM_TEST_TASKS - 1; tasksDone++) {
|
||||
if (task_sem_take(SEM_RDY, TIMEOUT) != RC_OK) {
|
||||
TC_ERROR("Monitor task timed out\n");
|
||||
task_sem_give(resultSems[TC_FAIL]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TC_PRINT("Generating interrupts for all allocated IRQ objects...\n");
|
||||
for (irq_obj = 0; irq_obj < NUM_OBJECTS; irq_obj++) {
|
||||
if (irq_vectors[irq_obj] != INVALID_VECTOR) {
|
||||
raiseInt((uint8_t)irq_vectors[irq_obj]);
|
||||
}
|
||||
}
|
||||
|
||||
task_sem_give(resultSems[TC_PASS]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Entry point for MonitorTask
|
||||
*
|
||||
* This routine keeps tabs on the progress of the tasks doing the actual testing
|
||||
* and generates the final test case summary message.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
void MonitorTaskEntry(void)
|
||||
{
|
||||
ksem_t result;
|
||||
int tasksDone;
|
||||
|
||||
PRINT_DATA("Starting task level interrupt handling tests\n");
|
||||
PRINT_LINE;
|
||||
|
||||
/*
|
||||
* the various test tasks start executing automatically;
|
||||
* wait for all tasks to complete or a failure to occur,
|
||||
* then issue the appropriate test case summary message
|
||||
*/
|
||||
|
||||
for (tasksDone = 0; tasksDone < NUM_TEST_TASKS; tasksDone++) {
|
||||
result = task_sem_group_take(resultSems, TIMEOUT);
|
||||
if (result != resultSems[TC_PASS]) {
|
||||
if (result != resultSems[TC_FAIL]) {
|
||||
TC_ERROR("Monitor task timed out\n");
|
||||
}
|
||||
TC_END_RESULT(TC_FAIL);
|
||||
TC_END_REPORT(TC_FAIL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TC_END_RESULT(TC_PASS);
|
||||
TC_END_REPORT(TC_PASS);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,185 +0,0 @@
|
|||
/* test_device.c - APIs for testing task level interrupts */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This module exercises the task level interrupt handling feature.
|
||||
|
||||
Each function allocates 2 IRQ objects and then tests for an event
|
||||
associated with the IRQ. The taskA() function also attempts to allocate an IRQ
|
||||
that has already been allocated by another task.
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <misc/printk.h>
|
||||
|
||||
#include <tc_util.h>
|
||||
|
||||
#define DEV1_ID 0
|
||||
#define DEV2_ID 1
|
||||
#define DEV3_ID 2
|
||||
#define DEV4_ID 3
|
||||
#define DEV5_ID 4
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
#define DEV1_IRQ 8
|
||||
#define DEV2_IRQ 14
|
||||
#define DEV3_IRQ 32
|
||||
#define DEV4_IRQ 34
|
||||
#elif defined(CONFIG_CPU_CORTEX_M3_M4)
|
||||
#define DEV1_IRQ 0
|
||||
#define DEV2_IRQ 1
|
||||
#define DEV3_IRQ 2
|
||||
#define DEV4_IRQ 3
|
||||
#else
|
||||
#error "Unknown target"
|
||||
#endif
|
||||
|
||||
#define NUM_OBJECTS 4
|
||||
uint32_t irq_vectors[NUM_OBJECTS] = {[0 ... (NUM_OBJECTS - 1)] = INVALID_VECTOR};
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief First of 2 tasks to allocate IRQ objects and check for events
|
||||
*
|
||||
* This task allocates 2 IRQ objects with unique IRQs and then tests for an
|
||||
* interrupt associated with those IRQs. The function then attempts to allocate
|
||||
* a device that has already been allocate from taskB.
|
||||
*
|
||||
* @return TC_PASS, TC_FAIL
|
||||
*/
|
||||
|
||||
int taskA(ksem_t semRdy)
|
||||
{
|
||||
irq_vectors[DEV1_ID] = task_irq_alloc(DEV1_ID, DEV1_IRQ, 1, 0);
|
||||
if (irq_vectors[DEV1_ID] == INVALID_VECTOR) {
|
||||
TC_ERROR("Not able to allocate IRQ object\n");
|
||||
return TC_FAIL;
|
||||
}
|
||||
TC_PRINT("IRQ object %d using IRQ%d allocated\n", DEV1_ID, DEV1_IRQ);
|
||||
|
||||
irq_vectors[DEV2_ID] = task_irq_alloc(DEV2_ID, DEV2_IRQ, 2, 0);
|
||||
if (irq_vectors[DEV2_ID] == INVALID_VECTOR) {
|
||||
TC_ERROR("Not able to allocate IRQ object\n");
|
||||
return TC_FAIL;
|
||||
}
|
||||
TC_PRINT("IRQ object %d using IRQ%d allocated\n\n", DEV2_ID, DEV2_IRQ);
|
||||
|
||||
/* Send semaphore to let loader know IRQ objects have been allocated */
|
||||
|
||||
task_sem_give(semRdy);
|
||||
|
||||
if (task_irq_wait(DEV1_ID, TICKS_UNLIMITED) != RC_OK) {
|
||||
TC_ERROR("Not able to test IRQ object event\n");
|
||||
return TC_FAIL;
|
||||
}
|
||||
TC_PRINT("Received event for IRQ object %d\n", DEV1_ID);
|
||||
task_irq_ack(DEV1_ID);
|
||||
|
||||
if (task_irq_wait(DEV2_ID, TICKS_UNLIMITED) != RC_OK) {
|
||||
TC_ERROR("Not able to test IRQ object event\n");
|
||||
return TC_FAIL;
|
||||
}
|
||||
TC_PRINT("Received event for IRQ object %d\n", DEV2_ID);
|
||||
task_irq_ack(DEV2_ID);
|
||||
|
||||
/* Wait for other task to receive its events */
|
||||
|
||||
(void)task_sem_take(semRdy, TICKS_UNLIMITED);
|
||||
|
||||
TC_PRINT("\nAttempt to allocate an IRQ object that\n");
|
||||
TC_PRINT("is already allocated by another task...\n");
|
||||
if (task_irq_alloc(DEV4_ID, DEV4_IRQ, 1, 0) != INVALID_VECTOR) {
|
||||
TC_ERROR("Error: Was able to allocate\n\n");
|
||||
return TC_FAIL;
|
||||
}
|
||||
TC_PRINT("Re-allocation of IRQ object %d prevented\n", DEV4_ID);
|
||||
|
||||
TC_PRINT("\nAttempt to allocate an IRQ that\n"
|
||||
"is already allocated by another task...\n");
|
||||
if (task_irq_alloc(DEV5_ID, DEV4_IRQ, 1, 0) != INVALID_VECTOR) {
|
||||
TC_ERROR("Error: Was able to allocate\n\n");
|
||||
return TC_FAIL;
|
||||
}
|
||||
TC_PRINT("Re-allocation of IRQ%d prevented\n\n", DEV4_IRQ);
|
||||
|
||||
/* Signal other task that we are done processing */
|
||||
|
||||
task_sem_give(semRdy);
|
||||
|
||||
return TC_PASS;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Second of 2 tasks to allocate IRQ objects and check for events
|
||||
*
|
||||
* This task allocates 2 IRQ objects with unique IRQs and then tests for an
|
||||
* interrupt associated with those IRQs. The function then frees an IRQ object
|
||||
* using task_irq_free().
|
||||
*
|
||||
* @return TC_PASS, TC_FAIL
|
||||
*/
|
||||
|
||||
int taskB(ksem_t semRdy)
|
||||
{
|
||||
irq_vectors[DEV3_ID] = task_irq_alloc(DEV3_ID, DEV3_IRQ, 1, 0);
|
||||
if (irq_vectors[DEV3_ID] == INVALID_VECTOR) {
|
||||
TC_ERROR("Not able to allocate IRQ object\n");
|
||||
return TC_FAIL;
|
||||
}
|
||||
TC_PRINT("IRQ object %d using IRQ%d allocated\n", DEV3_ID, DEV3_IRQ);
|
||||
|
||||
irq_vectors[DEV4_ID] = task_irq_alloc(DEV4_ID, DEV4_IRQ, 1, 0);
|
||||
if (irq_vectors[DEV4_ID] == INVALID_VECTOR) {
|
||||
TC_ERROR("Not able to allocate IRQ object\n");
|
||||
return TC_FAIL;
|
||||
}
|
||||
TC_PRINT("IRQ object %d using IRQ%d allocated\n\n", DEV4_ID, DEV4_IRQ);
|
||||
|
||||
/* Send semaphore to let loader/main know objects have been allocated */
|
||||
|
||||
task_sem_give(semRdy);
|
||||
|
||||
if (task_irq_wait(DEV3_ID, TICKS_UNLIMITED) != RC_OK) {
|
||||
TC_ERROR("Not able to test IRQ object event\n");
|
||||
return TC_FAIL;
|
||||
}
|
||||
TC_PRINT("Received event for IRQ object %d\n", DEV3_ID);
|
||||
task_irq_ack(DEV3_ID);
|
||||
|
||||
if (task_irq_wait(DEV4_ID, TICKS_UNLIMITED) != RC_OK) {
|
||||
TC_ERROR("Not able to test IRQ object event\n");
|
||||
return TC_FAIL;
|
||||
}
|
||||
TC_PRINT("Received event for IRQ object %d\n", DEV4_ID);
|
||||
task_irq_ack(DEV4_ID);
|
||||
|
||||
/* Signal other task that we are done receiving events */
|
||||
|
||||
task_sem_give(semRdy);
|
||||
|
||||
/*
|
||||
* Wait for other task to finish processing. The signal just previously
|
||||
* sent will not be seen here as the other task is a higher priority and
|
||||
* will thus consume the signal first.
|
||||
*/
|
||||
|
||||
(void)task_sem_take(semRdy, TICKS_UNLIMITED);
|
||||
return TC_PASS;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
[test]
|
||||
tags = core
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue