$treeview $search $mathjax $extrastylesheet
avr-libc
2.0.0
$projectbrief
|
$projectbrief
|
$searchbox |
AVR Libc Home Page |
AVR Libc Development Pages |
||||
Main Page |
User Manual |
Library Reference |
FAQ |
Example Projects |
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