$treeview $search $mathjax $extrastylesheet
avr-libc  2.0.0
$projectbrief
$projectbrief
$searchbox

AVR Libc Home Page

AVRs

AVR Libc Development Pages

Main Page

User Manual

Library Reference

FAQ

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$ */
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     Enables interrupts by setting the global interrupt mask. This function
00071     actually compiles into a single line of assembly, so there is no function
00072     call overhead.  However, the macro also implies a <i>memory barrier</i>
00073     which can cause additional loss of optimization.
00074 
00075     In order to implement atomic access to multi-byte objects,
00076     consider using the macros from <util/atomic.h>, rather than
00077     implementing them manually with cli() and sei().
00078 */
00079 #define sei()
00080 #else  /* !DOXYGEN */
00081 # define sei()  __asm__ __volatile__ ("sei" ::: "memory")
00082 #endif /* DOXYGEN */
00083 
00084 #if defined(__DOXYGEN__)
00085 /** \def cli()
00086     \ingroup avr_interrupts
00087 
00088     Disables all interrupts by clearing the global interrupt mask. This function
00089     actually compiles into a single line of assembly, so there is no function
00090     call overhead.  However, the macro also implies a <i>memory barrier</i>
00091     which can cause additional loss of optimization.
00092 
00093     In order to implement atomic access to multi-byte objects,
00094     consider using the macros from <util/atomic.h>, rather than
00095     implementing them manually with cli() and sei().
00096 */
00097 #define cli()
00098 #else  /* !DOXYGEN */
00099 # define cli()  __asm__ __volatile__ ("cli" ::: "memory")
00100 #endif /* DOXYGEN */
00101 
00102 
00103 /** \name Macros for writing interrupt handler functions */
00104 
00105 
00106 #if defined(__DOXYGEN__)
00107 /** \def ISR(vector [, attributes])
00108     \ingroup avr_interrupts
00109 
00110     Introduces an interrupt handler function (interrupt service
00111     routine) that runs with global interrupts initially disabled
00112     by default with no attributes specified.
00113 
00114     The attributes are optional and alter the behaviour and resultant
00115     generated code of the interrupt routine. Multiple attributes may
00116     be used for a single function, with a space seperating each
00117     attribute.
00118 
00119     Valid attributes are ISR_BLOCK, ISR_NOBLOCK, ISR_NAKED and
00120     ISR_ALIASOF(vect).
00121 
00122     \c vector must be one of the interrupt vector names that are
00123     valid for the particular MCU type.
00124 */
00125 #  define ISR(vector, [attributes])
00126 #else  /* real code */
00127 
00128 #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
00129 #  define __INTR_ATTRS used, externally_visible
00130 #else /* GCC < 4.1 */
00131 #  define __INTR_ATTRS used
00132 #endif
00133 
00134 #ifdef __cplusplus
00135 #  define ISR(vector, ...)            \
00136     extern "C" void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
00137     void vector (void)
00138 #else
00139 #  define ISR(vector, ...)            \
00140     void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
00141     void vector (void)
00142 #endif
00143 
00144 #endif /* DOXYGEN */
00145 
00146 #if defined(__DOXYGEN__)
00147 /** \def SIGNAL(vector)
00148     \ingroup avr_interrupts
00149 
00150     Introduces an interrupt handler function that runs with global interrupts
00151     initially disabled.
00152 
00153     This is the same as the ISR macro without optional attributes.
00154     \deprecated Do not use SIGNAL() in new code. Use ISR() instead.
00155 */
00156 #  define SIGNAL(vector)
00157 #else  /* real code */
00158 
00159 #ifdef __cplusplus
00160 #  define SIGNAL(vector)                    \
00161     extern "C" void vector(void) __attribute__ ((signal, __INTR_ATTRS));    \
00162     void vector (void)
00163 #else
00164 #  define SIGNAL(vector)                    \
00165     void vector (void) __attribute__ ((signal, __INTR_ATTRS));      \
00166     void vector (void)
00167 #endif
00168 
00169 #endif /* DOXYGEN */
00170 
00171 #if defined(__DOXYGEN__)
00172 /** \def EMPTY_INTERRUPT(vector)
00173     \ingroup avr_interrupts
00174 
00175     Defines an empty interrupt handler function. This will not generate
00176     any prolog or epilog code and will only return from the ISR. Do not
00177     define a function body as this will define it for you.
00178     Example:
00179     \code EMPTY_INTERRUPT(ADC_vect);\endcode */
00180 #  define EMPTY_INTERRUPT(vector)
00181 #else  /* real code */
00182 
00183 #ifdef __cplusplus
00184 #  define EMPTY_INTERRUPT(vector)                \
00185     extern "C" void vector(void) __attribute__ ((signal,naked,__INTR_ATTRS));    \
00186     void vector (void) {  __asm__ __volatile__ ("reti" ::); }
00187 #else
00188 #  define EMPTY_INTERRUPT(vector)                \
00189     void vector (void) __attribute__ ((signal,naked,__INTR_ATTRS));    \
00190     void vector (void) { __asm__ __volatile__ ("reti" ::); }
00191 #endif
00192 
00193 #endif /* DOXYGEN */
00194 
00195 #if defined(__DOXYGEN__)
00196 /** \def ISR_ALIAS(vector, target_vector)
00197     \ingroup avr_interrupts
00198 
00199     Aliases a given vector to another one in the same manner as the
00200     ISR_ALIASOF attribute for the ISR() macro. Unlike the ISR_ALIASOF
00201     attribute macro however, this is compatible for all versions of
00202     GCC rather than just GCC version 4.2 onwards.
00203 
00204     \note This macro creates a trampoline function for the aliased
00205     macro.  This will result in a two cycle penalty for the aliased
00206     vector compared to the ISR the vector is aliased to, due to the
00207     JMP/RJMP opcode used.
00208 
00209     \deprecated
00210     For new code, the use of ISR(..., ISR_ALIASOF(...))  is
00211     recommended.
00212 
00213     Example:
00214     \code
00215     ISR(INT0_vect)
00216     {
00217         PORTB = 42;
00218     }
00219 
00220     ISR_ALIAS(INT1_vect, INT0_vect);
00221     \endcode 
00222     
00223 */
00224 #  define ISR_ALIAS(vector, target_vector)
00225 #else /* real code */
00226 
00227 #ifdef __cplusplus
00228 #  if defined(__AVR_MEGA__) && __AVR_MEGA__
00229 #    define ISR_ALIAS(vector, tgt) extern "C" void vector (void) \
00230     __attribute__((signal, naked, __INTR_ATTRS)); \
00231     void vector (void) { asm volatile ("jmp " __STRINGIFY(tgt) ::); }
00232 #  else /* !__AVR_MEGA */
00233 #    define ISR_ALIAS(vector, tgt) extern "C" void vector (void) \
00234     __attribute__((signal, naked, __INTR_ATTRS)); \
00235     void vector (void) { asm volatile ("rjmp " __STRINGIFY(tgt) ::); }
00236 #  endif  /* __AVR_MEGA__ */
00237 #else     /* !__cplusplus */
00238 #  if defined(__AVR_MEGA__) && __AVR_MEGA__
00239 #  define ISR_ALIAS(vector, tgt) void vector (void) \
00240     __attribute__((signal, naked, __INTR_ATTRS)); \
00241     void vector (void) { asm volatile ("jmp " __STRINGIFY(tgt) ::); }
00242 #  else /* !__AVR_MEGA */
00243 #  define ISR_ALIAS(vector, tgt) void vector (void) \
00244     __attribute__((signal, naked, __INTR_ATTRS)); \
00245     void vector (void) { asm volatile ("rjmp " __STRINGIFY(tgt) ::); }
00246 #  endif  /* __AVR_MEGA__ */
00247 #endif  /* __cplusplus */
00248 
00249 #endif /* DOXYGEN */
00250 
00251 #if defined(__DOXYGEN__)
00252 /** \def reti()
00253     \ingroup avr_interrupts
00254 
00255     Returns from an interrupt routine, enabling global interrupts. This should
00256     be the last command executed before leaving an ISR defined with the ISR_NAKED
00257     attribute.
00258 
00259     This macro actually compiles into a single line of assembly, so there is
00260     no function call overhead.
00261 */
00262 #  define reti()
00263 #else  /* !DOXYGEN */
00264 #  define reti()  __asm__ __volatile__ ("reti" ::)
00265 #endif /* DOXYGEN */
00266 
00267 #if defined(__DOXYGEN__)
00268 /** \def BADISR_vect
00269     \ingroup avr_interrupts
00270 
00271     \code #include <avr/interrupt.h> \endcode
00272 
00273     This is a vector which is aliased to __vector_default, the vector
00274     executed when an ISR fires with no accompanying ISR handler. This
00275     may be used along with the ISR() macro to create a catch-all for
00276     undefined but used ISRs for debugging purposes.
00277 */
00278 #  define BADISR_vect
00279 #else  /* !DOXYGEN */
00280 #  define BADISR_vect __vector_default
00281 #endif /* DOXYGEN */
00282 
00283 /** \name ISR attributes */
00284 
00285 #if defined(__DOXYGEN__)
00286 /** \def ISR_BLOCK
00287     \ingroup avr_interrupts
00288 
00289     Identical to an ISR with no attributes specified. Global
00290     interrupts are initially disabled by the AVR hardware when
00291     entering the ISR, without the compiler modifying this state.
00292 
00293     Use this attribute in the attributes parameter of the ISR macro.
00294 */
00295 #  define ISR_BLOCK
00296 
00297 /** \def ISR_NOBLOCK
00298     \ingroup avr_interrupts
00299 
00300     ISR runs with global interrupts initially enabled.  The interrupt
00301     enable flag is activated by the compiler as early as possible
00302     within the ISR to ensure minimal processing delay for nested
00303     interrupts.
00304 
00305     This may be used to create nested ISRs, however care should be
00306     taken to avoid stack overflows, or to avoid infinitely entering
00307     the ISR for those cases where the AVR hardware does not clear the
00308     respective interrupt flag before entering the ISR.
00309 
00310     Use this attribute in the attributes parameter of the ISR macro.
00311 */
00312 #  define ISR_NOBLOCK
00313 
00314 /** \def ISR_NAKED
00315     \ingroup avr_interrupts
00316 
00317     ISR is created with no prologue or epilogue code. The user code is
00318     responsible for preservation of the machine state including the
00319     SREG register, as well as placing a reti() at the end of the
00320     interrupt routine.
00321 
00322     Use this attribute in the attributes parameter of the ISR macro.
00323 */
00324 #  define ISR_NAKED
00325 
00326 /** \def ISR_ALIASOF(target_vector)
00327     \ingroup avr_interrupts
00328 
00329     The ISR is linked to another ISR, specified by the vect parameter.
00330     This is compatible with GCC 4.2 and greater only.
00331 
00332     Use this attribute in the attributes parameter of the ISR macro.
00333 */
00334 #  define ISR_ALIASOF(target_vector)
00335 #else  /* !DOXYGEN */
00336 #  define ISR_BLOCK
00337 #  define ISR_NOBLOCK    __attribute__((interrupt))
00338 #  define ISR_NAKED      __attribute__((naked))
00339 #  define ISR_ALIASOF(v) __attribute__((alias(__STRINGIFY(v))))
00340 #endif /* DOXYGEN */
00341 
00342 /* \@} */
00343 
00344 #endif
 All Data Structures Files Functions Variables Typedefs Enumerations Defines