Beginning of high priority nested interrupt support for the ARMv7-M family

This commit is contained in:
Gregory Nutt 2013-12-21 11:03:38 -06:00
parent 49f73c04ae
commit 7bcfcb2544
16 changed files with 395 additions and 57 deletions

View File

@ -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).

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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)
{