2008-09-12 00:39:12 +00:00
|
|
|
/****************************************************************************
|
|
|
|
* include/nuttx/irq.h
|
2007-02-17 23:21:28 +00:00
|
|
|
*
|
2018-11-24 10:32:45 -06:00
|
|
|
* Copyright (C) 2007-2011, 2013, 2016-2017 Gregory Nutt. All rights
|
|
|
|
* reserved.
|
2012-07-17 03:58:11 +00:00
|
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
2007-02-17 23:21:28 +00:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in
|
|
|
|
* the documentation and/or other materials provided with the
|
|
|
|
* distribution.
|
2008-09-12 00:39:12 +00:00
|
|
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
2007-02-17 23:21:28 +00:00
|
|
|
* used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
2008-09-12 00:39:12 +00:00
|
|
|
****************************************************************************/
|
2007-02-17 23:21:28 +00:00
|
|
|
|
2010-01-23 03:05:05 +00:00
|
|
|
#ifndef __INCLUDE_NUTTX_IRQ_H
|
|
|
|
#define __INCLUDE_NUTTX_IRQ_H
|
2007-02-17 23:21:28 +00:00
|
|
|
|
2008-09-12 00:39:12 +00:00
|
|
|
/****************************************************************************
|
2007-02-17 23:21:28 +00:00
|
|
|
* Included Files
|
2008-09-12 00:39:12 +00:00
|
|
|
****************************************************************************/
|
2007-02-17 23:21:28 +00:00
|
|
|
|
2016-02-13 10:23:16 -06:00
|
|
|
#include <nuttx/config.h>
|
|
|
|
|
2007-02-17 23:21:28 +00:00
|
|
|
#ifndef __ASSEMBLY__
|
2017-03-03 08:55:16 -06:00
|
|
|
# include <stdint.h>
|
2007-02-17 23:21:28 +00:00
|
|
|
# include <assert.h>
|
|
|
|
#endif
|
|
|
|
|
2008-09-12 00:39:12 +00:00
|
|
|
/****************************************************************************
|
2014-09-28 10:15:33 -06:00
|
|
|
* Pre-processor Definitions
|
2008-09-12 00:39:12 +00:00
|
|
|
****************************************************************************/
|
2017-03-03 08:55:16 -06:00
|
|
|
|
2017-03-03 11:48:20 -06:00
|
|
|
#ifndef __ASSEMBLY__
|
2018-08-24 15:10:23 -06:00
|
|
|
/* IRQ detach is a convenience definition, it detach all the handlers
|
|
|
|
* sharing the same IRQ. Detaching an interrupt handler is equivalent to
|
|
|
|
* setting a NULL interrupt handler.
|
2013-03-18 21:10:08 +00:00
|
|
|
*/
|
2007-02-17 23:21:28 +00:00
|
|
|
|
2018-08-24 15:10:23 -06:00
|
|
|
# define irq_detach(irq) irq_attach(irq, NULL, NULL)
|
2017-03-03 11:48:20 -06:00
|
|
|
|
|
|
|
/* Maximum/minimum values of IRQ integer types */
|
|
|
|
|
|
|
|
# if NR_IRQS <= 256
|
|
|
|
# define IRQT_MAX UINT8_MAX
|
|
|
|
# elif NR_IRQS <= 65536
|
|
|
|
# define IRQT_MAX UINT16_MAX
|
|
|
|
# else
|
|
|
|
# define IRQT_MAX UINT32_MAX
|
|
|
|
# endif
|
|
|
|
|
|
|
|
# ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE
|
|
|
|
# if CONFIG_ARCH_NUSER_INTERRUPTS <= 256
|
|
|
|
# define IRQMAPPED_MAX UINT8_MAX
|
|
|
|
# elif CONFIG_ARCH_NUSER_INTERRUPTS <= 65536
|
|
|
|
# define IRQMAPPED_MAX UINT16_MAX
|
|
|
|
# else
|
|
|
|
# define IRQMAPPED_MAX UINT32_MAX
|
2017-03-03 14:39:35 -06:00
|
|
|
# endif
|
2017-03-03 11:48:20 -06:00
|
|
|
# endif
|
|
|
|
|
|
|
|
#endif /* __ASSEMBLY__ */
|
2007-02-17 23:21:28 +00:00
|
|
|
|
2008-09-12 00:39:12 +00:00
|
|
|
/****************************************************************************
|
2007-02-17 23:21:28 +00:00
|
|
|
* Public Types
|
2008-09-12 00:39:12 +00:00
|
|
|
****************************************************************************/
|
2007-02-17 23:21:28 +00:00
|
|
|
|
|
|
|
#ifndef __ASSEMBLY__
|
2017-03-03 10:20:40 -06:00
|
|
|
/* This type is an unsigned integer type large enough to hold the largest
|
|
|
|
* IRQ number.
|
|
|
|
*/
|
2017-03-03 08:55:16 -06:00
|
|
|
|
|
|
|
#if NR_IRQS <= 256
|
|
|
|
typedef uint8_t irq_t;
|
|
|
|
#elif NR_IRQS <= 65536
|
|
|
|
typedef uint16_t irq_t;
|
|
|
|
#else
|
|
|
|
typedef uint32_t irq_t;
|
|
|
|
#endif
|
|
|
|
|
2017-03-03 10:20:40 -06:00
|
|
|
/* This type is an unsigned integer type large enough to hold the largest
|
|
|
|
* mapped vector table index.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE
|
|
|
|
#if CONFIG_ARCH_NUSER_INTERRUPTS <= 256
|
|
|
|
typedef uint8_t irq_mapped_t;
|
|
|
|
#elif CONFIG_ARCH_NUSER_INTERRUPTS <= 65536
|
|
|
|
typedef uint16_t irq_mapped_t;
|
|
|
|
#else
|
|
|
|
typedef uint32_t irq_mapped_t;
|
|
|
|
#endif
|
|
|
|
#endif /* CONFIG_ARCH_MINIMAL_VECTORTABLE */
|
|
|
|
|
2017-03-03 08:55:16 -06:00
|
|
|
/* This struct defines the form of an interrupt service routine */
|
|
|
|
|
2018-01-12 17:41:09 -06:00
|
|
|
typedef CODE int (*xcpt_t)(int irq, FAR void *context, FAR void *arg);
|
|
|
|
#endif /* __ASSEMBLY__ */
|
2007-02-17 23:21:28 +00:00
|
|
|
|
|
|
|
/* Now include architecture-specific types */
|
|
|
|
|
|
|
|
#include <arch/irq.h>
|
|
|
|
|
2008-09-12 00:39:12 +00:00
|
|
|
/****************************************************************************
|
2015-10-02 16:30:35 -06:00
|
|
|
* Public Data
|
2008-09-12 00:39:12 +00:00
|
|
|
****************************************************************************/
|
2007-02-17 23:21:28 +00:00
|
|
|
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#ifdef __cplusplus
|
|
|
|
#define EXTERN extern "C"
|
2013-03-18 21:10:08 +00:00
|
|
|
extern "C"
|
|
|
|
{
|
2007-02-17 23:21:28 +00:00
|
|
|
#else
|
|
|
|
#define EXTERN extern
|
|
|
|
#endif
|
|
|
|
|
2017-03-03 10:20:40 -06:00
|
|
|
#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE
|
|
|
|
/* This is the interrupt vector mapping table. This must be provided by
|
|
|
|
* architecture specific logic if CONFIG_ARCH_MINIMAL_VECTORTABLE is define
|
|
|
|
* in the configuration.
|
|
|
|
*
|
|
|
|
* REVISIT: Currently declared in sched/irq/irq.h. This declaration here
|
|
|
|
* introduces a circular dependency since it depends on NR_IRQS which is
|
|
|
|
* defined in arch/irq.h but arch/irq.h includes nuttx/irq.h and we get
|
|
|
|
* here with NR_IRQS undefined.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* EXTERN const irq_mapped_t g_irqmap[NR_IRQS]; */
|
|
|
|
#endif
|
|
|
|
|
2013-03-18 21:10:08 +00:00
|
|
|
/****************************************************************************
|
|
|
|
* Public Function Prototypes
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: irq_attach
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Configure the IRQ subsystem so that IRQ number 'irq' is dispatched to
|
2017-02-27 06:27:56 -06:00
|
|
|
* 'isr' with argument 'arg'
|
2013-03-18 21:10:08 +00:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2017-02-28 18:20:45 -06:00
|
|
|
int irq_attach(int irq, xcpt_t isr, FAR void *arg);
|
2007-02-17 23:21:28 +00:00
|
|
|
|
2018-08-24 15:10:23 -06:00
|
|
|
#ifdef CONFIG_IRQCHAIN
|
|
|
|
int irqchain_detach(int irq, xcpt_t isr, FAR void *arg);
|
|
|
|
#else
|
|
|
|
# define irqchain_detach(irq, isr, arg) irq_detach(irq)
|
|
|
|
#endif
|
|
|
|
|
2016-02-13 10:23:16 -06:00
|
|
|
/****************************************************************************
|
|
|
|
* Name: enter_critical_section
|
|
|
|
*
|
|
|
|
* Description:
|
2018-11-25 16:04:31 -06:00
|
|
|
* If thread-specific IRQ counter is enabled (for SMP or other
|
|
|
|
* instrumentation):
|
|
|
|
*
|
2016-02-13 10:23:16 -06:00
|
|
|
* Take the CPU IRQ lock and disable interrupts on all CPUs. A thread-
|
|
|
|
* specific counter is increment to indicate that the thread has IRQs
|
|
|
|
* disabled and to support nested calls to enter_critical_section().
|
2016-11-19 11:48:08 -06:00
|
|
|
*
|
|
|
|
* NOTE: Most architectures do not support disabling all CPUs from one
|
|
|
|
* CPU. ARM is an example. In such cases, logic in
|
|
|
|
* enter_critical_section() will still manage entrance into the
|
|
|
|
* protected logic using spinlocks.
|
|
|
|
*
|
2018-11-25 13:52:23 -06:00
|
|
|
* If thread-specific IRQ counter is not enabled:
|
2018-11-25 16:04:31 -06:00
|
|
|
*
|
2016-02-14 16:19:15 -06:00
|
|
|
* This function is equivalent to up_irq_save().
|
2016-02-13 10:23:16 -06:00
|
|
|
*
|
2016-11-19 11:48:08 -06:00
|
|
|
* Input Parameters:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* An opaque, architecture-specific value that represents the state of
|
|
|
|
* the interrupts prior to the call to enter_critical_section();
|
|
|
|
*
|
2016-02-13 10:23:16 -06:00
|
|
|
****************************************************************************/
|
|
|
|
|
2018-11-25 13:52:23 -06:00
|
|
|
#ifdef CONFIG_IRQCOUNT
|
2016-02-13 10:23:16 -06:00
|
|
|
irqstate_t enter_critical_section(void);
|
|
|
|
#else
|
2019-01-27 11:21:03 -06:00
|
|
|
# define enter_critical_section() up_irq_save()
|
2016-02-13 10:23:16 -06:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: leave_critical_section
|
|
|
|
*
|
|
|
|
* Description:
|
2018-11-25 16:04:31 -06:00
|
|
|
* If thread-specific IRQ counter is enabled (for SMP or other
|
|
|
|
* instrumentation):
|
|
|
|
*
|
2016-02-13 10:23:16 -06:00
|
|
|
* Decrement the IRQ lock count and if it decrements to zero then release
|
2016-11-19 11:48:08 -06:00
|
|
|
* the spinlock and restore the interrupt state as it was prior to the
|
|
|
|
* previous call to enter_critical_section().
|
|
|
|
*
|
2018-11-25 13:52:23 -06:00
|
|
|
* If thread-specific IRQ counter is not enabled:
|
2018-11-25 16:04:31 -06:00
|
|
|
*
|
2016-02-14 16:19:15 -06:00
|
|
|
* This function is equivalent to up_irq_restore().
|
2016-02-13 10:23:16 -06:00
|
|
|
*
|
2016-11-19 11:48:08 -06:00
|
|
|
* Input Parameters:
|
|
|
|
* flags - The architecture-specific value that represents the state of
|
|
|
|
* the interrupts prior to the call to enter_critical_section();
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
2016-02-13 10:23:16 -06:00
|
|
|
****************************************************************************/
|
|
|
|
|
2018-11-25 13:52:23 -06:00
|
|
|
#ifdef CONFIG_IRQCOUNT
|
2016-02-13 10:23:16 -06:00
|
|
|
void leave_critical_section(irqstate_t flags);
|
|
|
|
#else
|
2016-02-14 16:19:15 -06:00
|
|
|
# define leave_critical_section(f) up_irq_restore(f)
|
2016-02-13 10:23:16 -06:00
|
|
|
#endif
|
|
|
|
|
2017-12-07 19:39:04 +00:00
|
|
|
/****************************************************************************
|
|
|
|
* Name: spin_lock_irqsave
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* If SMP and SPINLOCK_IRQ are enabled:
|
|
|
|
* Disable local interrupts and take the global spinlock (g_irq_spin)
|
|
|
|
* if the call counter (g_irq_spin_count[cpu]) equals to 0. Then the
|
|
|
|
* counter on the CPU is increment to allow nested call.
|
|
|
|
*
|
|
|
|
* NOTE: This API is very simple to protect data (e.g. H/W register
|
|
|
|
* or internal data structure) in SMP mode. But do not use this API
|
|
|
|
* with kernel APIs which suspend a caller thread. (e.g. nxsem_wait)
|
|
|
|
*
|
|
|
|
* If SMP and SPINLOCK_IRQ are not enabled:
|
|
|
|
* This function is equivalent to enter_critical_section().
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* An opaque, architecture-specific value that represents the state of
|
|
|
|
* the interrupts prior to the call to spin_lock_irqsave();
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2018-02-04 15:41:22 -06:00
|
|
|
#if defined(CONFIG_SMP) && defined(CONFIG_SPINLOCK_IRQ) && \
|
|
|
|
defined(CONFIG_ARCH_GLOBAL_IRQDISABLE)
|
2017-12-07 19:39:04 +00:00
|
|
|
irqstate_t spin_lock_irqsave(void);
|
|
|
|
#else
|
2019-01-27 11:21:03 -06:00
|
|
|
# define spin_lock_irqsave() enter_critical_section()
|
2017-12-07 19:39:04 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: spin_unlock_irqrestore
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* If SMP and SPINLOCK_IRQ are enabled:
|
|
|
|
* Decrement the call counter (g_irq_spin_count[cpu]) and if it
|
|
|
|
* decrements to zero then release the spinlock (g_irq_spin) and
|
|
|
|
* restore the interrupt state as it was prior to the previous call to
|
|
|
|
* spin_lock_irqsave().
|
|
|
|
*
|
|
|
|
* If SMP and SPINLOCK_IRQ are not enabled:
|
|
|
|
* This function is equivalent to leave_critical_section().
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* flags - The architecture-specific value that represents the state of
|
|
|
|
* the interrupts prior to the call to spin_lock_irqsave();
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2018-02-04 15:41:22 -06:00
|
|
|
#if defined(CONFIG_SMP) && defined(CONFIG_SPINLOCK_IRQ) && \
|
|
|
|
defined(CONFIG_ARCH_GLOBAL_IRQDISABLE)
|
2017-12-07 19:39:04 +00:00
|
|
|
void spin_unlock_irqrestore(irqstate_t flags);
|
|
|
|
#else
|
|
|
|
# define spin_unlock_irqrestore(f) leave_critical_section(f)
|
|
|
|
#endif
|
|
|
|
|
2007-02-17 23:21:28 +00:00
|
|
|
#undef EXTERN
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-11-19 13:23:15 -06:00
|
|
|
#endif /* __ASSEMBLY__ */
|
2010-01-23 03:05:05 +00:00
|
|
|
#endif /* __INCLUDE_NUTTX_IRQ_H */
|