EmbDev.net

Forum: ARM programming with GCC/GNU tools Nested interrupt On - Off


von Adam (Guest)


Rate this post
useful
not useful
Hi.

I have a question about using the nested interrupts.
Currently I'am using the starting S-file:


========================================================================
/*---------------------------------------------------------------------- 
--------
//*-         ATMEL Microcontroller Software Support  -  ROUSSET  -
//*--------------------------------------------------------------------- 
---------
//* The software is delivered "AS IS" without warranty or condition of
any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability
or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*--------------------------------------------------------------------- 
--------
//*- File source          : Cstartup.s
//*- Object               : Generic CStartup for KEIL and GCC
//*- Compilation flag     : None
//*-
//*- 1.0 18/Oct/04 JPP    : Creation
//*- 1.1 21/Feb/05 JPP    : Set Interrupt
//*- 1.1 01/Apr/05 JPP    : save SPSR
//*
//*- WinARM/arm-elf-gcc-version by Martin Thomas - Modifications:
//*  remapping-support, vector-location, stack-position and more...
//*--------------------------------------------------------------------- 
--------*/

/*
   20060902 (mth) : moved IRQ-Handler from section .vect* to
                    .init/.fastrun
   20061101 (mth) : update IRQ-Handler
                    FIQ-stack init
*/

/* check configuration-options and map to "assembler symbols": */

#ifdef ROM_RUN
.set RAM_MODE, 0
#ifdef VECTORS_IN_RAM
.set REMAP, 1
.set VECTREMAPPED, 1
#else
.set REMAP, 0
.set VECTREMAPPED, 0
#endif
#endif

#ifdef RAM_RUN
.set RAM_MODE, 1
.set REMAP, 1
.set VECTREMAPPED, 0
#endif


.if (RAM_MODE)
.print "RAM_MODE enabled"
.else
.print "ROM_MODE enabled"
.endif

.if (REMAP)
.print "remapping enabled"
.endif

.if (VECTREMAPPED)
.print "Vectors at start of RAM"
.else
.print "Vectors at start of Code"
.endif

  .equ AIC_IVR,         (256)
  .equ AIC_FVR,         (260)
  .equ AIC_EOICR,       (304)
  .equ AT91C_BASE_AIC,  (0xFFFFF000)

/*---------------------------------------------------------------------- 
--------
//*- Exception vectors
//*--------------------
//*- These vectors can be read at address 0 or at RAM address
//*- They ABSOLUTELY requires to be in relative addresssing mode in
order to
//*- guarantee a valid jump. For the moment, all are just looping.
//*- If an exception occurs before remap, this would result in an
infinite loop.
//*- To ensure if a exeption occurs before start application to infinite
loop.
//*--------------------------------------------------------------------- 
---------*/

.if (VECTREMAPPED)
.print "Vectors in section .vectmapped -> .data"
.section .vectmapped, "ax"
.else
.print "Vectors in section .vectorg -> .text"
.section .vectorg, "ax"
.endif

      LDR     PC,Reset_Addr    /* 0x00 Reset handler */
      LDR     PC,Undef_Addr    /* 0x04 Undefined Instruction */
      LDR     PC,SWI_Addr      /* 0x08 Software Interrupt */
      LDR     PC,PAbt_Addr    /* 0x0C Prefetch Abort */
      LDR     PC,DAbt_Addr    /* 0x10 Data Abort */
      NOP                     /* 0x14 reserved  */
      LDR     PC,IRQ_Addr      /* 0x18 IRQ */
fiqvec:                                 /* 0x1c FIQ */
/*---------------------------------------------------------------------- 
--------
//*- Function             : FIQ_Handler_Entry
//*- Treatments           : FIQ Controller Interrupt Handler.
//*- Called Functions     : AIC_FVR[interrupt]
//*--------------------------------------------------------------------- 
---------*/

FIQ_Handler_Entry:

/*- Switch in SVC/User Mode to allow User Stack access for C code   */
/* because the FIQ is not yet acknowledged*/

