Skip to main content
Visitor II
September 4, 2007
Question

Enable/Disable Global Interrupts

  • September 4, 2007
  • 11 replies
  • 4403 views
Posted on September 04, 2007 at 20:02

Enable/Disable Global Interrupts

    This topic has been closed for replies.

    11 replies

    sjacksonAuthor
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:44

    I'm designing some code that has data that will be written to by an ISR and read by a non-ISR function. My main program needs to perform a few quick operations using this stored data and thus I need to ensure that the data is not overwritten by an ISR midstream. Thus I'd like a quick and easy way to globally disable and enable interrupts.

    Should I declare all members that will be accessed in this way ''volatile'' or can I use:

    Code:

    // Begin critical section

    SCU_AHBPeriphClockConfig(__VIC,DISABLE); // Disable all interrupts

    //Do stuff

    SCU_AHBPeriphClockConfig(__VIC,ENABLE); // Enable all interrupts

    Thanks!

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:44

    You could disable at core level

    vPortEnableInterrupts:

    STMDB SP!, {R0}

    MRS R0, CPSR

    BIC R0, R0, #0xC0

    MSR CPSR, R0

    LDMIA SP!, {R0}

    BX lr

    vPortDisableInterrupts:

    STMDB SP!, {R0}

    MRS R0, CPSR

    ORR R0, R0, #0xC0

    MSR CPSR, R0

    LDMIA SP!, {R0}

    BX lr

    you can also put this in inline asm if you wish.

    What compiler are you using?

    Most have inbuilt functions to do this, eg.

    __disable_interrupt();

    __enable_interrupt();

    Regards

    sjo

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:44

    Just to add to thread. I am also looking for a way to easily enable then disable interrupts.

    I am using:

    ARM/Thumb C/C++ Compiler, RVCT3.1 [Build 903] for uVision [Standard]

    From the documentation (Italics and bold are mine):

    The __disable_irq intrinsic can only be executed in privileged modes, that is, in non user modes. In User mode this intrinsic does not change the interrupt flags in the CPSR.

    So, I too need an alternate method to enable/disable interrupts.

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:44

    Um, the inability to enable/disable interrupts in USER mode is a feature of the ARM. There is no way around it, unless you switch to something like System or Supervisor modes.

    Why are you using USER mode for an embedded application? This would only apply if you were doing something like Linux, and the default on power up is SYSTEM anyways.

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:44

    In user mode the only way for enabling/disabling interrupts

    is to use software interupts (SWI).

    start from here:

    http://www.keil.com/support/docs/3229.htm

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:44

    question @lakata:

    - the application run in system mode

    - i use no SWI for enabling/disabling interrupts

    how can i sure that enabling/disabling interrupts

    is an atomic operation ?

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:44

    Hey lakata,

    Anything from within main( ) would be in User Mode. Hence, my concern with the ability to disable interrupts. My application does a fair amount of processing from within main (I'm not using any OS). Interrupts get generated and move data around. main executes a state machine, processing data as needed to move the state along.

    My goal is to not ever disable interrupts, but while debugging it sometimes helps.

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:44

    Your choices are above, they are good enough techniques for freertos, uclinux and ecos.

    Spen

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:44

    sjo's recommendations are atomic, as far as I know, although I would be hesitant to put any critical instructions immediately after writing to CPSR in case there is something funky with the ARM instruction pipeline.

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:44

    Why are you using USER mode in main()? If you are using the default STR library, main runs from SYS mode. Look at 91x_init.s and ignore the comments (I hate comments like this. Most of the 91x library is littered with bad comments that are flat out wrong or misleading).

    ; --- Now change to USR/SYS mode and set up User mode stack,

    MSR CPSR_c, #Mode_SYS ; IRQs & FIQs are now enabled

    LDR SP, = SFE(CSTACK) & 0xFFFFFFF8

    -Mark