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
No data
Reply
  • Hi John,

    Thanks for the reply, but I did not directly access these registers.

    Maybe you were confused by the second code section I posted... that is the assembly output of the compiler, not my code. Note that the code I posted in the first code section is commented out with semi-colons, and the corresponding assembly code follows.

    Anyone else?

    --
    George Andrew Brindeiro
    Robotron Automation and Technology

Children
  • Sorry for my limited knowledge.

    I did not notice this:
    http://www.keil.com/support/man/docs/armcc/armcc_Chdgbbia.htm
    There is no virtual Processor Status Register (PSR). Any references to the PSR are always to the physical PSR.

    Hope my second try would be better.
    infocenter.arm.com/.../index.jsp

    Note that CPSR_c is used instead of CPSR in the MSR instruction, to avoid altering the condition code flags.
    A better implementation is:

    /* NewState=1 will enable IRQ, NewState=0 will disable IRQ */
    /* ARM core must be in a privileged mode, e.g. supervisor  */
    void ChangeIRQ(unsigned int NewState)
    {
        int my_cpsr;
    
        __asm
        {
        MRS my_cpsr, CPSR                        /* get current program status */
        ORR my_cpsr, my_cpsr, #0x80              /* set IRQ disable bit flag */
        BIC my_cpsr, my_cpsr, NewState, LSL #7   /* reset IRQ bit with new value */
        MSR CPSR_c, my_cpsr                      /* store updated program status */
        }
    }
    


    which compiles into:

    ChangeIRQ
        MRS r1,CPSR
        ORR r1,r1,#0x80
        BIC r0,r1,r0,LSL #7
        MSR CPSR_c,r0
        MOV pc,lr
    

  • Hi,

    I had to make some modifications to the code, but essentially it worked. For instance, that code assumes that the program is in Privileged Mode. In that case, I have to change the SPSR and not the CPSR, if I want interrupts to be enabled/disabled in User Mode.

    I added that code with some modifications to my SWI code and the assembler output is consistent (the inline assembly part is showing in the code). Whenever I am able to test on the board, I'll post the final SWI code.

    Thanks for the link!
    --
    George Andrew Brindeiro
    Robotron Automation and Technology