/*- Save and r0 in FIQ_Register */
            mov         r9,r0
            ldr         r0 , [r8, #AIC_FVR]
            msr         CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC

/*- Save scratch/used registers and LR in User Stack */
            stmfd       sp!, { r1-r3, r12, lr}

/*- Branch to the routine pointed by the AIC_FVR */
            mov         r14, pc
            bx          r0

/*- Restore scratch/used registers and LR from User Stack */
            ldmia       sp!, { r1-r3, r12, lr}

/*- Leave Interrupts disabled and switch back in FIQ mode */
            msr         CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ

/*- Restore the R0 ARM_MODE_SVC register */
            mov         r0,r9

/*- Restore the Program Counter using the LR_fiq directly in the PC */
            subs        pc,lr,#4

/* end of fiqhandler */

Reset_Addr:       .word     InitReset
Undef_Addr:       .word     Undef_Handler
/* SWI_Addr:         .word     SWI_Handler */
SWI_Addr:         .word     SoftwareInterruptASM      /* in
swi_handler.S */
PAbt_Addr:        .word     PAbt_Handler
DAbt_Addr:        .word     DAbt_Handler
IRQ_Addr:         .word     IRQ_Handler_Entry

Undef_Handler:  B       Undef_Handler
/* SWI_Handler:    B       SWI_Handler */
PAbt_Handler:   B       PAbt_Handler
DAbt_Handler:   B       DAbt_Handler


        .arm
        .section .init, "ax"
        .global _startup
        .func   _startup
_startup:
reset:

.if (VECTREMAPPED)
/* mthomas: Dummy used during startup */
        LDR PC,=Reset_Addr_F
        NOP
        NOP
        NOP
        NOP
        NOP /*.word 0xdeadbeef*/ /* Reserved Address */
        NOP
        NOP
Reset_Addr_F:       .word     InitReset
.endif

.RAM_TOP:
  .word  __TOP_STACK

InitReset:

/*---------------------------------------------------------------------- 
--------
/*- Remapping
/*---------------------------------------------------------------------- 
--------*/
.if (VECTREMAPPED)
    .print "RCR setting for remapping enabled"
    .equ    MC_BASE,0xFFFFFF00  /* MC Base Address */
    .equ    MC_RCR, 0x00        /* MC_RCR Offset */


    /* store first word in RAM into r4 */
    ldr r0,=__FIRST_IN_RAM
    ldr r4,[r0]
    /* load value at address 0 into R2 */
    ldr r1,=0x00000000
    ldr r2,[r1]
    /* xor value from address 0 (flip all bits), store in R3 */
    ldr r3,=0xffffffff
    eor r3, r2, r3
    /* write xored value to first word in RAM
    if already remapped this will also change
    the value at 0 */
    str r3,[r0]
    /* load from address 0 again into R3 */
    ldr r3,[r1]
    /* restore first value in RAM */
    str r4,[r0]

    /* compare */
    cmp r3, r2
    bne already_remapped

    /* if both values have been equal the change of the
    RAM-value had no effect on the value at 0x00000000
    so we are not remapping yet -> remap now: */
    LDR     R0, =MC_BASE
    MOV     R1, #1
    STR     R1, [R0, #MC_RCR]

already_remapped:
.endif


/*---------------------------------------------------------------------- 
--------
/*- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit
/*---------------------------------------------------------------------- 
--------*/
            .extern   AT91F_LowLevelInit
/*- minumum C initialization */
/*- call  AT91F_LowLevelInit( void) */

            ldr     sp, .RAM_TOP            /* temporary stack in
internal RAM (**) */
/*--Call Low level init function in ABSOLUTE through the Interworking
*/
            ldr     r0,=AT91F_LowLevelInit
            mov     lr, pc
            bx      r0
/*---------------------------------------------------------------------- 
--------
//*- Stack Sizes Definition
//*------------------------
//*- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when
using
//*- the vectoring. This assume that the IRQ management.
//*- The Interrupt Stack must be adjusted depending on the interrupt
handlers.
//*- Fast Interrupt not requires stack If in your application it
required you must
//*- be definehere.
//*- The System stack size is not defined and is limited by the free
internal
//*- SRAM.
//*--------------------------------------------------------------------- 
---------*/

/*---------------------------------------------------------------------- 
--------
//*- Top of Stack Definition
//*-------------------------
//*- Interrupt and Supervisor Stack are located at the top of internal
memory in
//*- order to speed the exception handling context saving and restoring.
//*- ARM_MODE_SVC (Application, C) Stack is located at the top of the
external memory.
//*--------------------------------------------------------------------- 
---------*/

          .EQU    IRQ_STACK_SIZE,    (3*8*4)
          .EQU    FIQ_STACK_SIZE,    (3*8*4)
          .EQU    ARM_MODE_FIQ,       0x11
          .EQU    ARM_MODE_IRQ,       0x12
          .EQU    ARM_MODE_SVC,       0x13

          .EQU    I_BIT,              0x80
          .EQU    F_BIT,              0x40

/*---------------------------------------------------------------------- 
--------
//*- Setup the stack for each mode
//*-------------------------------*/
                mov     r0, sp /* see (**) */

/*- Set up Fast Interrupt Mode and set FIQ Mode Stack*/
                msr     CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
                mov    sp, r0
                sub    r0, r0, #FIQ_STACK_SIZE
/*- Init the FIQ register*/
                ldr     r8, =AT91C_BASE_AIC

/*- Set up Interrupt Mode and set IRQ Mode Stack*/
                msr     CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
                mov     sp, r0                     /* Init stack IRQ */
                sub     r0, r0, #IRQ_STACK_SIZE

/*- Set up Supervisor Mode and set Supervisor Mode Stack*/
//        /* start with INT and FIQ enabled */
//        msr     CPSR_c, #ARM_MODE_SVC

        /* start with INT and FIQ disabled */
        msr     CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT

        mov     sp, r0                     /* Init stack Sup */


/*- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode
Stack*/

/* Relocate .data section (Copy from ROM to RAM)
   This will also copy the .vectmapped and .fastrun */
                LDR     R1, =_etext
                LDR     R2, =_data
                LDR     R3, =_edata
LoopRel:        CMP     R2, R3
                LDRLO   R0, [R1], #4
                STRLO   R0, [R2], #4
                BLO     LoopRel

/* Clear .bss section (Zero init) */
                MOV     R0, #0
                LDR     R1, =__bss_start__
                LDR     R2, =__bss_end__
LoopZI:         CMP     R1, R2
                STRLO   R0, [R1], #4
                BLO     LoopZI


/* call C++ constructors of global objects */
    LDR   r0, =__ctors_start__
    LDR   r1, =__ctors_end__
ctor_loop:
    CMP   r0, r1
    BEQ   ctor_end
    LDR   r2, [r0], #4
    STMFD   sp!, {r0-r1}
    MOV   lr, pc
/*    MOV   pc, r2 */
    BX r2 /* mthomas 8/2006 */
    LDMFD   sp!, {r0-r1}
    B     ctor_loop
ctor_end:


/* call main() */
    ldr  lr,=exit
    ldr  r0,=main
    bx  r0

        .size   _startup, . - _startup
        .endfunc

/* "exit" dummy added by mthomas to avoid sbrk write read etc. needed
   by the newlib default "exit" */
        .global exit
        .func   exit
exit:
        b    .
        .size   exit, . - exit
        .endfunc




/*---------------------------------------------------------------------- 
--------
//*- Manage exception
//*---------------
//*- This module The exception must be ensure in ARM mode
//*--------------------------------------------------------------------- 
---------
//*--------------------------------------------------------------------- 
---------
//*- Function             : IRQ_Handler_Entry
//*- Treatments           : IRQ Controller Interrupt Handler.
//*- Called Functions     : AIC_IVR[interrupt]
//*--------------------------------------------------------------------- 
---------*/

.if (VECTREMAPPED)
.print "IRQ_Handler_Entry in section .fastrun -> .data"
.section .fastrun, "ax"
.else
.print "IRQ_Handler_Entry in section .init -> .text"
.section .init, "ax"
.endif

        .global IRQ_Handler_Entry
        .func   IRQ_Handler_Entry
IRQ_Handler_Entry:
/*---- Adjust and save return address on the stack */
    sub     lr, lr, #4
    stmfd   sp!, {lr}

/*---- Save r0 and SPSR on the stack */
    mrs     r14, SPSR
    stmfd   sp!, {r0, r14}

/*---- Write in the IVR to support Protect mode */
/*---- No effect in Normal Mode */
/*---- De-assert NIRQ and clear the source in Protect mode */
    ldr     r14, =AT91C_BASE_AIC
    ldr     r0, [r14, #AIC_IVR]
    str     r14, [r14, #AIC_IVR]

/*---- Enable nested interrupts and switch to Supervisor mode */
    msr     CPSR_c, #ARM_MODE_SVC

/*---- Save scratch/used registers and LR on the stack */
    stmfd   sp!, {r1-r3, r12, r14}

/*---- Branch to the routine pointed by AIC_IVR */
    mov     r14, pc
    bx      r0

/*---- Restore scratch/used registers and LR from the stack */
    ldmia   sp!, {r1-r3, r12, r14}

/*---- Disable nested interrupts and switch back to IRQ mode */
    msr     CPSR_c, #I_BIT | ARM_MODE_IRQ

/*---- Acknowledge interrupt by writing AIC_EOICR */
    ldr     r14, =AT91C_BASE_AIC
    str     r14, [r14, #AIC_EOICR]

/*---- Restore SPSR and r0 from the stack */
    ldmia   sp!, {r0, r14}
    msr     SPSR_cxsf, r14

/*---- Return from interrupt handler */
    ldmia   sp!, {pc}^

        .size   IRQ_Handler_Entry, . - IRQ_Handler_Entry
        .endfunc


/*---------------------------------------------------------------
//* ?EXEPTION_VECTOR
//* This module is only linked if needed for closing files.
//*---------------------------------------------------------------*/
        .global AT91F_Default_FIQ_handler
        .func   AT91F_Default_FIQ_handler
AT91F_Default_FIQ_handler:
            b     AT91F_Default_FIQ_handler
        .size   AT91F_Default_FIQ_handler, . - AT91F_Default_FIQ_handler
        .endfunc

        .global AT91F_Default_IRQ_handler
        .func   AT91F_Default_IRQ_handler
AT91F_Default_IRQ_handler:
            b     AT91F_Default_IRQ_handler
        .size   AT91F_Default_IRQ_handler, . - AT91F_Default_IRQ_handler
        .endfunc

        .global AT91F_Spurious_handler
        .func   AT91F_Spurious_handler
AT91F_Spurious_handler:
            b     AT91F_Spurious_handler
        .size   AT91F_Spurious_handler, . - AT91F_Spurious_handler
        .endfunc

        .end

======================================================================== 
===


In the function "IRQ_Handler_Entry:" write

/*---- Save r0 and SPSR on the stack */
    mrs     r14, SPSR
    stmfd   sp!, {r0, r14}

.
.
.
/*---- Enable nested interrupts and switch to Supervisor mode */
    msr     CPSR_c, #ARM_MODE_SVC

.
.
.
So, I think I can use nested interrupts.
The question is the nested interrupts is default turn-on or turn-off?


For example the IRQ PIT function- I want to interrupt this function by
interrupt-function with highter priority.

void systime_isr(void)         /* System Interrupt Handler */
{

  //INTenable(); <---------- any function to turn on interrupt ???


        volatile unsigned long status;
  static int cnt, cnt2;

  // Interrupt Acknowledge
  status = AT91C_BASE_PITC->PITC_PIVR;

  // any code
        //


}
Do I have  to turn on (re-enable) the interrupts or it has done default?

Can I use this function to re-enable interrupts ??

#define MY_SWI_CALL_RES(MY_SWI_ID, MY_RESULT) \
  asm volatile( \
  "swi %a1     \n\t" \
  "mov %0,r0  \n\t" \
  : "=r" (MY_RESULT) : "I" (MY_SWI_ID) : "r0", "lr" )

static inline unsigned long IntEnable(void) {
  unsigned long res;
  MY_SWI_CALL_RES(SWI_NUM_IRQ_EN, res);
  return res;
}

regards
/Adam

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.