Nested interrupt On - Off

Guest #1172284
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

Reply

Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.

Formatting
  • [c]C-Code[/c]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]
  • [[Title]] – link to an article
  • Link to another post: right-click its post ID (#8078628), copy the address, paste it into the text

More about formatting

Post long source code as an attachment, not in the text.

Already registered? Log in

Not shown to anyone. We send you a link; your post appears once you confirm it there.

By submitting you create a free account and accept the terms of use.