This commit removes CONFIG_ARCH_INT_DISABLEALL. In the normal course of things, interrupts must occasionally be disabled using the up_irq_save() inline function to prevent contention in use of resources that may be shared between interrupt level and non-interrupt level logic. Now the question arises, if we are using BASEPRI to disable interrupts and have high priority interrupts enabled (CONFIG_ARCH_HIPRI_INTERRUPT=y), do we disable all interrupts except SVCall (we cannot disable SVCall interrupts). Or do we only disable the "normal" interrupts?
If we are using the BASEPRI register to disable interrupts, then the answer is that we must disable ONLY the "normal interrupts". That is because we cannot disable SVCALL interrupts and we cannot permit SVCAll interrupts running at a higher priority than the high priority interrupts (otherwise, they will introduce jitter in the high priority interrupt response time.) Hence, if you need to disable the high priority interrupt, you will have to disable the interrupt either at the peripheral that generates the interrupt or at the NVIC. Disabling global interrupts via the BASEPRI register cannot effect high priority interrupts.
This commit is contained in:
parent
851285d729
commit
545cfada38
38
arch/Kconfig
38
arch/Kconfig
@ -898,44 +898,6 @@ config ARCH_HIPRI_INTERRUPT
|
|||||||
the nested interrupt, the interrupt stack if no privileged task has
|
the nested interrupt, the interrupt stack if no privileged task has
|
||||||
run
|
run
|
||||||
|
|
||||||
config ARCH_INT_DISABLEALL
|
|
||||||
bool "Disable high priority interrupts"
|
|
||||||
default y
|
|
||||||
depends on ARCH_HIPRI_INTERRUPT && EXPERIMENTAL
|
|
||||||
---help---
|
|
||||||
If ARCH_HIPRI_INTERRUPT is defined, then special high priority
|
|
||||||
interrupts are supported. These are not "nested" in the normal
|
|
||||||
sense of the word. These high priority interrupts can interrupt
|
|
||||||
normal processing but execute outside of OS (although they can "get
|
|
||||||
back into the game" via a PendSV interrupt).
|
|
||||||
|
|
||||||
In the normal course of things, interrupts must occasionally be
|
|
||||||
disabled using the up_irq_save() inline function to prevent contention
|
|
||||||
in use of resources that may be shared between interrupt level and
|
|
||||||
non-interrupt level logic. Now the question arises, if
|
|
||||||
ARCH_HIPRI_INTERRUPT, do we disable all interrupts (except SVCall),
|
|
||||||
or do we only disable the "normal" interrupts. Since the high
|
|
||||||
priority interrupts cannot interact with the OS, you may want to
|
|
||||||
permit the high priority interrupts even if interrupts are
|
|
||||||
disabled. The setting ARCH_INT_DISABLEALL can be used to select
|
|
||||||
either behavior:
|
|
||||||
|
|
||||||
----------------------------+--------------+----------------------------
|
|
||||||
CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES
|
|
||||||
----------------------------+--------------+--------------+-------------
|
|
||||||
CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO
|
|
||||||
----------------------------+--------------+--------------+-------------
|
|
||||||
| | | SVCall
|
|
||||||
| SVCall | SVCall | HIGH
|
|
||||||
Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL
|
|
||||||
| | MAXNORMAL |
|
|
||||||
----------------------------+--------------+--------------+-------------
|
|
||||||
|
|
||||||
NOTE: This does not work now because interrupts get disabled in the
|
|
||||||
standard interrupt handling, prohibiting nesting. Fix is simple: Need
|
|
||||||
to used more priority levels so that we can make a cleaner distinction
|
|
||||||
with the standard interrupt handler.
|
|
||||||
|
|
||||||
comment "Boot options"
|
comment "Boot options"
|
||||||
|
|
||||||
choice
|
choice
|
||||||
|
@ -65,49 +65,33 @@
|
|||||||
* In the normal course of things, interrupts must occasionally be disabled
|
* In the normal course of things, interrupts must occasionally be disabled
|
||||||
* using the up_irq_save() inline function to prevent contention in use of
|
* using the up_irq_save() inline function to prevent contention in use of
|
||||||
* resources that may be shared between interrupt level and non-interrupt
|
* resources that may be shared between interrupt level and non-interrupt
|
||||||
* level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT,
|
* level logic. Now the question arises, if we are using
|
||||||
* do we disable all interrupts (except SVCall), or do we only disable the
|
* CONFIG_ARCH_HIPRI_INTERRUPT=y, do we disable all interrupts except
|
||||||
* "normal" interrupts. Since the high priority interrupts cannot interact
|
* SVCall (we cannot disable SVCall interrupts). Or do we only disable the
|
||||||
* with the OS, you may want to permit the high priority interrupts even if
|
* "normal" interrupts?
|
||||||
* interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be
|
|
||||||
* used to select either behavior:
|
|
||||||
*
|
*
|
||||||
* ----------------------------+--------------+----------------------------
|
* If we are using the BASEPRI register to disable interrupts, then the
|
||||||
* CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES
|
* answer is that we must disable ONLY the "normal interrupts". That
|
||||||
* ----------------------------+--------------+--------------+-------------
|
* is because we cannot disable SVCALL interrupts and we cannot permit
|
||||||
* CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO
|
* SVCAll interrupts running at a higher priority than the high priority
|
||||||
* ----------------------------+--------------+--------------+-------------
|
* interrupts (otherwise, they will introduce jitter in the high priority
|
||||||
* | | | SVCall
|
* interrupt response time.)
|
||||||
* | SVCall | SVCall | HIGH
|
|
||||||
* Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL
|
|
||||||
* | | MAXNORMAL |
|
|
||||||
* ----------------------------+--------------+--------------+-------------
|
|
||||||
*
|
*
|
||||||
|
* Hence, if you need to disable the high priority interrupt, you will have
|
||||||
|
* to disable the interrupt either at the peripheral that generates the
|
||||||
|
* interrupt or at the NVIC. Disabling global interrupts via the BASEPRI
|
||||||
|
* register cannot effect high priority interrupts.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL)
|
/* The high priority interrupt must be highest priority. This prevents
|
||||||
|
* SVCALL handling from adding jitter to high priority interrupt response.
|
||||||
/* In this case, disabling interrupts will disable all interrupts EXCEPT
|
* Disabling interrupts will disable all interrupts EXCEPT SVCALL and the
|
||||||
* SVCALL. NOTE that this will add jitter to the high priority interrupt
|
* high priority interrupts.
|
||||||
* response because it may be deferred by SVCALL interupt handling.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# define NVIC_SYSH_MAXNORMAL_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT
|
#define NVIC_SYSH_MAXNORMAL_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT
|
||||||
# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 1*NVIC_SYSH_PRIORITY_STEP)
|
#define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 2*NVIC_SYSH_PRIORITY_STEP)
|
||||||
# define NVIC_SYSH_DISABLE_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 1*NVIC_SYSH_PRIORITY_STEP)
|
#define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT
|
||||||
# define NVIC_SYSH_SVCALL_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 2*NVIC_SYSH_PRIORITY_STEP)
|
#define NVIC_SYSH_SVCALL_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 1*NVIC_SYSH_PRIORITY_STEP)
|
||||||
#else
|
|
||||||
|
|
||||||
/* In this case, the high priority interrupt must be highest priority. This
|
|
||||||
* prevents SVCALL handling from adding jitter to high priority interrupt
|
|
||||||
* response. Disabling interrupts will disable all interrupts EXCEPT SVCALL
|
|
||||||
* and the high priority interrupts.
|
|
||||||
*/
|
|
||||||
|
|
||||||
# define NVIC_SYSH_MAXNORMAL_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT
|
|
||||||
# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 2*NVIC_SYSH_PRIORITY_STEP)
|
|
||||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT
|
|
||||||
# define NVIC_SYSH_SVCALL_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 1*NVIC_SYSH_PRIORITY_STEP)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ARCH_ARM_INCLUDE_ARM7_M_NVICPRI_H */
|
#endif /* __ARCH_ARM_INCLUDE_ARM7_M_NVICPRI_H */
|
||||||
|
@ -70,35 +70,33 @@
|
|||||||
* In the normal course of things, interrupts must occasionally be disabled
|
* In the normal course of things, interrupts must occasionally be disabled
|
||||||
* using the up_irq_save() inline function to prevent contention in use of
|
* using the up_irq_save() inline function to prevent contention in use of
|
||||||
* resources that may be shared between interrupt level and non-interrupt
|
* resources that may be shared between interrupt level and non-interrupt
|
||||||
* level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT,
|
* level logic. Now the question arises, if we are using
|
||||||
* do we disable all interrupts (except SVCall), or do we only disable the
|
* CONFIG_ARCH_HIPRI_INTERRUPT=y, do we disable all interrupts except
|
||||||
* "normal" interrupts. Since the high priority interrupts cannot interact
|
* SVCall (we cannot disable SVCall interrupts). Or do we only disable the
|
||||||
* with the OS, you may want to permit the high priority interrupts even if
|
* "normal" interrupts?
|
||||||
* interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be
|
|
||||||
* used to select either behavior:
|
|
||||||
*
|
*
|
||||||
* ----------------------------+--------------+----------------------------
|
* If we are using the BASEPRI register to disable interrupts, then the
|
||||||
* CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES
|
* answer is that we must disable ONLY the "normal interrupts". That
|
||||||
* ----------------------------+--------------+--------------+-------------
|
* is because we cannot disable SVCALL interrupts and we cannot permit
|
||||||
* CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO
|
* SVCAll interrupts running at a higher priority than the high priority
|
||||||
* ----------------------------+--------------+--------------+-------------
|
* interrupts (otherwise, they will introduce jitter in the high priority
|
||||||
* | | | SVCall
|
* interrupt response time.)
|
||||||
* | SVCall | SVCall | HIGH
|
*
|
||||||
* Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL
|
* Hence, if you need to disable the high priority interrupt, you will have
|
||||||
* | | MAXNORMAL |
|
* to disable the interrupt either at the peripheral that generates the
|
||||||
* ----------------------------+--------------+--------------+-------------
|
* interrupt or at the NVIC. Disabling global interrupts via the BASEPRI
|
||||||
|
* register cannot effect high priority interrupts.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL)
|
/* The high priority interrupt must be highest priority. This prevents
|
||||||
# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP)
|
* SVCALL handling from adding jitter to high priority interrupt response.
|
||||||
# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
* Disabling interrupts will disable all interrupts EXCEPT SVCALL and the
|
||||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY
|
* high priority interrupts.
|
||||||
# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
*/
|
||||||
#else
|
|
||||||
# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
#define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||||
# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
#define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY
|
#define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY
|
||||||
# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
#define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ARCH_ARM_INCLUDE_CXD56XX_CHIP_H */
|
#endif /* __ARCH_ARM_INCLUDE_CXD56XX_CHIP_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user