nanokernel: deprecate dynamic IRQs
We have not found any use-cases for dynamic IRQs where a static IRQ did not also suffice. Deprecate so that we can eventually remove from Zephyr and nontrivially decrease the complexity of the kernel. Change-Id: I509655371773aeaca7d01134dd850eb4cd95f387 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
a83f895dd5
commit
15800ce78a
14 changed files with 26 additions and 112 deletions
|
@ -277,7 +277,7 @@ For example, if 3 bits are implemented, use 1, 2, and 3,
|
||||||
not 0x20h, 0x40h, and 0x60h.
|
not 0x20h, 0x40h, and 0x60h.
|
||||||
|
|
||||||
Interrupt priority is set using the *prio* parameter of
|
Interrupt priority is set using the *prio* parameter of
|
||||||
:c:macro:`IRQ_CONNECT()` or :c:func:`irq_connect_dynamic()`.
|
:c:macro:`IRQ_CONNECT()`.
|
||||||
|
|
||||||
The range of available priorities is different if using Zero Latency Interrupts
|
The range of available priorities is different if using Zero Latency Interrupts
|
||||||
(ZLI) or not.
|
(ZLI) or not.
|
||||||
|
|
|
@ -25,9 +25,6 @@ Each ISR has the following properties:
|
||||||
An :abbr:`IDT (Interrupt Descriptor Table)` is used to associate a given interrupt
|
An :abbr:`IDT (Interrupt Descriptor Table)` is used to associate a given interrupt
|
||||||
source with a given ISR.
|
source with a given ISR.
|
||||||
Only a single ISR can be associated with a specific IRQ at any given time.
|
Only a single ISR can be associated with a specific IRQ at any given time.
|
||||||
An ISR can be incorporated into the IDT when the Zephyr project is built
|
|
||||||
(a "static ISR") or bound to the IDT when the system is up and running
|
|
||||||
(a "dynamic ISR").
|
|
||||||
|
|
||||||
Multiple ISRs can utilize the same function to process interrupts,
|
Multiple ISRs can utilize the same function to process interrupts,
|
||||||
allowing a single function to service a device that generates
|
allowing a single function to service a device that generates
|
||||||
|
@ -66,27 +63,10 @@ response, and which can be done quickly and without blocking.
|
||||||
Installing an ISR
|
Installing an ISR
|
||||||
*****************
|
*****************
|
||||||
|
|
||||||
Use one of the following procedures to install an ISR:
|
It's important to note that IRQ_CONNECT() is not a C function and does
|
||||||
|
some inline assembly magic behind the scenes. All its arguments must be known
|
||||||
* `Installing a Static ISR`_
|
at build time. Drivers that have multiple instances may need to define
|
||||||
* `Installing a Dynamic ISR`_
|
per-instance config functions to configure the interrupt for that instance.
|
||||||
|
|
||||||
Installing a Static ISR
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Use a static ISR to register an interrupt handler when the interrupt
|
|
||||||
parameters are known during the build time and the device is always
|
|
||||||
present in the system.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
There is no API method to uninstall a static ISR; however, it is
|
|
||||||
possible to replace it by installing a dynamic ISR.
|
|
||||||
|
|
||||||
Prerequisites
|
|
||||||
-------------
|
|
||||||
|
|
||||||
* Ensure that the platform used by the project supports static ISRs.
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
@ -112,51 +92,6 @@ Example
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
Installing a Dynamic ISR
|
|
||||||
========================
|
|
||||||
|
|
||||||
Use a dynamic ISR to register an interrupt handler when the interrupt
|
|
||||||
parameters can be found out only at runtime, or when a device is not always
|
|
||||||
present in the system.
|
|
||||||
|
|
||||||
Prerequisites
|
|
||||||
-------------
|
|
||||||
|
|
||||||
* Ensure that the platform used by the project supports dynamic ISRs.
|
|
||||||
|
|
||||||
* (x86 only) Set the :option:`NUM_DYNAMIC_STUBS` configuration option
|
|
||||||
to specify the maximum number of dynamic ISRs allowed in the project.
|
|
||||||
|
|
||||||
* (ARC & ARM only) Enable the :option:`SW_ISR_TABLE_DYNAMIC` so that
|
|
||||||
interrupts may be connected at runtime.
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
|
|
||||||
This is an example of a dynamic interrupt for x86:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
#define MY_DEV_IRQ 24 /* device uses IRQ 24 */
|
|
||||||
#define MY_DEV_PRIO 2 /* device uses interrupt priority 2 */
|
|
||||||
#define MY_ISR_ARG 17 /* argument passed to my_isr() */
|
|
||||||
/* IRQ flags. Interrupt is triggered by low level signal */
|
|
||||||
#define MY_IRQ_FLAGS (IOAPIC_LEVEL | IOAPIC_LOW)
|
|
||||||
|
|
||||||
void my_isr(void *arg)
|
|
||||||
{
|
|
||||||
... /* ISR code */
|
|
||||||
}
|
|
||||||
|
|
||||||
void my_isr_installer(void)
|
|
||||||
{
|
|
||||||
...
|
|
||||||
irq_connect_dynamic(MY_DEV_IRQ, MY_DEV_PRIO, my_isr, MY_ISR_ARG,
|
|
||||||
MY_IRQ_FLAGS);
|
|
||||||
...
|
|
||||||
irq_enable(MY_DEV_IRQ);
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
Working with Interrupts
|
Working with Interrupts
|
||||||
***********************
|
***********************
|
||||||
|
@ -221,22 +156,11 @@ Additional intermediate context switches may be required
|
||||||
to execute any currently executing fiber or any higher-priority tasks
|
to execute any currently executing fiber or any higher-priority tasks
|
||||||
that are scheduled to run.
|
that are scheduled to run.
|
||||||
|
|
||||||
IDT Security
|
|
||||||
============
|
|
||||||
|
|
||||||
Ideally, the IDT memory area should be protected against accidental
|
|
||||||
modification, in the same way that text and read-only data areas
|
|
||||||
are protected. If no dynamic interrupts are in use, i.e.
|
|
||||||
:option:`NUM_DYNAMIC_STUBS` is 0, the IDT will be located in ROM.
|
|
||||||
|
|
||||||
APIs
|
APIs
|
||||||
****
|
****
|
||||||
|
|
||||||
These are the interrupt-related Application Program Interfaces.
|
These are the interrupt-related Application Program Interfaces.
|
||||||
|
|
||||||
:c:func:`irq_connect_dynamic()`
|
|
||||||
Registers a dynamic ISR with the IDT and interrupt controller.
|
|
||||||
|
|
||||||
:c:func:`irq_enable()`
|
:c:func:`irq_enable()`
|
||||||
Enables interrupts from a specific IRQ.
|
Enables interrupts from a specific IRQ.
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
/* Pull in the arch-specific implementations */
|
/* Pull in the arch-specific implementations */
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
|
||||||
|
#ifndef _ASMLANGUAGE
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* Configure a static interrupt.
|
* Configure a static interrupt.
|
||||||
*
|
*
|
||||||
|
@ -52,9 +57,18 @@
|
||||||
*
|
*
|
||||||
* @return The vector assigned to this interrupt
|
* @return The vector assigned to this interrupt
|
||||||
*/
|
*/
|
||||||
#define irq_connect_dynamic(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
|
extern int _arch_irq_connect_dynamic(unsigned int irq, unsigned int priority,
|
||||||
_arch_irq_connect_dynamic(irq_p, priority_p, isr_p, isr_param_p, \
|
void (*routine)(void *parameter), void *parameter,
|
||||||
flags_p)
|
uint32_t flags);
|
||||||
|
|
||||||
|
static inline int __attribute__((deprecated))
|
||||||
|
irq_connect_dynamic(unsigned int irq, unsigned int priority,
|
||||||
|
void (*routine)(void *parameter), void *parameter,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return _arch_irq_connect_dynamic(irq, priority, routine, parameter, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,5 +136,9 @@
|
||||||
*/
|
*/
|
||||||
#define irq_disable(irq) _arch_irq_disable(irq)
|
#define irq_disable(irq) _arch_irq_disable(irq)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ASMLANGUAGE */
|
||||||
#endif /* _IRQ_H_ */
|
#endif /* _IRQ_H_ */
|
||||||
|
|
|
@ -11,4 +11,3 @@ CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
|
||||||
CONFIG_SYS_POWER_MANAGEMENT=y
|
CONFIG_SYS_POWER_MANAGEMENT=y
|
||||||
|
|
||||||
CONFIG_NUM_IRQS=43
|
CONFIG_NUM_IRQS=43
|
||||||
CONFIG_SW_ISR_TABLE_DYNAMIC=y
|
|
||||||
|
|
|
@ -9,4 +9,3 @@ CONFIG_NUM_TIMER_PACKETS=16
|
||||||
CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
|
CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
|
||||||
CONFIG_SYS_POWER_MANAGEMENT=y
|
CONFIG_SYS_POWER_MANAGEMENT=y
|
||||||
CONFIG_NUM_IRQS=43
|
CONFIG_NUM_IRQS=43
|
||||||
CONFIG_SW_ISR_TABLE_DYNAMIC=y
|
|
||||||
|
|
|
@ -117,10 +117,6 @@ void dummyIsr(void *unused)
|
||||||
*/
|
*/
|
||||||
void fgTaskEntry(void)
|
void fgTaskEntry(void)
|
||||||
{
|
{
|
||||||
#ifdef TEST_max
|
|
||||||
/* dynamically link in dummy ISR */
|
|
||||||
irq_connect_dynamic(IRQ_LINE, IRQ_PRIORITY, dummyIsr, (void *) 0, 0);
|
|
||||||
#endif /* TEST_max */
|
|
||||||
#ifdef TEST_reg
|
#ifdef TEST_reg
|
||||||
IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0);
|
IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
CONFIG_SERIAL=n
|
CONFIG_SERIAL=n
|
||||||
CONFIG_IPM=n
|
CONFIG_IPM=n
|
||||||
CONFIG_SW_ISR_TABLE_DYNAMIC=y
|
|
||||||
|
|
|
@ -2,4 +2,3 @@ CONFIG_PRINTK=y
|
||||||
CONFIG_STDOUT_CONSOLE=y
|
CONFIG_STDOUT_CONSOLE=y
|
||||||
CONFIG_NUM_IRQS=43
|
CONFIG_NUM_IRQS=43
|
||||||
CONFIG_FAULT_DUMP=2
|
CONFIG_FAULT_DUMP=2
|
||||||
CONFIG_SW_ISR_TABLE_DYNAMIC=y
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
CONFIG_PRINTK=y
|
CONFIG_PRINTK=y
|
||||||
CONFIG_STDOUT_CONSOLE=y
|
CONFIG_STDOUT_CONSOLE=y
|
||||||
CONFIG_IDT_NUM_VECTORS=256
|
CONFIG_IDT_NUM_VECTORS=256
|
||||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
|
||||||
|
|
|
@ -120,11 +120,6 @@ static void fiberEntry(int message, int arg1)
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
#ifdef TEST_max
|
|
||||||
/* dynamically link in dummy ISR */
|
|
||||||
irq_connect_dynamic(IRQ_LINE, IRQ_PRIORITY, dummyIsr,
|
|
||||||
(void *) 0, 0);
|
|
||||||
#endif /* TEST_max */
|
|
||||||
#ifdef TEST_reg
|
#ifdef TEST_reg
|
||||||
IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0);
|
IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,7 +51,3 @@ config STATIC_ISR
|
||||||
bool "static isr"
|
bool "static isr"
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config DYNAMIC_ISR
|
|
||||||
bool "dynamic isr"
|
|
||||||
default n
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,5 @@ CONFIG_OBJECTS_LIFO=y
|
||||||
CONFIG_OBJECTS_FIFO=y
|
CONFIG_OBJECTS_FIFO=y
|
||||||
CONFIG_OBJECTS_STACK=y
|
CONFIG_OBJECTS_STACK=y
|
||||||
CONFIG_STATIC_ISR=n
|
CONFIG_STATIC_ISR=n
|
||||||
CONFIG_DYNAMIC_ISR=y
|
|
||||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
|
||||||
#CONFIG_TOOLCHAIN_VARIANT="iamcu"
|
#CONFIG_TOOLCHAIN_VARIANT="iamcu"
|
||||||
CONFIG_KERNEL_BIN_NAME="prj10"
|
CONFIG_KERNEL_BIN_NAME="prj10"
|
||||||
|
|
|
@ -14,7 +14,5 @@ CONFIG_OBJECTS_LIFO=y
|
||||||
CONFIG_OBJECTS_FIFO=y
|
CONFIG_OBJECTS_FIFO=y
|
||||||
CONFIG_OBJECTS_STACK=y
|
CONFIG_OBJECTS_STACK=y
|
||||||
CONFIG_STATIC_ISR=n
|
CONFIG_STATIC_ISR=n
|
||||||
CONFIG_DYNAMIC_ISR=y
|
|
||||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
|
||||||
CONFIG_NANO_TIMEOUTS=y
|
CONFIG_NANO_TIMEOUTS=y
|
||||||
CONFIG_KERNEL_BIN_NAME="prj11"
|
CONFIG_KERNEL_BIN_NAME="prj11"
|
||||||
|
|
|
@ -115,12 +115,6 @@ void main(void)
|
||||||
IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0);
|
IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DYNAMIC_ISR
|
|
||||||
/* dynamically link in dummy ISR */
|
|
||||||
irq_connect_dynamic(IRQ_LINE, IRQ_PRIORITY, dummyIsr,
|
|
||||||
(void *) 0, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_OBJECTS_FIBER
|
#ifdef CONFIG_OBJECTS_FIBER
|
||||||
/* start a trivial fiber */
|
/* start a trivial fiber */
|
||||||
task_fiber_start(pStack, FIBER_STACK_SIZE, fiberEntry, (int) MESSAGE,
|
task_fiber_start(pStack, FIBER_STACK_SIZE, fiberEntry, (int) MESSAGE,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue