Beginning of high priority nested interrupt support for the ARMv7-M family
This commit is contained in:
parent
49f73c04ae
commit
7bcfcb2544
@ -6238,7 +6238,7 @@
|
||||
* Makefile.unix: Now has supports qconfig and gconfig targets.
|
||||
These tools will use the Qt and GTK versions of the kconfig-
|
||||
frontends configuration tools (if you built them) (2013-12-16)
|
||||
* arch/arm/src/armv7-a/arm_head.h: Fixe some errors in the cache
|
||||
* arch/arm/src/armv7-a/arm_head.h: Fix some errors in the cache
|
||||
invalidation logic (only seem to matter for Cortex-A8) (21-3-12-19).
|
||||
* Kconfig and all Make.defs files: Add CONFIG_DEBUG_NOOPT. Now
|
||||
you can indepenently enable/disable debug symbols and optimization
|
||||
@ -6250,4 +6250,7 @@
|
||||
autogenerated Documentation/NuttXConfigVariables.html file.
|
||||
This old configuration variable documentation is now a liability
|
||||
and, hence, was removed (2013-12-20).
|
||||
|
||||
* nuttx/arch/Kconfig, nuttx/arch/arm/Kconfig, nuttx/arch/arm/include/x/chip.h,
|
||||
and nuttx/arch/arm/src/x/x_irq.c where x={kinetis, lm, lpc17xx, lpc43xx,
|
||||
sam34, or stm32}: Beginning of support for nested, high priority
|
||||
interrupts. Lots more still needs to be done (2013-12-21).
|
||||
|
95
arch/Kconfig
95
arch/Kconfig
@ -44,7 +44,7 @@ config ARCH_MIPS
|
||||
config ARCH_RGMP
|
||||
bool "RGMP"
|
||||
---help---
|
||||
RTOS and GPOS on Multi-Processor (RGMP) architecture. See
|
||||
RTOS and GPOS on Multi-Processor (RGMP) architecture. See
|
||||
http://rgmp.sourceforge.net/wiki/index.php/Main_Page.
|
||||
|
||||
config ARCH_SH
|
||||
@ -208,8 +208,11 @@ config ARCH_CALIBRATION
|
||||
watch to measure the actual delay then adjust BOARD_LOOPSPERMSEC until
|
||||
the actual delay is 100 seconds.
|
||||
|
||||
comment "Interrupt options"
|
||||
|
||||
config ARCH_HAVE_INTERRUPTSTACK
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARCH_INTERRUPTSTACK
|
||||
int "Interrupt Stack Size"
|
||||
@ -221,6 +224,96 @@ config ARCH_INTERRUPTSTACK
|
||||
defined to be zero), the user task stacks will be used during interrupt
|
||||
handling.
|
||||
|
||||
config ARCH_HAVE_HIPRI_INTERRUPT
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARCH_HIPRI_INTERRUPT
|
||||
bool "High priority interrupts"
|
||||
default n
|
||||
depends on ARCH_HAVE_HIPRI_INTERRUPT && ARCH_HAVE_IRQPRIO
|
||||
select ARMV7M_USEBASEPRI
|
||||
select ARCH_IRQPRIO
|
||||
---help---
|
||||
NOTE: This description is currently unique to the Cortex-M family
|
||||
which is the only family that currently supports this feature. The
|
||||
general feature is not conceptually unique to the Cortex-M but it
|
||||
is extended to any other family, then this discussion will have to
|
||||
be generalized.
|
||||
|
||||
If ARMV7M_USEBASEPRI is selected, then interrupts will be disabled
|
||||
by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so
|
||||
that most interrupts will not have execution priority. SVCall must
|
||||
have execution priority in all cases.
|
||||
|
||||
In the normal cases, interrupts are not nest-able and all interrupts
|
||||
run at an execution priority between NVIC_SYSH_PRIORITY_MIN and
|
||||
NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for
|
||||
SVCall).
|
||||
|
||||
If, in addition, 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).
|
||||
|
||||
How do you specify a high priority interrupt? You need to do two
|
||||
things:
|
||||
|
||||
1) You need to change the address in the vector table so that
|
||||
the high priority interrupt vectors to your special C
|
||||
interrupt handler. There are two ways to do this:
|
||||
|
||||
a) If you select CONFIG_ARCH_RAMVECTORS, then vectors will
|
||||
be kept in RAM and the system will support the interface:
|
||||
|
||||
int up_ramvec_attach(int irq, up_vector_t vector)
|
||||
|
||||
that can be used to attach your C interrupt handler to the
|
||||
vector at run time.
|
||||
|
||||
b) Alternatively, you could keep your vectors in FLASH but in
|
||||
order to this, you would have to develop your own custom
|
||||
vector table.
|
||||
|
||||
2) Then set the priority of your interrupt to NVIC to
|
||||
NVIC_SYSH_HIGH_PRIORITY using the standard interface:
|
||||
|
||||
int up_prioritize_irq(int irq, int priority)
|
||||
|
||||
config ARCH_INT_DISABLEALL
|
||||
bool "Disable high priority interrupts"
|
||||
default y
|
||||
depends on ARCH_HIPRI_INTERRUPT
|
||||
---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 irqsave() 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 |
|
||||
----------------------------+--------------+--------------+-------------
|
||||
|
||||
comment "Boot options"
|
||||
|
||||
choice
|
||||
|
@ -176,12 +176,14 @@ config ARCH_CORTEXM3
|
||||
default n
|
||||
select ARCH_HAVE_IRQPRIO
|
||||
select ARCH_HAVE_RAMVECTORS
|
||||
select ARCH_HAVE_HIPRI_INTERRUPT
|
||||
|
||||
config ARCH_CORTEXM4
|
||||
bool
|
||||
default n
|
||||
select ARCH_HAVE_IRQPRIO
|
||||
select ARCH_HAVE_RAMVECTORS
|
||||
select ARCH_HAVE_HIPRI_INTERRUPT
|
||||
|
||||
config ARCH_CORTEXA5
|
||||
bool
|
||||
|
@ -832,8 +832,54 @@
|
||||
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
|
||||
#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Steps between supported priority values */
|
||||
|
||||
#define NVIC_SYSH_DISABLE_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
#define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled
|
||||
* by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most
|
||||
* interrupts will not have execution priority. SVCall must have execution
|
||||
* priority in all cases.
|
||||
*
|
||||
* In the normal cases, interrupts are not nest-able and all interrupts run
|
||||
* at an execution priority between NVIC_SYSH_PRIORITY_MIN and
|
||||
* NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall).
|
||||
*
|
||||
* If, in addition, CONFIG_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 irqsave() 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 CONFIG_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 CONFIG_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 |
|
||||
* ----------------------------+--------------+--------------+-------------
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL)
|
||||
# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY
|
||||
# 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_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY
|
||||
# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
|
@ -94,7 +94,7 @@
|
||||
# define LM_NQEI 2 /* Two quadrature encoders */
|
||||
# define LM_NPORTS 7 /* 7 Ports (GPIOA-G), 0-42 GPIOs */
|
||||
# define LM_NCANCONTROLLER 0 /* No CAN controllers */
|
||||
#elif defined(CONFIG_ARCH_CHIP_LM3S9B96)
|
||||
#elif defined(CONFIG_ARCH_CHIP_LM3S9B96)
|
||||
# define LM3S 1 /* LM3S family */
|
||||
# undef LM4F /* Not LM4F family */
|
||||
# define LM_NTIMERS 4 /* Four general purpose timers */
|
||||
@ -153,8 +153,54 @@
|
||||
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
|
||||
#define NVIC_SYSH_PRIORITY_STEP 0x20 /* Three bits of interrupt priority used */
|
||||
|
||||
#define NVIC_SYSH_DISABLE_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
#define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled
|
||||
* by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most
|
||||
* interrupts will not have execution priority. SVCall must have execution
|
||||
* priority in all cases.
|
||||
*
|
||||
* In the normal cases, interrupts are not nest-able and all interrupts run
|
||||
* at an execution priority between NVIC_SYSH_PRIORITY_MIN and
|
||||
* NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall).
|
||||
*
|
||||
* If, in addition, CONFIG_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 irqsave() 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 CONFIG_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 CONFIG_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 |
|
||||
* ----------------------------+--------------+--------------+-------------
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL)
|
||||
# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY
|
||||
# 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_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY
|
||||
# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
|
@ -1,7 +1,7 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/include/lpc17xx/chip.h
|
||||
*
|
||||
* Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
* with LPC178x support from Rommel Marcelo
|
||||
*
|
||||
@ -373,8 +373,54 @@
|
||||
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
|
||||
#define NVIC_SYSH_PRIORITY_STEP 0x08 /* Five bits of interrupt priority used */
|
||||
|
||||
#define NVIC_SYSH_DISABLE_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
#define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled
|
||||
* by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most
|
||||
* interrupts will not have execution priority. SVCall must have execution
|
||||
* priority in all cases.
|
||||
*
|
||||
* In the normal cases, interrupts are not nest-able and all interrupts run
|
||||
* at an execution priority between NVIC_SYSH_PRIORITY_MIN and
|
||||
* NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall).
|
||||
*
|
||||
* If, in addition, CONFIG_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 irqsave() 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 CONFIG_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 CONFIG_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 |
|
||||
* ----------------------------+--------------+--------------+-------------
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL)
|
||||
# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY
|
||||
# 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_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY
|
||||
# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
|
@ -568,8 +568,54 @@
|
||||
#define NVIC_SYSH_PRIORITY_MAX LPC43M4_SYSH_PRIORITY_MAX
|
||||
#define NVIC_SYSH_PRIORITY_STEP LPC43M4_SYSH_PRIORITY_INCR
|
||||
|
||||
#define NVIC_SYSH_DISABLE_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
#define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled
|
||||
* by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most
|
||||
* interrupts will not have execution priority. SVCall must have execution
|
||||
* priority in all cases.
|
||||
*
|
||||
* In the normal cases, interrupts are not nest-able and all interrupts run
|
||||
* at an execution priority between NVIC_SYSH_PRIORITY_MIN and
|
||||
* NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall).
|
||||
*
|
||||
* If, in addition, CONFIG_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 irqsave() 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 CONFIG_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 CONFIG_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 |
|
||||
* ----------------------------+--------------+--------------+-------------
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL)
|
||||
# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY
|
||||
# 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_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY
|
||||
# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
|
@ -806,8 +806,54 @@
|
||||
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
|
||||
#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Four bits of interrupt priority used */
|
||||
|
||||
#define NVIC_SYSH_DISABLE_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
#define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled
|
||||
* by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most
|
||||
* interrupts will not have execution priority. SVCall must have execution
|
||||
* priority in all cases.
|
||||
*
|
||||
* In the normal cases, interrupts are not nest-able and all interrupts run
|
||||
* at an execution priority between NVIC_SYSH_PRIORITY_MIN and
|
||||
* NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall).
|
||||
*
|
||||
* If, in addition, CONFIG_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 irqsave() 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 CONFIG_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 CONFIG_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 |
|
||||
* ----------------------------+--------------+--------------+-------------
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL)
|
||||
# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY
|
||||
# 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_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY
|
||||
# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
|
@ -1,7 +1,7 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/include/stm32/chip.h
|
||||
*
|
||||
* Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -1636,8 +1636,54 @@
|
||||
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
|
||||
#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Four bits of interrupt priority used */
|
||||
|
||||
#define NVIC_SYSH_DISABLE_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
#define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled
|
||||
* by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most
|
||||
* interrupts will not have execution priority. SVCall must have execution
|
||||
* priority in all cases.
|
||||
*
|
||||
* In the normal cases, interrupts are not nest-able and all interrupts run
|
||||
* at an execution priority between NVIC_SYSH_PRIORITY_MIN and
|
||||
* NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall).
|
||||
*
|
||||
* If, in addition, CONFIG_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 irqsave() 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 CONFIG_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 CONFIG_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 |
|
||||
* ----------------------------+--------------+--------------+-------------
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL)
|
||||
# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY
|
||||
# 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_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY
|
||||
# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_STM32_CHIP_H */
|
||||
|
||||
|
@ -96,7 +96,7 @@ void up_initial_state(struct tcb_s *tcb)
|
||||
/* Save the task entry point (stripping off the thumb bit) */
|
||||
|
||||
xcp->regs[REG_PC] = (uint32_t)tcb->start & ~1;
|
||||
|
||||
|
||||
/* Specify thumb mode */
|
||||
|
||||
xcp->regs[REG_XPSR] = ARMV7M_XPSR_T;
|
||||
|
@ -512,14 +512,8 @@ int up_prioritize_irq(int irq, int priority)
|
||||
uint32_t regval;
|
||||
int shift;
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
DEBUGASSERT(irq >= KINETIS_IRQ_MEMFAULT && irq < NR_IRQS &&
|
||||
priority >= NVIC_SYSH_DISABLE_PRIORITY &&
|
||||
priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#else
|
||||
DEBUGASSERT(irq >= KINETIS_IRQ_MEMFAULT && irq < NR_IRQS &&
|
||||
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#endif
|
||||
|
||||
if (irq < KINETIS_IRQ_EXTINT)
|
||||
{
|
||||
|
@ -461,14 +461,8 @@ int up_prioritize_irq(int irq, int priority)
|
||||
uint32_t regval;
|
||||
int shift;
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
DEBUGASSERT(irq >= LM_IRQ_MEMFAULT && irq < NR_IRQS &&
|
||||
priority >= NVIC_SYSH_DISABLE_PRIORITY &&
|
||||
priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#else
|
||||
DEBUGASSERT(irq >= LM_IRQ_MEMFAULT && irq < NR_IRQS &&
|
||||
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#endif
|
||||
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
|
||||
if (irq < LM_IRQ_INTERRUPTS)
|
||||
{
|
||||
|
@ -475,14 +475,8 @@ int up_prioritize_irq(int irq, int priority)
|
||||
uint32_t regval;
|
||||
int shift;
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
DEBUGASSERT(irq >= LPC17_IRQ_MEMFAULT && irq < LPC17_IRQ_NIRQS &&
|
||||
priority >= NVIC_SYSH_DISABLE_PRIORITY &&
|
||||
priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#else
|
||||
DEBUGASSERT(irq >= LPC17_IRQ_MEMFAULT && irq < LPC17_IRQ_NIRQS &&
|
||||
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#endif
|
||||
|
||||
if (irq < LPC17_IRQ_EXTINT)
|
||||
{
|
||||
|
@ -513,14 +513,8 @@ int up_prioritize_irq(int irq, int priority)
|
||||
uint32_t regval;
|
||||
int shift;
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
DEBUGASSERT(irq >= LPC43_IRQ_MEMFAULT && irq < NR_IRQS &&
|
||||
priority >= NVIC_SYSH_DISABLE_PRIORITY &&
|
||||
priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#else
|
||||
DEBUGASSERT(irq >= LPC43_IRQ_MEMFAULT && irq < NR_IRQS &&
|
||||
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#endif
|
||||
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
|
||||
if (irq < LPC43_IRQ_EXTINT)
|
||||
{
|
||||
|
@ -535,14 +535,8 @@ int up_prioritize_irq(int irq, int priority)
|
||||
uint32_t regval;
|
||||
int shift;
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
DEBUGASSERT(irq >= SAM_IRQ_MEMFAULT && irq < SAM_IRQ_NIRQS &&
|
||||
priority >= NVIC_SYSH_DISABLE_PRIORITY &&
|
||||
priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#else
|
||||
DEBUGASSERT(irq >= SAM_IRQ_MEMFAULT && irq < SAM_IRQ_NIRQS &&
|
||||
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#endif
|
||||
|
||||
if (irq < SAM_IRQ_EXTINT)
|
||||
{
|
||||
|
@ -486,14 +486,8 @@ int up_prioritize_irq(int irq, int priority)
|
||||
uint32_t regval;
|
||||
int shift;
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < NR_IRQS &&
|
||||
priority >= NVIC_SYSH_DISABLE_PRIORITY &&
|
||||
priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#else
|
||||
DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < NR_IRQS &&
|
||||
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#endif
|
||||
|
||||
if (irq < STM32_IRQ_INTERRUPTS)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user