This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

enable_irq()/disable_irq() in ARMCC V4

Hi everyone,

I have posted to this forum a couple months ago about using the enable_irq()/disable_irq() instruction intrinsics in RealView Compiler (ARMCC V4.0.0.728). In that occasion, I set up two software interrupts for calling such intrinsics, as they only have the intended effect when not in User Mode.

Just now, though, I realized that interrupts were not being disabled. I know for a fact that my SWI are set up appropriately, because they change the value of a flag I set up. Does anyone have any clue what could be happening? Documentation seems to be pretty clear about the fact that one enters supervisor mode during SWI, and that would be appropriate for enabling/disabling interrupts, but I must be missing something.

Relevant source code

void __SWI_8 (void)
{
  __enable_irq();
  __enable_fiq();
  interrupts_enabled = 1;
}

void __SWI_9 (void)
{
  __disable_irq();
  __disable_fiq();
  interrupts_enabled = 0;
}

Relevant links

Instruction Intrinsics
http://www.keil.com/support/man/docs/armcc/armcc_chdfgfab.htm

disable_irq()
www.keil.com/.../armccref_CJAFBCBB.htm

enable_irq()
www.keil.com/.../armccref_CJAEAEHA.htm

ARMCC: MODIFY IRQ FLAG TO ENABLE/DISABLE INTERRUPTS (RealView Compiler V3)
http://www.keil.com/support/docs/3229.htm

Thanks in advance,
--
George Andrew Brindeiro
Robotron Automation and Technology

