LCOV - code coverage report
Current view: top level - zephyr - irq.h Coverage Total Hit
Test: new.info Lines: 100.0 % 14 14
Test Date: 2025-09-05 20:47:19

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2015 Intel corporation
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : /**
       8              :  * @file
       9              :  * @brief Public interface for configuring interrupts
      10              :  */
      11              : #ifndef ZEPHYR_INCLUDE_IRQ_H_
      12              : #define ZEPHYR_INCLUDE_IRQ_H_
      13              : 
      14              : /* Pull in the arch-specific implementations */
      15              : #include <zephyr/arch/cpu.h>
      16              : 
      17              : #ifndef _ASMLANGUAGE
      18              : #include <zephyr/toolchain.h>
      19              : #include <zephyr/types.h>
      20              : 
      21              : #ifdef __cplusplus
      22              : extern "C" {
      23              : #endif
      24              : 
      25              : /**
      26              :  * @defgroup isr_apis Interrupt Service Routine APIs
      27              :  * @ingroup kernel_apis
      28              :  * @{
      29              :  */
      30              : 
      31              : /**
      32              :  * @brief Initialize an interrupt handler.
      33              :  *
      34              :  * This routine initializes an interrupt handler for an IRQ. The IRQ must be
      35              :  * subsequently enabled before the interrupt handler begins servicing
      36              :  * interrupts.
      37              :  *
      38              :  * @warning
      39              :  * Although this routine is invoked at run-time, all of its arguments must be
      40              :  * computable by the compiler at build time.
      41              :  *
      42              :  * @param irq_p IRQ line number.
      43              :  * @param priority_p Interrupt priority.
      44              :  * @param isr_p Address of interrupt service routine.
      45              :  * @param isr_param_p Parameter passed to interrupt service routine.
      46              :  * @param flags_p Architecture-specific IRQ configuration flags..
      47              :  */
      48            1 : #define IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
      49              :         ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p)
      50              : 
      51              : /**
      52              :  * Configure a dynamic interrupt.
      53              :  *
      54              :  * Use this instead of IRQ_CONNECT() if arguments cannot be known at build time.
      55              :  *
      56              :  * @param irq IRQ line number
      57              :  * @param priority Interrupt priority
      58              :  * @param routine Interrupt service routine
      59              :  * @param parameter ISR parameter
      60              :  * @param flags Arch-specific IRQ configuration flags
      61              :  *
      62              :  * @return The vector assigned to this interrupt
      63              :  */
      64              : static inline int
      65            1 : irq_connect_dynamic(unsigned int irq, unsigned int priority,
      66              :                     void (*routine)(const void *parameter),
      67              :                     const void *parameter, uint32_t flags)
      68              : {
      69              :         return arch_irq_connect_dynamic(irq, priority, routine, parameter,
      70              :                                         flags);
      71              : }
      72              : 
      73              : /**
      74              :  * Disconnect a dynamic interrupt.
      75              :  *
      76              :  * Use this in conjunction with shared interrupts to remove a routine/parameter
      77              :  * pair from the list of clients using the same interrupt line. If the interrupt
      78              :  * is not being shared then the associated _sw_isr_table entry will be replaced
      79              :  * by (NULL, z_irq_spurious) (default entry).
      80              :  *
      81              :  * @param irq IRQ line number
      82              :  * @param priority Interrupt priority
      83              :  * @param routine Interrupt service routine
      84              :  * @param parameter ISR parameter
      85              :  * @param flags Arch-specific IRQ configuration flags
      86              :  *
      87              :  * @return 0 in case of success, negative value otherwise
      88              :  */
      89              : static inline int
      90            1 : irq_disconnect_dynamic(unsigned int irq, unsigned int priority,
      91              :                        void (*routine)(const void *parameter),
      92              :                        const void *parameter, uint32_t flags)
      93              : {
      94              :         return arch_irq_disconnect_dynamic(irq, priority, routine,
      95              :                                            parameter, flags);
      96              : }
      97              : 
      98              : /**
      99              :  * @brief Initialize a 'direct' interrupt handler.
     100              :  *
     101              :  * This routine initializes an interrupt handler for an IRQ. The IRQ must be
     102              :  * subsequently enabled via irq_enable() before the interrupt handler begins
     103              :  * servicing interrupts.
     104              :  *
     105              :  * These ISRs are designed for performance-critical interrupt handling and do
     106              :  * not go through common interrupt handling code. They must be implemented in
     107              :  * such a way that it is safe to put them directly in the vector table.  For
     108              :  * ISRs written in C, The ISR_DIRECT_DECLARE() macro will do this
     109              :  * automatically. For ISRs written in assembly it is entirely up to the
     110              :  * developer to ensure that the right steps are taken.
     111              :  *
     112              :  * This type of interrupt currently has a few limitations compared to normal
     113              :  * Zephyr interrupts:
     114              :  * - No parameters are passed to the ISR.
     115              :  * - No stack switch is done, the ISR will run on the interrupted context's
     116              :  *   stack, unless the architecture automatically does the stack switch in HW.
     117              :  * - Interrupt locking state is unchanged from how the HW sets it when the ISR
     118              :  *   runs. On arches that enter ISRs with interrupts locked, they will remain
     119              :  *   locked.
     120              :  * - Scheduling decisions are now optional, controlled by the return value of
     121              :  *   ISRs implemented with the ISR_DIRECT_DECLARE() macro
     122              :  * - The call into the OS to exit power management idle state is now optional.
     123              :  *   Normal interrupts always do this before the ISR is run, but when it runs
     124              :  *   is now controlled by the placement of a ISR_DIRECT_PM() macro, or omitted
     125              :  *   entirely.
     126              :  *
     127              :  * @warning
     128              :  * Although this routine is invoked at run-time, all of its arguments must be
     129              :  * computable by the compiler at build time.
     130              :  *
     131              :  * @note
     132              :  * All IRQs configured with the IRQ_ZERO_LATENCY flag must be declared as
     133              :  * direct.
     134              :  *
     135              :  * @param irq_p IRQ line number.
     136              :  * @param priority_p Interrupt priority.
     137              :  * @param isr_p Address of interrupt service routine.
     138              :  * @param flags_p Architecture-specific IRQ configuration flags.
     139              :  */
     140            1 : #define IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \
     141              :         ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p)
     142              : 
     143              : /**
     144              :  * @brief Common tasks before executing the body of an ISR
     145              :  *
     146              :  * This macro must be at the beginning of all direct interrupts and performs
     147              :  * minimal architecture-specific tasks before the ISR itself can run. It takes
     148              :  * no arguments and has no return value.
     149              :  */
     150            1 : #define ISR_DIRECT_HEADER() ARCH_ISR_DIRECT_HEADER()
     151              : 
     152              : /**
     153              :  * @brief Common tasks before exiting the body of an ISR
     154              :  *
     155              :  * This macro must be at the end of all direct interrupts and performs
     156              :  * minimal architecture-specific tasks like EOI. It has no return value.
     157              :  *
     158              :  * In a normal interrupt, a check is done at end of interrupt to invoke
     159              :  * z_swap() logic if the current thread is preemptible and there is another
     160              :  * thread ready to run in the kernel's ready queue cache. This is now optional
     161              :  * and controlled by the check_reschedule argument. If unsure, set to nonzero.
     162              :  * On systems that do stack switching and nested interrupt tracking in software,
     163              :  * z_swap() should only be called if this was a non-nested interrupt.
     164              :  *
     165              :  * @param check_reschedule If nonzero, additionally invoke scheduling logic
     166              :  */
     167            1 : #define ISR_DIRECT_FOOTER(check_reschedule) \
     168              :         ARCH_ISR_DIRECT_FOOTER(check_reschedule)
     169              : 
     170              : /**
     171              :  * @brief Perform power management idle exit logic
     172              :  *
     173              :  * This macro may optionally be invoked somewhere in between IRQ_DIRECT_HEADER()
     174              :  * and IRQ_DIRECT_FOOTER() invocations. It performs tasks necessary to
     175              :  * exit power management idle state. It takes no parameters and returns no
     176              :  * arguments. It may be omitted, but be careful!
     177              :  *
     178              :  * @warning
     179              :  * This macro must not be used at all with IRQs configured with the
     180              :  * IRQ_ZERO_LATENCY flag.
     181              :  */
     182            1 : #define ISR_DIRECT_PM() ARCH_ISR_DIRECT_PM()
     183              : 
     184              : /**
     185              :  * @brief Helper macro to declare a direct interrupt service routine.
     186              :  *
     187              :  * This will declare the function in a proper way and automatically include
     188              :  * the ISR_DIRECT_FOOTER() and ISR_DIRECT_HEADER() macros. The function should
     189              :  * return nonzero status if a scheduling decision should potentially be made.
     190              :  * See ISR_DIRECT_FOOTER() for more details on the scheduling decision.
     191              :  *
     192              :  * For architectures that support 'regular' and 'fast' interrupt types, where
     193              :  * these interrupt types require different assembly language handling of
     194              :  * registers by the ISR, this will always generate code for the 'fast'
     195              :  * interrupt type.
     196              :  *
     197              :  * @warning
     198              :  * Any ISRs that serve IRQs configured with the IRQ_ZERO_LATENCY flag must
     199              :  * always return 0 in this macro.
     200              :  *
     201              :  * Example usage:
     202              :  *
     203              :  *     ISR_DIRECT_DECLARE(my_isr)
     204              :  *     {
     205              :  *             bool done = do_stuff();
     206              :  *             ISR_DIRECT_PM(); // done after do_stuff() due to latency concerns
     207              :  *             if (!done) {
     208              :  *                 return 0; // don't bother checking if we have to z_swap()
     209              :  *             }
     210              :  *
     211              :  *             k_sem_give(some_sem);
     212              :  *             return 1;
     213              :  *      }
     214              :  *
     215              :  * @param name symbol name of the ISR
     216              :  */
     217            1 : #define ISR_DIRECT_DECLARE(name) ARCH_ISR_DIRECT_DECLARE(name)
     218              : 
     219              : /**
     220              :  * @brief Lock interrupts.
     221              :  * @def irq_lock()
     222              :  *
     223              :  * This routine disables all interrupts on the CPU. It returns an unsigned
     224              :  * integer "lock-out key", which is an architecture-dependent indicator of
     225              :  * whether interrupts were locked prior to the call. The lock-out key must be
     226              :  * passed to irq_unlock() to re-enable interrupts.
     227              :  *
     228              :  * @note
     229              :  * This routine must also serve as a memory barrier to ensure the uniprocessor
     230              :  * implementation of spinlocks is correct.
     231              :  *
     232              :  * This routine can be called recursively, as long as the caller keeps track
     233              :  * of each lock-out key that is generated. Interrupts are re-enabled by
     234              :  * passing each of the keys to irq_unlock() in the reverse order they were
     235              :  * acquired. (That is, each call to irq_lock() must be balanced by
     236              :  * a corresponding call to irq_unlock().)
     237              :  *
     238              :  * This routine can only be invoked from supervisor mode. Some architectures
     239              :  * (for example, ARM) will fail silently if invoked from user mode instead
     240              :  * of generating an exception.
     241              :  *
     242              :  * This routine can be called by ISRs and threads.
     243              :  *
     244              :  * @warning
     245              :  * As long as all recursive calls to irq_lock() have not been balanced with
     246              :  * corresponding irq_unlock() calls, the caller "holds the interrupt lock".
     247              :  *
     248              :  * "Holding the interrupt lock" when a context switch occurs is illegal.
     249              :  *
     250              :  * @warning
     251              :  * The lock-out key should never be used to manually re-enable interrupts
     252              :  * or to inspect or manipulate the contents of the CPU's interrupt bits.
     253              :  *
     254              :  * @return An architecture-dependent lock-out key representing the
     255              :  *         "interrupt disable state" prior to the call.
     256              :  */
     257              : #ifdef CONFIG_SMP
     258              : unsigned int z_smp_global_lock(void);
     259            1 : #define irq_lock() z_smp_global_lock()
     260              : #else
     261              : #define irq_lock() arch_irq_lock()
     262              : #endif
     263              : 
     264              : /**
     265              :  * @brief Unlock interrupts.
     266              :  * @def irq_unlock()
     267              :  *
     268              :  * This routine reverses the effect of a previous call to irq_lock() using
     269              :  * the associated lock-out key. The caller must call the routine once for
     270              :  * each time it called irq_lock(), supplying the keys in the reverse order
     271              :  * they were acquired, before interrupts are enabled.
     272              :  *
     273              :  * @note
     274              :  * This routine must also serve as a memory barrier to ensure the uniprocessor
     275              :  * implementation of spinlocks is correct.
     276              :  *
     277              :  * This routine can only be invoked from supervisor mode. Some architectures
     278              :  * (for example, ARM) will fail silently if invoked from user mode instead
     279              :  * of generating an exception.
     280              :  *
     281              :  * @note Can be called by ISRs.
     282              :  *
     283              :  * @param key Lock-out key generated by irq_lock().
     284              :  */
     285              : #ifdef CONFIG_SMP
     286              : void z_smp_global_unlock(unsigned int key);
     287            1 : #define irq_unlock(key) z_smp_global_unlock(key)
     288              : #else
     289              : #define irq_unlock(key) arch_irq_unlock(key)
     290              : #endif
     291              : 
     292              : /**
     293              :  * @brief Enable an IRQ.
     294              :  *
     295              :  * This routine enables interrupts from source @a irq.
     296              :  *
     297              :  * @param irq IRQ line.
     298              :  */
     299            1 : #define irq_enable(irq) arch_irq_enable(irq)
     300              : 
     301              : /**
     302              :  * @brief Disable an IRQ.
     303              :  *
     304              :  * This routine disables interrupts from source @a irq.
     305              :  *
     306              :  * @param irq IRQ line.
     307              :  */
     308            1 : #define irq_disable(irq) arch_irq_disable(irq)
     309              : 
     310              : /**
     311              :  * @brief Get IRQ enable state.
     312              :  *
     313              :  * This routine indicates if interrupts from source @a irq are enabled.
     314              :  *
     315              :  * @param irq IRQ line.
     316              :  *
     317              :  * @return interrupt enable state, true or false
     318              :  */
     319            1 : #define irq_is_enabled(irq) arch_irq_is_enabled(irq)
     320              : 
     321              : /**
     322              :  * @}
     323              :  */
     324              : 
     325              : #ifdef __cplusplus
     326              : }
     327              : #endif
     328              : 
     329              : #endif /* ASMLANGUAGE */
     330              : #endif /* ZEPHYR_INCLUDE_IRQ_H_ */
        

Generated by: LCOV version 2.0-1