AVR Libc Home Page AVRs AVR Libc Development Pages
Main Page User Manual Library Reference FAQ Alphabetical Index Example Projects

interrupt.h

Go to the documentation of this file.
00001 /* Copyright (c) 2002,2005,2007 Marek Michalkiewicz
00002    Copyright (c) 2007, Dean Camera
00003 
00004    All rights reserved.
00005 
00006    Redistribution and use in source and binary forms, with or without
00007    modification, are permitted provided that the following conditions are met:
00008 
00009    * Redistributions of source code must retain the above copyright
00010      notice, this list of conditions and the following disclaimer.
00011 
00012    * Redistributions in binary form must reproduce the above copyright
00013      notice, this list of conditions and the following disclaimer in
00014      the documentation and/or other materials provided with the
00015      distribution.
00016 
00017    * Neither the name of the copyright holders nor the names of
00018      contributors may be used to endorse or promote products derived
00019      from this software without specific prior written permission.
00020 
00021   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00022   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00025   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00026   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00027   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00028   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00029   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00030   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031   POSSIBILITY OF SUCH DAMAGE. */
00032 
00033 /* $Id: interrupt.h 2158 2010-06-10 15:48:28Z joerg_wunsch $ */
00034 
00035 #ifndef _AVR_INTERRUPT_H_
00036 #define _AVR_INTERRUPT_H_
00037 
00038 #include <avr/io.h>
00039 
00040 #if !defined(__DOXYGEN__) && !defined(__STRINGIFY)
00041 /* Auxiliary macro for ISR_ALIAS(). */
00042 #define __STRINGIFY(x) #x
00043 #endif /* !defined(__DOXYGEN__) */
00044 
00045 /** 
00046 \file 
00047 \@{ 
00048 */
00049 
00050 
00051 /** \name Global manipulation of the interrupt flag
00052 
00053     The global interrupt flag is maintained in the I bit of the status
00054     register (SREG).
00055 
00056     Handling interrupts frequently requires attention regarding atomic
00057     access to objects that could be altered by code running within an
00058     interrupt context, see <util/atomic.h>.
00059 
00060     Frequently, interrupts are being disabled for periods of time in
00061     order to perform certain operations without being disturbed; see
00062     \ref optim_code_reorder for things to be taken into account with
00063     respect to compiler optimizations.
00064 */
00065 
00066 #if defined(__DOXYGEN__)
00067 /** \def sei()
00068     \ingroup avr_interrupts
00069 
00070     \code #include <avr/interrupt.h> \endcode
00071 
00072     Enables interrupts by setting the global interrupt mask. This function
00073     actually compiles into a single line of assembly, so there is no function
00074     call overhead.  However, the macro also implies a <i>memory barrier</i>
00075     which can cause additional loss of optimization.
00076 
00077     In order to implement atomic access to multi-byte objects,
00078     consider using the macros from <util/atomic.h>, rather than
00079     implementing them manually with cli() and sei().
00080 */
00081 #define sei()
00082 #else  /* !DOXYGEN */
00083 # define sei()  __asm__ __volatile__ ("sei" ::: "memory")
00084 #endif /* DOXYGEN */
00085 
00086 #if defined(__DOXYGEN__)
00087 /** \def cli()
00088     \ingroup avr_interrupts
00089 
00090     \code #include <avr/interrupt.h> \endcode
00091 
00092     Disables all interrupts by clearing the global interrupt mask. This function
00093     actually compiles into a single line of assembly, so there is no function
00094     call overhead.  However, the macro also implies a <i>memory barrier</i>
00095     which can cause additional loss of optimization.
00096 
00097     In order to implement atomic access to multi-byte objects,
00098     consider using the macros from <util/atomic.h>, rather than
00099     implementing them manually with cli() and sei().
00100 */
00101 #define cli()
00102 #else  /* !DOXYGEN */
00103 # define cli()  __asm__ __volatile__ ("cli" ::: "memory")
00104 #endif /* DOXYGEN */
00105 
00106 
00107 /** \name Macros for writing interrupt handler functions */
00108 
00109 
00110 #if defined(__DOXYGEN__)
00111 /** \def ISR(vector [, attributes])
00112     \ingroup avr_interrupts
00113 
00114     \code #include <avr/interrupt.h> \endcode
00115 
00116     Introduces an interrupt handler function (interrupt service
00117     routine) that runs with global interrupts initially disabled
00118     by default with no attributes specified.
00119 
00120     The attributes are optional and alter the behaviour and resultant
00121     generated code of the interrupt routine. Multiple attributes may
00122     be used for a single function, with a space seperating each
00123     attribute.
00124 
00125     Valid attributes are ISR_BLOCK, ISR_NOBLOCK, ISR_NAKED and
00126     ISR_ALIASOF(vect).
00127 
00128     \c vector must be one of the interrupt vector names that are
00129     valid for the particular MCU type.
00130 */
00131 #  define ISR(vector, [attributes])
00132 #else  /* real code */
00133 
00134 #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
00135 #  define __INTR_ATTRS used, externally_visible
00136 #else /* GCC < 4.1 */
00137 #  define __INTR_ATTRS used
00138 #endif
00139 
00140 #ifdef __cplusplus
00141 #  define ISR(vector, ...)            \
00142     extern "C" void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
00143     void vector (void)
00144 #else
00145 #  define ISR(vector, ...)            \
00146     void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
00147     void vector (void)
00148 #endif
00149 
00150 #endif /* DOXYGEN */
00151 
00152 #if defined(__DOXYGEN__)
00153 /** \def SIGNAL(vector)
00154     \ingroup avr_interrupts
00155 
00156     \code #include <avr/interrupt.h> \endcode
00157 
00158     Introduces an interrupt handler function that runs with global interrupts
00159     initially disabled.
00160 
00161     This is the same as the ISR macro without optional attributes.
00162     \deprecated Do not use SIGNAL() in new code. Use ISR() instead.
00163 */
00164 #  define SIGNAL(vector)
00165 #else  /* real code */
00166 
00167 #ifdef __cplusplus
00168 #  define SIGNAL(vector)                                        \
00169     extern "C" void vector(void) __attribute__ ((signal, __INTR_ATTRS));        \
00170     void vector (void)
00171 #else
00172 #  define SIGNAL(vector)                                        \
00173     void vector (void) __attribute__ ((signal, __INTR_ATTRS));          \
00174     void vector (void)
00175 #endif
00176 
00177 #endif /* DOXYGEN */
00178 
00179 #if defined(__DOXYGEN__)
00180 /** \def EMPTY_INTERRUPT(vector)
00181     \ingroup avr_interrupts
00182 
00183     \code #include <avr/interrupt.h> \endcode
00184 
00185     Defines an empty interrupt handler function. This will not generate
00186     any prolog or epilog code and will only return from the ISR. Do not
00187     define a function body as this will define it for you.
00188     Example:
00189     \code EMPTY_INTERRUPT(ADC_vect);\endcode */
00190 #  define EMPTY_INTERRUPT(vector)
00191 #else  /* real code */
00192 
00193 #ifdef __cplusplus
00194 #  define EMPTY_INTERRUPT(vector)                \
00195     extern "C" void vector(void) __attribute__ ((signal,naked,__INTR_ATTRS));    \
00196     void vector (void) {  __asm__ __volatile__ ("reti" ::); }
00197 #else
00198 #  define EMPTY_INTERRUPT(vector)                \
00199     void vector (void) __attribute__ ((signal,naked,__INTR_ATTRS));    \
00200     void vector (void) { __asm__ __volatile__ ("reti" ::); }
00201 #endif
00202 
00203 #endif /* DOXYGEN */
00204 
00205 #if defined(__DOXYGEN__)
00206 /** \def ISR_ALIAS(vector, target_vector)
00207     \ingroup avr_interrupts
00208 
00209     \code #include <avr/interrupt.h> \endcode
00210 
00211     Aliases a given vector to another one in the same manner as the
00212     ISR_ALIASOF attribute for the ISR() macro. Unlike the ISR_ALIASOF
00213     attribute macro however, this is compatible for all versions of
00214     GCC rather than just GCC version 4.2 onwards.
00215 
00216     \note This macro creates a trampoline function for the aliased
00217     macro.  This will result in a two cycle penalty for the aliased
00218     vector compared to the ISR the vector is aliased to, due to the
00219     JMP/RJMP opcode used.
00220 
00221     \deprecated
00222     For new code, the use of ISR(..., ISR_ALIASOF(...))  is
00223     recommended.
00224 
00225     Example:
00226     \code
00227     ISR(INT0_vect)
00228     {
00229         PORTB = 42;
00230     }
00231 
00232     ISR_ALIAS(INT1_vect, INT0_vect);
00233     \endcode 
00234 */
00235 #  define ISR_ALIAS(vector, target_vector)
00236 #else /* real code */
00237 
00238 #ifdef __cplusplus
00239 #  if defined(__AVR_MEGA__) && __AVR_MEGA__
00240 #    define ISR_ALIAS(vector, tgt) extern "C" void vector (void) \
00241         __attribute__((signal, naked, __INTR_ATTRS)); \
00242         void vector (void) { asm volatile ("jmp " __STRINGIFY(tgt) ::); }
00243 #  else /* !__AVR_MEGA */
00244 #    define ISR_ALIAS(vector, tgt) extern "C" void vector (void) \
00245         __attribute__((signal, naked, __INTR_ATTRS)); \
00246         void vector (void) { asm volatile ("rjmp " __STRINGIFY(tgt) ::); }
00247 #  endif  /* __AVR_MEGA__ */
00248 #else     /* !__cplusplus */
00249 #  if defined(__AVR_MEGA__) && __AVR_MEGA__
00250 #  define ISR_ALIAS(vector, tgt) void vector (void) \
00251         __attribute__((signal, naked, __INTR_ATTRS)); \
00252         void vector (void) { asm volatile ("jmp " __STRINGIFY(tgt) ::); }
00253 #  else /* !__AVR_MEGA */
00254 #  define ISR_ALIAS(vector, tgt) void vector (void) \
00255         __attribute__((signal, naked, __INTR_ATTRS)); \
00256         void vector (void) { asm volatile ("rjmp " __STRINGIFY(tgt) ::); }
00257 #  endif  /* __AVR_MEGA__ */
00258 #endif  /* __cplusplus */
00259 
00260 #endif /* DOXYGEN */
00261 
00262 #if defined(__DOXYGEN__)
00263 /** \def reti()
00264     \ingroup avr_interrupts
00265 
00266     \code #include <avr/interrupt.h> \endcode
00267 
00268     Returns from an interrupt routine, enabling global interrupts. This should
00269     be the last command executed before leaving an ISR defined with the ISR_NAKED
00270     attribute.
00271 
00272     This macro actually compiles into a single line of assembly, so there is
00273     no function call overhead.
00274 */
00275 #  define reti()
00276 #else  /* !DOXYGEN */
00277 #  define reti()  __asm__ __volatile__ ("reti" ::)
00278 #endif /* DOXYGEN */
00279 
00280 #if defined(__DOXYGEN__)
00281 /** \def BADISR_vect
00282     \ingroup avr_interrupts
00283 
00284     \code #include <avr/interrupt.h> \endcode
00285 
00286     This is a vector which is aliased to __vector_default, the vector
00287     executed when an ISR fires with no accompanying ISR handler. This
00288     may be used along with the ISR() macro to create a catch-all for
00289     undefined but used ISRs for debugging purposes.
00290 */
00291 #  define BADISR_vect
00292 #else  /* !DOXYGEN */
00293 #  define BADISR_vect __vector_default
00294 #endif /* DOXYGEN */
00295 
00296 /** \name ISR attributes */
00297 
00298 #if defined(__DOXYGEN__)
00299 /** \def ISR_BLOCK
00300     \ingroup avr_interrupts
00301 
00302     \code# include <avr/interrupt.h> \endcode
00303 
00304     Identical to an ISR with no attributes specified. Global
00305     interrupts are initially disabled by the AVR hardware when
00306     entering the ISR, without the compiler modifying this state.
00307 
00308     Use this attribute in the attributes parameter of the ISR macro.
00309 */
00310 #  define ISR_BLOCK
00311 
00312 /** \def ISR_NOBLOCK
00313     \ingroup avr_interrupts
00314 
00315     \code# include <avr/interrupt.h> \endcode
00316 
00317     ISR runs with global interrupts initially enabled.  The interrupt
00318     enable flag is activated by the compiler as early as possible
00319     within the ISR to ensure minimal processing delay for nested
00320     interrupts.
00321 
00322     This may be used to create nested ISRs, however care should be
00323     taken to avoid stack overflows, or to avoid infinitely entering
00324     the ISR for those cases where the AVR hardware does not clear the
00325     respective interrupt flag before entering the ISR.
00326 
00327     Use this attribute in the attributes parameter of the ISR macro.
00328 */
00329 #  define ISR_NOBLOCK
00330 
00331 /** \def ISR_NAKED
00332     \ingroup avr_interrupts
00333 
00334     \code# include <avr/interrupt.h> \endcode
00335 
00336     ISR is created with no prologue or epilogue code. The user code is
00337     responsible for preservation of the machine state including the
00338     SREG register, as well as placing a reti() at the end of the
00339     interrupt routine.
00340 
00341     Use this attribute in the attributes parameter of the ISR macro.
00342 */
00343 #  define ISR_NAKED
00344 
00345 /** \def ISR_ALIASOF(target_vector)
00346     \ingroup avr_interrupts
00347 
00348     \code#include <avr/interrupt.h>\endcode
00349 
00350     The ISR is linked to another ISR, specified by the vect parameter.
00351     This is compatible with GCC 4.2 and greater only.
00352 
00353     Use this attribute in the attributes parameter of the ISR macro.
00354 */
00355 #  define ISR_ALIASOF(target_vector)
00356 #else  /* !DOXYGEN */
00357 #  define ISR_BLOCK
00358 #  define ISR_NOBLOCK    __attribute__((interrupt))
00359 #  define ISR_NAKED      __attribute__((naked))
00360 #  define ISR_ALIASOF(v) __attribute__((alias(__STRINGIFY(v))))
00361 #endif /* DOXYGEN */
00362 
00363 /* \@} */
00364 
00365 #endif

Automatically generated by Doxygen 1.7.3 on Thu May 19 2011.