Parents
  • I tried doing the following:

    void __SWI_8 (void)
    {
      //__enable_irq();
      //__enable_fiq();
      int temp;
    
       __asm
      {
         MRS     temp, SPSR_cxsf        // Get SPSR
         ORR     temp, temp, #0xC0      // Set IRQ/FIQ flag to disable
         MSR     SPSR_cxsf, temp        // Set SPSR
      }
    
      interrupts_enabled = 1;
    }
    
    void __SWI_9 (void)
    {
      //__disable_irq();
      //__disable_fiq();
      int temp;
    
      __asm
      {
         MRS     temp, SPSR_cxsf        // Get SPSR
         BIC     temp, temp, #0xC0      // Clear IRQ/FIQ flag to enable
         MSR     SPSR_cxsf, temp        // Set SPSR
      }
    
      interrupts_enabled = 0;
    }
    

    This compiles, and I thought it would work, but obviously it doesn't...

    I checked the output of the compiler, I don't see any reference (except for comments) to my asm code. Specifically, this is what I get:

                      __SWI_8 PROC
    ;;;49
    ;;;50     void __SWI_8 (void)
    000084  e59f1040          LDR      r1,|L1.204|
    ;;;51     {
    ;;;52       //__enable_irq();
    ;;;53       //__enable_fiq();
    ;;;54       int temp;
    ;;;55
    ;;;56        __asm
    ;;;57       {
    ;;;58          MRS     temp, SPSR             // Get SPSR
    ;;;59          ORR     temp, temp, #0xC0      // Set IRQ/FIQ flag to disable
    ;;;60          MSR     SPSR, temp             // Set SPSR
    ;;;61       }
    ;;;62
    ;;;63       interrupts_enabled = 1;
    000088  e3a00001          MOV      r0,#1
    00008c  e5c10000          STRB     r0,[r1,#0]  ; interrupts_enabled
    ;;;64     }
    000090  e12fff1e          BX       lr
    ;;;65
                              ENDP
    
                      __SWI_9 PROC
    ;;;66     void __SWI_9 (void)
    000094  e59f1030          LDR      r1,|L1.204|
    ;;;67     {
    ;;;68       //__disable_irq();
    ;;;69       //__disable_fiq();
    ;;;70       int temp;
    ;;;71
    ;;;72       __asm
    ;;;73       {
    ;;;74          MRS     temp, SPSR             // Get SPSR
    ;;;75          BIC     temp, temp, #0xC0      // Clear IRQ/FIQ flag to enable
    ;;;76          MSR     SPSR, temp             // Set SPSR
    ;;;77       }
    ;;;78
    ;;;79       interrupts_enabled = 0;
    000098  e3a00000          MOV      r0,#0
    00009c  e5c10000          STRB     r0,[r1,#0]  ; interrupts_enabled
    ;;;80     }
    0000a0  e12fff1e          BX       lr
    ;;;81
                              ENDP
    

    Any tips on where I'm wrong? This should be relatively straightforward.

    Thanks,
    --
    George Andrew Brindeiro
    Robotron Automation and Technology

Reply
  • I tried doing the following:

    void __SWI_8 (void)
    {
      //__enable_irq();
      //__enable_fiq();
      int temp;
    
       __asm
      {
         MRS     temp, SPSR_cxsf        // Get SPSR
         ORR     temp, temp, #0xC0      // Set IRQ/FIQ flag to disable
         MSR     SPSR_cxsf, temp        // Set SPSR
      }
    
      interrupts_enabled = 1;
    }
    
    void __SWI_9 (void)
    {
      //__disable_irq();
      //__disable_fiq();
      int temp;
    
      __asm
      {
         MRS     temp, SPSR_cxsf        // Get SPSR
         BIC     temp, temp, #0xC0      // Clear IRQ/FIQ flag to enable
         MSR     SPSR_cxsf, temp        // Set SPSR
      }
    
      interrupts_enabled = 0;
    }
    

    This compiles, and I thought it would work, but obviously it doesn't...

    I checked the output of the compiler, I don't see any reference (except for comments) to my asm code. Specifically, this is what I get:

                      __SWI_8 PROC
    ;;;49
    ;;;50     void __SWI_8 (void)
    000084  e59f1040          LDR      r1,|L1.204|
    ;;;51     {
    ;;;52       //__enable_irq();
    ;;;53       //__enable_fiq();
    ;;;54       int temp;
    ;;;55
    ;;;56        __asm
    ;;;57       {
    ;;;58          MRS     temp, SPSR             // Get SPSR
    ;;;59          ORR     temp, temp, #0xC0      // Set IRQ/FIQ flag to disable
    ;;;60          MSR     SPSR, temp             // Set SPSR
    ;;;61       }
    ;;;62
    ;;;63       interrupts_enabled = 1;
    000088  e3a00001          MOV      r0,#1
    00008c  e5c10000          STRB     r0,[r1,#0]  ; interrupts_enabled
    ;;;64     }
    000090  e12fff1e          BX       lr
    ;;;65
                              ENDP
    
                      __SWI_9 PROC
    ;;;66     void __SWI_9 (void)
    000094  e59f1030          LDR      r1,|L1.204|
    ;;;67     {
    ;;;68       //__disable_irq();
    ;;;69       //__disable_fiq();
    ;;;70       int temp;
    ;;;71
    ;;;72       __asm
    ;;;73       {
    ;;;74          MRS     temp, SPSR             // Get SPSR
    ;;;75          BIC     temp, temp, #0xC0      // Clear IRQ/FIQ flag to enable
    ;;;76          MSR     SPSR, temp             // Set SPSR
    ;;;77       }
    ;;;78
    ;;;79       interrupts_enabled = 0;
    000098  e3a00000          MOV      r0,#0
    00009c  e5c10000          STRB     r0,[r1,#0]  ; interrupts_enabled
    ;;;80     }
    0000a0  e12fff1e          BX       lr
    ;;;81
                              ENDP
    

    Any tips on where I'm wrong? This should be relatively straightforward.

    Thanks,
    --
    George Andrew Brindeiro
    Robotron Automation and Technology

Children
  • http://www.keil.com/support/man/docs/armcc/armcc_Chdgddcj.htm

    Restrictions on inline assembly operations

    Some low-level features that are available in the ARM assembler armasm, such as branching and writing to PC, are not supported.

    Registers such as r0-r3, sp, lr, and the NZCV flags in the CPSR must be used with caution. If you use C or C++ expressions, these might be used as temporary registers and NZCV flags might be corrupted by the compiler when evaluating the expression. See Virtual registers.

    The pc, lr, and sp registers cannot be explicitly read or modified using inline assembly code because there is no direct access to any physical registers. However, you can use the following intrinsics described in the Compiler Reference Guide to access these registers: