avr-libc  2.0.0
Standard C library for AVR-GCC

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.
1 /* Copyright (c) 2002,2005,2007 Marek Michalkiewicz
2  Copyright (c) 2007, Dean Camera
3 
4  All rights reserved.
5 
6  Redistribution and use in source and binary forms, with or without
7  modification, are permitted provided that the following conditions are met:
8 
9  * Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11 
12  * Redistributions in binary form must reproduce the above copyright
13  notice, this list of conditions and the following disclaimer in
14  the documentation and/or other materials provided with the
15  distribution.
16 
17  * Neither the name of the copyright holders nor the names of
18  contributors may be used to endorse or promote products derived
19  from this software without specific prior written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  POSSIBILITY OF SUCH DAMAGE. */
32 
33 /* $Id: interrupt.h 2220 2011-02-22 21:08:58Z arcanum $ */
34 
35 #ifndef _AVR_INTERRUPT_H_
36 #define _AVR_INTERRUPT_H_
37 
38 #include <avr/io.h>
39 
40 #if !defined(__DOXYGEN__) && !defined(__STRINGIFY)
41 /* Auxiliary macro for ISR_ALIAS(). */
42 #define __STRINGIFY(x) #x
43 #endif /* !defined(__DOXYGEN__) */
44 
45 /**
46 \file
47 \@{
48 */
49 
50 
51 /** \name Global manipulation of the interrupt flag
52 
53  The global interrupt flag is maintained in the I bit of the status
54  register (SREG).
55 
56  Handling interrupts frequently requires attention regarding atomic
57  access to objects that could be altered by code running within an
58  interrupt context, see <util/atomic.h>.
59 
60  Frequently, interrupts are being disabled for periods of time in
61  order to perform certain operations without being disturbed; see
62  \ref optim_code_reorder for things to be taken into account with
63  respect to compiler optimizations.
64 */
65 
66 #if defined(__DOXYGEN__)
67 /** \def sei()
68  \ingroup avr_interrupts
69 
70  Enables interrupts by setting the global interrupt mask. This function
71  actually compiles into a single line of assembly, so there is no function
72  call overhead. However, the macro also implies a <i>memory barrier</i>
73  which can cause additional loss of optimization.
74 
75  In order to implement atomic access to multi-byte objects,
76  consider using the macros from <util/atomic.h>, rather than
77  implementing them manually with cli() and sei().
78 */
79 #define sei()
80 #else /* !DOXYGEN */
81 # define sei() __asm__ __volatile__ ("sei" ::: "memory")
82 #endif /* DOXYGEN */
83 
84 #if defined(__DOXYGEN__)
85 /** \def cli()
86  \ingroup avr_interrupts
87 
88  Disables all interrupts by clearing the global interrupt mask. This function
89  actually compiles into a single line of assembly, so there is no function
90  call overhead. However, the macro also implies a <i>memory barrier</i>
91  which can cause additional loss of optimization.
92 
93  In order to implement atomic access to multi-byte objects,
94  consider using the macros from <util/atomic.h>, rather than
95  implementing them manually with cli() and sei().
96 */
97 #define cli()
98 #else /* !DOXYGEN */
99 # define cli() __asm__ __volatile__ ("cli" ::: "memory")
100 #endif /* DOXYGEN */
101 
102 
103 /** \name Macros for writing interrupt handler functions */
104 
105 
106 #if defined(__DOXYGEN__)
107 /** \def ISR(vector [, attributes])
108  \ingroup avr_interrupts
109 
110  Introduces an interrupt handler function (interrupt service
111  routine) that runs with global interrupts initially disabled
112  by default with no attributes specified.
113 
114  The attributes are optional and alter the behaviour and resultant
115  generated code of the interrupt routine. Multiple attributes may
116  be used for a single function, with a space seperating each
117  attribute.
118 
119  Valid attributes are ISR_BLOCK, ISR_NOBLOCK, ISR_NAKED and
120  ISR_ALIASOF(vect).
121 
122  \c vector must be one of the interrupt vector names that are
123  valid for the particular MCU type.
124 */
125 # define ISR(vector, [attributes])
126 #else /* real code */
127 
128 #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
129 # define __INTR_ATTRS used, externally_visible
130 #else /* GCC < 4.1 */
131 # define __INTR_ATTRS used
132 #endif
133 
134 #ifdef __cplusplus
135 # define ISR(vector, ...) \
136  extern "C" void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
137  void vector (void)
138 #else
139 # define ISR(vector, ...) \
140  void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
141  void vector (void)
142 #endif
143 
144 #endif /* DOXYGEN */
145 
146 #if defined(__DOXYGEN__)
147 /** \def SIGNAL(vector)
148  \ingroup avr_interrupts
149 
150  Introduces an interrupt handler function that runs with global interrupts
151  initially disabled.
152 
153  This is the same as the ISR macro without optional attributes.
154  \deprecated Do not use SIGNAL() in new code. Use ISR() instead.
155 */
156 # define SIGNAL(vector)
157 #else /* real code */
158 
159 #ifdef __cplusplus
160 # define SIGNAL(vector) \
161  extern "C" void vector(void) __attribute__ ((signal, __INTR_ATTRS)); \
162  void vector (void)
163 #else
164 # define SIGNAL(vector) \
165  void vector (void) __attribute__ ((signal, __INTR_ATTRS)); \
166  void vector (void)
167 #endif
168 
169 #endif /* DOXYGEN */
170 
171 #if defined(__DOXYGEN__)
172 /** \def EMPTY_INTERRUPT(vector)
173  \ingroup avr_interrupts
174 
175  Defines an empty interrupt handler function. This will not generate
176  any prolog or epilog code and will only return from the ISR. Do not
177  define a function body as this will define it for you.
178  Example:
179  \code EMPTY_INTERRUPT(ADC_vect);\endcode */
180 # define EMPTY_INTERRUPT(vector)
181 #else /* real code */
182 
183 #ifdef __cplusplus
184 # define EMPTY_INTERRUPT(vector) \
185  extern "C" void vector(void) __attribute__ ((signal,naked,__INTR_ATTRS)); \
186  void vector (void) { __asm__ __volatile__ ("reti" ::); }
187 #else
188 # define EMPTY_INTERRUPT(vector) \
189  void vector (void) __attribute__ ((signal,naked,__INTR_ATTRS)); \
190  void vector (void) { __asm__ __volatile__ ("reti" ::); }
191 #endif
192 
193 #endif /* DOXYGEN */
194 
195 #if defined(__DOXYGEN__)
196 /** \def ISR_ALIAS(vector, target_vector)
197  \ingroup avr_interrupts
198 
199  Aliases a given vector to another one in the same manner as the
200  ISR_ALIASOF attribute for the ISR() macro. Unlike the ISR_ALIASOF
201  attribute macro however, this is compatible for all versions of
202  GCC rather than just GCC version 4.2 onwards.
203 
204  \note This macro creates a trampoline function for the aliased
205  macro. This will result in a two cycle penalty for the aliased
206  vector compared to the ISR the vector is aliased to, due to the
207  JMP/RJMP opcode used.
208 
209  \deprecated
210  For new code, the use of ISR(..., ISR_ALIASOF(...)) is
211  recommended.
212 
213  Example:
214  \code
215  ISR(INT0_vect)
216  {
217  PORTB = 42;
218  }
219 
220  ISR_ALIAS(INT1_vect, INT0_vect);
221  \endcode
222 
223 */
224 # define ISR_ALIAS(vector, target_vector)
225 #else /* real code */
226 
227 #ifdef __cplusplus
228 # if defined(__AVR_MEGA__) && __AVR_MEGA__
229 # define ISR_ALIAS(vector, tgt) extern "C" void vector (void) \
230  __attribute__((signal, naked, __INTR_ATTRS)); \
231  void vector (void) { asm volatile ("jmp " __STRINGIFY(tgt) ::); }
232 # else /* !__AVR_MEGA */
233 # define ISR_ALIAS(vector, tgt) extern "C" void vector (void) \
234  __attribute__((signal, naked, __INTR_ATTRS)); \
235  void vector (void) { asm volatile ("rjmp " __STRINGIFY(tgt) ::); }
236 # endif /* __AVR_MEGA__ */
237 #else /* !__cplusplus */
238 # if defined(__AVR_MEGA__) && __AVR_MEGA__
239 # define ISR_ALIAS(vector, tgt) void vector (void) \
240  __attribute__((signal, naked, __INTR_ATTRS)); \
241  void vector (void) { asm volatile ("jmp " __STRINGIFY(tgt) ::); }
242 # else /* !__AVR_MEGA */
243 # define ISR_ALIAS(vector, tgt) void vector (void) \
244  __attribute__((signal, naked, __INTR_ATTRS)); \
245  void vector (void) { asm volatile ("rjmp " __STRINGIFY(tgt) ::); }
246 # endif /* __AVR_MEGA__ */
247 #endif /* __cplusplus */
248 
249 #endif /* DOXYGEN */
250 
251 #if defined(__DOXYGEN__)
252 /** \def reti()
253  \ingroup avr_interrupts
254 
255  Returns from an interrupt routine, enabling global interrupts. This should
256  be the last command executed before leaving an ISR defined with the ISR_NAKED
257  attribute.
258 
259  This macro actually compiles into a single line of assembly, so there is
260  no function call overhead.
261 */
262 # define reti()
263 #else /* !DOXYGEN */
264 # define reti() __asm__ __volatile__ ("reti" ::)
265 #endif /* DOXYGEN */
266 
267 #if defined(__DOXYGEN__)
268 /** \def BADISR_vect
269  \ingroup avr_interrupts
270 
271  \code #include <avr/interrupt.h> \endcode
272 
273  This is a vector which is aliased to __vector_default, the vector
274  executed when an ISR fires with no accompanying ISR handler. This
275  may be used along with the ISR() macro to create a catch-all for
276  undefined but used ISRs for debugging purposes.
277 */
278 # define BADISR_vect
279 #else /* !DOXYGEN */
280 # define BADISR_vect __vector_default
281 #endif /* DOXYGEN */
282 
283 /** \name ISR attributes */
284 
285 #if defined(__DOXYGEN__)
286 /** \def ISR_BLOCK
287  \ingroup avr_interrupts
288 
289  Identical to an ISR with no attributes specified. Global
290  interrupts are initially disabled by the AVR hardware when
291  entering the ISR, without the compiler modifying this state.
292 
293  Use this attribute in the attributes parameter of the ISR macro.
294 */
295 # define ISR_BLOCK
296 
297 /** \def ISR_NOBLOCK
298  \ingroup avr_interrupts
299 
300  ISR runs with global interrupts initially enabled. The interrupt
301  enable flag is activated by the compiler as early as possible
302  within the ISR to ensure minimal processing delay for nested
303  interrupts.
304 
305  This may be used to create nested ISRs, however care should be
306  taken to avoid stack overflows, or to avoid infinitely entering
307  the ISR for those cases where the AVR hardware does not clear the
308  respective interrupt flag before entering the ISR.
309 
310  Use this attribute in the attributes parameter of the ISR macro.
311 */
312 # define ISR_NOBLOCK
313 
314 /** \def ISR_NAKED
315  \ingroup avr_interrupts
316 
317  ISR is created with no prologue or epilogue code. The user code is
318  responsible for preservation of the machine state including the
319  SREG register, as well as placing a reti() at the end of the
320  interrupt routine.
321 
322  Use this attribute in the attributes parameter of the ISR macro.
323 */
324 # define ISR_NAKED
325 
326 /** \def ISR_ALIASOF(target_vector)
327  \ingroup avr_interrupts
328 
329  The ISR is linked to another ISR, specified by the vect parameter.
330  This is compatible with GCC 4.2 and greater only.
331 
332  Use this attribute in the attributes parameter of the ISR macro.
333 */
334 # define ISR_ALIASOF(target_vector)
335 #else /* !DOXYGEN */
336 # define ISR_BLOCK
337 # define ISR_NOBLOCK __attribute__((interrupt))
338 # define ISR_NAKED __attribute__((naked))
339 # define ISR_ALIASOF(v) __attribute__((alias(__STRINGIFY(v))))
340 #endif /* DOXYGEN */
341 
342 /* \@} */
343 
344 #endif