summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-12-21 11:03:38 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-12-21 11:03:38 -0600
commit61d8a57e974548c1c7ef65e9546976053f6c5a9e (patch)
tree3fd21b720c1b5da5cc29775428b86d25ecf68a31
parentedd6a69500e41872b60c0a50697392227b688653 (diff)
downloadnuttx-61d8a57e974548c1c7ef65e9546976053f6c5a9e.tar.gz
nuttx-61d8a57e974548c1c7ef65e9546976053f6c5a9e.tar.bz2
nuttx-61d8a57e974548c1c7ef65e9546976053f6c5a9e.zip
Beginning of high priority nested interrupt support for the ARMv7-M family
-rw-r--r--nuttx/ChangeLog7
-rw-r--r--nuttx/arch/Kconfig95
-rw-r--r--nuttx/arch/arm/Kconfig2
-rw-r--r--nuttx/arch/arm/include/kinetis/chip.h50
-rw-r--r--nuttx/arch/arm/include/lm/chip.h52
-rw-r--r--nuttx/arch/arm/include/lpc17xx/chip.h52
-rw-r--r--nuttx/arch/arm/include/lpc43xx/chip.h50
-rw-r--r--nuttx/arch/arm/include/sam34/chip.h50
-rw-r--r--nuttx/arch/arm/include/stm32/chip.h52
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_initialstate.c2
-rw-r--r--nuttx/arch/arm/src/kinetis/kinetis_irq.c6
-rw-r--r--nuttx/arch/arm/src/lm/lm_irq.c8
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_irq.c6
-rw-r--r--nuttx/arch/arm/src/lpc43xx/lpc43_irq.c8
-rw-r--r--nuttx/arch/arm/src/sam34/sam_irq.c6
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_irq.c6
16 files changed, 395 insertions, 57 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index b0f4e6b08..3320f5250 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -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).
diff --git a/nuttx/arch/Kconfig b/nuttx/arch/Kconfig
index 9d87a1b33..e9fc690ab 100644
--- a/nuttx/arch/Kconfig
+++ b/nuttx/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
diff --git a/nuttx/arch/arm/Kconfig b/nuttx/arch/arm/Kconfig
index 2ec96c66b..0e721697f 100644
--- a/nuttx/arch/arm/Kconfig
+++ b/nuttx/arch/arm/Kconfig
@@ -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
diff --git a/nuttx/arch/arm/include/kinetis/chip.h b/nuttx/arch/arm/include/kinetis/chip.h
index cb686c5d6..bd9909050 100644
--- a/nuttx/arch/arm/include/kinetis/chip.h
+++ b/nuttx/arch/arm/include/kinetis/chip.h
@@ -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
diff --git a/nuttx/arch/arm/include/lm/chip.h b/nuttx/arch/arm/include/lm/chip.h
index 86e21c14d..53ca4d9f0 100644
--- a/nuttx/arch/arm/include/lm/chip.h
+++ b/nuttx/arch/arm/include/lm/chip.h
@@ -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
diff --git a/nuttx/arch/arm/include/lpc17xx/chip.h b/nuttx/arch/arm/include/lpc17xx/chip.h
index 3880268c9..f03785e19 100644
--- a/nuttx/arch/arm/include/lpc17xx/chip.h
+++ b/nuttx/arch/arm/include/lpc17xx/chip.h
@@ -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
diff --git a/nuttx/arch/arm/include/lpc43xx/chip.h b/nuttx/arch/arm/include/lpc43xx/chip.h
index 7ff787e48..6168672ea 100644
--- a/nuttx/arch/arm/include/lpc43xx/chip.h
+++ b/nuttx/arch/arm/include/lpc43xx/chip.h
@@ -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
diff --git a/nuttx/arch/arm/include/sam34/chip.h b/nuttx/arch/arm/include/sam34/chip.h
index 27b4a9231..0e63fd4b5 100644
--- a/nuttx/arch/arm/include/sam34/chip.h
+++ b/nuttx/arch/arm/include/sam34/chip.h
@@ -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
diff --git a/nuttx/arch/arm/include/stm32/chip.h b/nuttx/arch/arm/include/stm32/chip.h
index 240796a03..12fb73f7c 100644
--- a/nuttx/arch/arm/include/stm32/chip.h
+++ b/nuttx/arch/arm/include/stm32/chip.h
@@ -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 */
diff --git a/nuttx/arch/arm/src/armv7-m/up_initialstate.c b/nuttx/arch/arm/src/armv7-m/up_initialstate.c
index c19d32f11..7b6eb3042 100644
--- a/nuttx/arch/arm/src/armv7-m/up_initialstate.c
+++ b/nuttx/arch/arm/src/armv7-m/up_initialstate.c
@@ -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;
diff --git a/nuttx/arch/arm/src/kinetis/kinetis_irq.c b/nuttx/arch/arm/src/kinetis/kinetis_irq.c
index bf4585d9b..5deda2a16 100644
--- a/nuttx/arch/arm/src/kinetis/kinetis_irq.c
+++ b/nuttx/arch/arm/src/kinetis/kinetis_irq.c
@@ -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)
{
diff --git a/nuttx/arch/arm/src/lm/lm_irq.c b/nuttx/arch/arm/src/lm/lm_irq.c
index 8d7997a13..0ef8d2197 100644
--- a/nuttx/arch/arm/src/lm/lm_irq.c
+++ b/nuttx/arch/arm/src/lm/lm_irq.c
@@ -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)
{
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c b/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c
index 8ab0a94d0..840574fab 100644
--- a/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c
@@ -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)
{
diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_irq.c b/nuttx/arch/arm/src/lpc43xx/lpc43_irq.c
index fb316e0d2..779a9c50c 100644
--- a/nuttx/arch/arm/src/lpc43xx/lpc43_irq.c
+++ b/nuttx/arch/arm/src/lpc43xx/lpc43_irq.c
@@ -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)
{
diff --git a/nuttx/arch/arm/src/sam34/sam_irq.c b/nuttx/arch/arm/src/sam34/sam_irq.c
index 3ffe4d3f9..0a868530e 100644
--- a/nuttx/arch/arm/src/sam34/sam_irq.c
+++ b/nuttx/arch/arm/src/sam34/sam_irq.c
@@ -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)
{
diff --git a/nuttx/arch/arm/src/stm32/stm32_irq.c b/nuttx/arch/arm/src/stm32/stm32_irq.c
index ce931afa7..27b0c10fe 100644
--- a/nuttx/arch/arm/src/stm32/stm32_irq.c
+++ b/nuttx/arch/arm/src/stm32/stm32_irq.c
@@ -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)
{