interrupt_utils.h
Go to the documentation of this file.
00001 /*
00002  *  Defines and Macros for Interrupt-Service-Routines
00003  *  collected and partly created by
00004  *  Martin Thomas <mthomas@rhrk.uni-kl.de>
00005  *
00006  *  Copyright 2005 M. Thomas
00007  *  No guarantees, warrantees, or promises, implied or otherwise.
00008  *  May be used for hobby or commercial purposes provided copyright
00009  *  notice remains intact.
00010  */
00011 
00012 /* 
00013    Warning: The enable- and disable-functions can not be used
00014    in USR-mode which is the default for the Philips-examples
00015    (see Startup.S). cpsr can not be written in USR-mode. 
00016    If you need to enable or disable interrupts use the 
00017    SWI-calls (see example SWI/swi.c/swi_handler.S). The 
00018    functions can be used in SYS-mode to start the system
00019    in SYS-mode the startup-code must be changed.
00020 
00021    The macros in this file are useful if interrupt-service-routines
00022    when using thumb-mode and/or optimisation without an addtional
00023    "assembler-wrapper". The gcc-attribute interrupt("IRQ") does 
00024    not work reliably here. See timer.c for an example implementation 
00025    of an ISR that uses macros. For the gcc-port of the Philips-examples 
00026    the macros are not needed, all functionality has been integrated 
00027    into isr_wrapper (see Startup.S).
00028 */
00029 
00030 #ifndef interrupt_utils_
00031 #define interrupt_utils_
00032 
00033 /* 
00034    The following defines are usefull for 
00035    interrupt service routine declarations.
00036 */
00037 
00038 /* 
00039    RAMFUNC 
00040    Attribute which defines a function to be located 
00041    in memory section .fastrun and called via "long calls". 
00042    See linker-skript and startup-code to see how the
00043    .fastrun-section is handled.
00044    The definition is not only useful for ISRs but since
00045    ISRs should be executed fast the macro is defined in
00046    this header.
00047 */
00048 #define RAMFUNC __attribute__ ((long_call, section (".fastrun")))
00049 
00050 
00051 /*
00052   INTFUNC
00053   standard attribute for arm-elf-gcc which marks
00054   a function as ISR (for the VIC). Since gcc seems
00055   to produce wrong code if this attribute is used in
00056   thumb/thumb-interwork and/or activated optimisation
00057   the attribute should only be used for "pure ARM-mode" 
00058   binaries.
00059 */
00060 #define INTFUNC __attribute__ ((interrupt("IRQ"))) 
00061 
00062 
00063 /*
00064   NACKEDFUNC
00065   gcc will not add any code to a function declared
00066   "nacked". The user has to take care to save registers
00067   and add the needed code for ISR functions. Some
00068   macros for this tasks are provided below.
00069 */
00070 #define NACKEDFUNC __attribute__((naked))
00071 
00072 
00073 /******************************************************************************
00074  *
00075  * MACRO Name: ISR_STORE()
00076  *
00077  * Description:
00078  *    This MACRO is used upon entry to an ISR with interrupt nesting.  
00079  *    Should be used together with ISR_ENABLE_NEST(). The MACRO
00080  *    performs the following steps:
00081  *
00082  *    1 - Save the non-banked registers r0-r12 and lr onto the IRQ stack.
00083  *
00084  *****************************************************************************/
00085 #define ISR_STORE() asm volatile( \
00086  "STMDB SP!,{R0-R12,LR}\n" )
00087  
00088  /******************************************************************************
00089  *
00090  * MACRO Name: ISR_RESTORE()
00091  *
00092  * Description:
00093  *    This MACRO is used upon exit from an ISR with interrupt nesting.  
00094  *    Should be used together with ISR_DISABLE_NEST(). The MACRO
00095  *    performs the following steps:
00096  *
00097  *    1 - Load the non-banked registers r0-r12 and lr from the IRQ stack.
00098  *    2 - Adjusts resume adress
00099  *
00100  *****************************************************************************/
00101 #define ISR_RESTORE()  asm volatile( \
00102  "LDMIA SP!,{R0-R12,LR}\n" \
00103  "SUBS  R15,R14,#0x0004\n" ) 
00104 
00105 /******************************************************************************
00106  *
00107  * MACRO Name: ISR_ENABLE_NEST()
00108  *
00109  * Description:
00110  *    This MACRO is used upon entry from an ISR with interrupt nesting.  
00111  *    Should be used after ISR_STORE. 
00112  *
00113  *****************************************************************************/
00114 #define ISR_ENABLE_NEST() asm volatile( \
00115  "MRS     LR, SPSR \n"  \
00116  "STMFD   SP!, {LR} \n" \
00117  "MSR     CPSR_c, #0x1F \n" \
00118  "STMFD   SP!, {LR} " )
00119 
00120 /******************************************************************************
00121  *
00122  * MACRO Name: ISR_DISABLE_NEST()
00123  *
00124  * Description:
00125  *    This MACRO is used upon entry from an ISR with interrupt nesting.  
00126  *    Should be used before ISR_RESTORE. 
00127  *
00128  *****************************************************************************/
00129 #define ISR_DISABLE_NEST() asm volatile(  \
00130  "LDMFD   SP!, {LR} \n" \
00131  "MSR     CPSR_c, #0x92 \n" \
00132  "LDMFD   SP!, {LR} \n" \
00133  "MSR     SPSR_cxsf, LR \n" )
00134 
00135 
00136  
00137 /*
00138  * The following marcos are from the file "armVIC.h" by:
00139  *
00140  * Copyright 2004, R O SoftWare
00141  * No guarantees, warrantees, or promises, implied or otherwise.
00142  * May be used for hobby or commercial purposes provided copyright
00143  * notice remains intact.
00144  * 
00145  */ 
00146  
00147 /******************************************************************************
00148  *
00149  * MACRO Name: ISR_ENTRY()
00150  *
00151  * Description:
00152  *    This MACRO is used upon entry to an ISR.  The current version of
00153  *    the gcc compiler for ARM does not produce correct code for
00154  *    interrupt routines to operate properly with THUMB code.  The MACRO
00155  *    performs the following steps:
00156  *
00157  *    1 - Adjust address at which execution should resume after servicing
00158  *        ISR to compensate for IRQ entry
00159  *    2 - Save the non-banked registers r0-r12 and lr onto the IRQ stack.
00160  *    3 - Get the status of the interrupted program is in SPSR.
00161  *    4 - Push it onto the IRQ stack as well.
00162  *
00163  *****************************************************************************/
00164 #define ISR_ENTRY() asm volatile(" sub   lr, lr,#4\n" \
00165                                  " stmfd sp!,{r0-r12,lr}\n" \
00166                                  " mrs   r1, spsr\n" \
00167                                  " stmfd sp!,{r1}")
00168 
00169 /******************************************************************************
00170  *
00171  * MACRO Name: ISR_EXIT()
00172  *
00173  * Description:
00174  *    This MACRO is used to exit an ISR.  The current version of the gcc
00175  *    compiler for ARM does not produce correct code for interrupt
00176  *    routines to operate properly with THUMB code.  The MACRO performs
00177  *    the following steps:
00178  *
00179  *    1 - Recover SPSR value from stack       
00180  *    2 - and restore  its value                   
00181  *    3 - Pop the return address & the saved general registers from
00182  *        the IRQ stack & return
00183  *
00184  *****************************************************************************/
00185 #define ISR_EXIT()  asm volatile(" ldmfd sp!,{r1}\n" \
00186                                  " msr   spsr_c,r1\n" \
00187                                  " ldmfd sp!,{r0-r12,pc}^") 
00188   
00189 /******************************************************************************
00190  *
00191  * Function Name: disableIRQ()
00192  *
00193  * Description:
00194  *    This function sets the IRQ disable bit in the status register
00195  *
00196  * Calling Sequence: 
00197  *    void
00198  *
00199  * Returns:
00200  *    previous value of CPSR
00201  *
00202  *****************************************************************************/
00203 unsigned disableIRQ(void);
00204 
00205 /******************************************************************************
00206  *
00207  * Function Name: enableIRQ()
00208  *
00209  * Description:
00210  *    This function clears the IRQ disable bit in the status register
00211  *
00212  * Calling Sequence: 
00213  *    void
00214  *
00215  * Returns:
00216  *    previous value of CPSR
00217  *
00218  *****************************************************************************/
00219 unsigned enableIRQ(void);
00220 
00221 /******************************************************************************
00222  *
00223  * Function Name: restoreIRQ()
00224  *
00225  * Description:
00226  *    This function restores the IRQ disable bit in the status register
00227  *    to the value contained within passed oldCPSR
00228  *
00229  * Calling Sequence: 
00230  *    void
00231  *
00232  * Returns:
00233  *    previous value of CPSR
00234  *
00235  *****************************************************************************/
00236 unsigned restoreIRQ(unsigned oldCPSR);
00237 
00238 /******************************************************************************
00239  *
00240  * Function Name: disableFIQ()
00241  *
00242  * Description:
00243  *    This function sets the FIQ disable bit in the status register
00244  *
00245  * Calling Sequence: 
00246  *    void
00247  *
00248  * Returns:
00249  *    previous value of CPSR
00250  *
00251  *****************************************************************************/
00252 unsigned disableFIQ(void);
00253 
00254 /******************************************************************************
00255  *
00256  * Function Name: enableFIQ()
00257  *
00258  * Description:
00259  *    This function clears the FIQ disable bit in the status register
00260  *
00261  * Calling Sequence: 
00262  *    void
00263  *
00264  * Returns:
00265  *    previous value of CPSR
00266  *
00267  *****************************************************************************/
00268 unsigned enableFIQ(void);
00269 
00270 /******************************************************************************
00271  *
00272  * Function Name: restoreFIQ()
00273  *
00274  * Description:
00275  *    This function restores the FIQ disable bit in the status register
00276  *    to the value contained within passed oldCPSR
00277  *
00278  * Calling Sequence: 
00279  *    void
00280  *
00281  * Returns:
00282  *    previous value of CPSR
00283  *
00284  *****************************************************************************/
00285 unsigned restoreFIQ(unsigned oldCPSR);
00286 
00287 
00288 #endif
00289 


asctec_hl_firmware
Author(s): Markus Achtelik, Michael Achtelik, Stephan Weiss, Laurent Kneip
autogenerated on Tue Dec 17 2013 11:39:27