<div dir="ltr">I attach a piece of code from the file $(RTEMS-4.7.3)/c/src/lib/<div dir="ltr">libbsp/arm/shared/irq/irq_asm.S,<br>its the ISR handler of ARM core.<br><br>In the line 59 to 62, it judge whether the arm core is in irq mode,<br>

if so - exit the isr handler and return to normal program<br>else - go on to do some more work and return<br><br>But its impossible to call this function in normal program<br>except an interrupt really happen.<br><br>If so, the arm core is sure to be in the irq mode,<br>

the code from line 63 to 128 seems would never be executed.<br><br>Could the maintainer of ARM explain it?<br>I was so confused.<br>Thanks.<br><br>**********************************************************************************<br>


24            .globl _ISR_Handler<br>  25    _ISR_Handler:<br>  26            stmdb   sp!, {r0, r1, r2, r3, r12}   /* save regs on INT stack */<br>  27            stmdb   sp!, {lr}               /*    now safe to call C funcs */<br>

  28    <br>  29    /* one nest level deeper */<br>  30            ldr     r0, =_ISR_Nest_level<br>  31            ldr     r1, [r0]<br>  32            add     r1, r1,#1<br>  33            str     r1, [r0]<br>  34    <br>
  35    /* disable multitasking */<br>
  36            ldr     r0, =_Thread_Dispatch_disable_level<br>  37            ldr     r1, [r0]<br>  38            add     r1, r1,#1<br>  39            str     r1, [r0]<br>  40    <br>  41    /* BSP specific function to INT handler */<br>

  42            /* FIXME: I'm not sure why I can't save just r12. I'm also  */<br>  43            /*     not sure which of r1-r3 are important.               */<br>  44            bl      ExecuteITHandler<br>
  45    <br>
  46    /* one less nest level  */<br>  47            ldr     r0, =_ISR_Nest_level<br>  48            ldr     r1, [r0]<br>  49            sub     r1, r1,#1<br>  50            str     r1, [r0]<br>  51    <br>  52    /* unnest multitasking */<br>

  53            ldr     r0, =_Thread_Dispatch_disable_level<br>  54            ldr     r1, [r0]<br>  55            sub     r1, r1,#1<br>  56            str     r1, [r0]<br>  57    <br>  58    /* check to see if we interrupted nd INT (with FIQ?) */<br>

  59            mrs   r0, spsr<br>  60            and   r0, r0, #0x1f<br>  61            cmp   r0, #0x12        /* is it INT mode? */<br>  62            beq   exitit<br>  63    <br>  64    /* If thread dispatching is disabled, exit */<br>

  65            cmp     r1, #0<br>  66            bne     exitit<br>  67    <br>  68    /* If a task switch is necessary, call scheduler */<br>  69            ldr     r0, =_Context_Switch_necessary<br>  70            ldr     r1, [r0]<br>

  71            cmp     r1, #0<br>  72    <br>  73            /* since bframe is going to clear _ISR_Signals_to_thread_executing, */<br>  74            /*    we need to load it here */<br>  75            ldr     r0, =_ISR_Signals_to_thread_executing<br>

  76            ldr     r1, [r0]<br>  77            bne     bframe<br>  78    <br>  79    /* If a signals to be sent (_ISR_Signals_to_thread_executing != 0),        */<br>  80    /*  call scheduler */<br>  81            cmp     r1, #0<br>

  82            beq     exitit<br>  83    <br>  84    /* _ISR_Signals_to_thread_executing = FALSE */<br>  85            mov     r1, #0<br>  86            str     r1, [r0]<br>  87    <br>  88    bframe:<br>  89    <br>  90    /* Now we need to set up the return from this ISR to be _ISR_Dispatch */<br>

  91    /* To do that, we need to save the current lr_int and spsr_int on the */<br>  92    /* SVC stack                                                          */<br>  93            mrs     r0, spsr<br>  94            ldmia   sp!, {r1}       /* get lr off stack */<br>

  95            stmdb   sp!, {r1}<br>  96            mrs     r2, cpsr<br>  97            orr     r3, r2, #0x1    /* change to SVC mode */<br>  98            msr     cpsr_c, r3<br>  99    <br> 100            /* now in SVC mode */<br>

 101            stmdb   sp!, {r0, r1}   /* put spsr_int and lr_int on SVC stack */<br> 102            msr     cpsr_c, r2      /* change back to INT mode */<br> 103    <br> 104            /* now in INT mode */<br> 105    <br>

 106            /* replace lr with address of _ISR_Dispatch */<br> 107            ldr     lr, =_ISR_Dispatch_p_4    /* On entry to an ISR, the lr is */<br> 108                                              /*    the return address + 4, so */<br>

 109                                              /*    we have to emulate that    */<br> 110            ldmia   sp!, {r1}                 /* out with the old          */<br> 111            stmdb   sp!, {lr}                 /*    in with the new (lr) */<br>

 112    <br> 113            orr     r0, r0, #0xc0<br> 114            msr     spsr, r0<br> 115    <br> 116    exitit:<br> 117            ldmia   sp!, {lr}                     /* restore regs from INT stack */<br> 118            ldmia   sp!, {r0, r1, r2, r3, r12}    /* restore regs from INT stack */<br>

 119            subs    pc, lr, #4                /* return */<br> 120    <br> 121            /* on entry to _ISR_Dispatch, we're in SVC mode */<br> 122            .globl _ISR_Dispatch<br> 123    _ISR_Dispatch:<br> 124            stmdb   sp!, {r0-r3, r12,lr}      /* save regs on SVC stack */<br>

 125                                              /*    (now safe to call C funcs) */<br> 126                                              /*    we don't save lr, since  */<br> 127                                              /*    it's just going to get   */<br>

 128                                              /*    overwritten              */<br>************************************************************************************************</div></div>