This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Global Interrupt Disable

Hi,

to protect a small critical section it is sometimes usual to have all interrupts blocked (except NMI and Reset). Normally this looks like

- store the old Global Interrupt State
- disable interrupts

  [critical section]

- restore the old Global Interrupt State back.

How can I do this on Stellaris ARM LM4F processor?

Sure, I've thousands of single disables but I'm searching for the global one. Somewhere I've read that this register is called "PRIMASK" with the values 0 for enable and 1 for disable. What is the address? And why it is undocumented?

  • Might this do the job for you?  (a true copy - from current SW-DRL-UG)

    16.2.2.4 IntMasterDisable

    Description:
    This function prevents the processor from receiving interrupts. This function does not affect
    the set of interrupts enabled in the interrupt controller; it just gates the single interrupt from the
    controller to the processor.

  • Hi,

    I agree with cb1, but I can add some more.Here is an excerpt from something found on internet and copied on my archives. The author (PK) maybe will recognize this:

    > Critical sections can be avoided in three ways: BASEPRI, exclusives,
    > bit-band. BASEPRI allows masking all interrupts of a specified priority and
    > below (0 is highest, so BASEPRI=5 masks 5, 6, and 7). For example, if the top
    > 4 priority interrupts (0-3) do not use memory objects, then the critical
    > section on memory object manipulation would mask off only the next 4
    > priorities by writing a 4. To make BASEPRI even easier, a register called
    > BASEPRI_MAX is written to - this only raises the priority mask and does not
    > lower. So, you do not have to use "if (critsect_pri < BASEPRI) BASEPRI =
    > critsect_pri;". Instead, you just set BASEPRI_MAX and it will only set if a
    > lower number (you restore by writing the saved value to BASEPRI).
    > Additionally, you can avoid use of critical sections using Exclusives. This
    > is LDREX and STREX. This makes it possible to read a value from memory (byte,
    > half, word, or bit), modify it, and then write it back; if another task or an
    > ISR has written it between the load and store, the store will not happen and
    > you will be told that via a register. So, you use a spin-lock model with no
    > extra test-and-set location. Exclusives can be used for FIFOs (e.g. from ISR
    > to tasks or tasks to ISRs) as non-locking and non-blocking models, as well as
    > for many other shared resources. Finally the bit-band can be used. Bit-band
    > maps 1MB of SRAM and 1MB of peripheral into 32MB of addressable bits (each).
    > So, for each word in the SRAM, you have 32 words in the bit-band space; these
    > each access 1 bit of the word (you can also access by byte or half, but since
    > a 32-bit register model, access by word is convenient). The bit band not only
    > allows for memory savings (when you use boolean data), but can be used for
    > critical data as well. Writes to the bit-band area are atomic in HW (implicit
    > RMW of word cannot be split by an ISR). So, bits can be used for population
    > and claim bits as well as requests. For example, ISRs can not only set
    > PendSV, but also set tasks-to-wake via bit band. Then, the PendSV handler can
    > read by word (or DWORD) to see if any tasks are waiting to be woken (or have
    > work to do). To find the 1st task to run, you can use the CLZ instruction;
    > this is count-leading-zeros. So, it will return the MSb which is 1. If you
    > need the LSb, you use RBIT and then CLZ.

    If you need to know more, then ARM documentation will be the first source, the second one can be a look to FreeRTOS.

    Petrei 

  • Thanks for the immediate answer.

    If I would use the ROM_IntMasterDisable() function then tis function will change something inside the processor. What? That was my question.

    The definition is as follows:

    #if defined(TARGET_IS_TEMPEST_RB1) || \
        defined(TARGET_IS_TEMPEST_RC1) || \
        defined(TARGET_IS_TEMPEST_RC3) || \
        defined(TARGET_IS_TEMPEST_RC5) || \
        defined(TARGET_IS_FIRESTORM_RA2) || \
        defined(TARGET_IS_BLIZZARD_RA1) || \
        defined(TARGET_IS_BLIZZARD_RA2)
    #define ROM_IntMasterDisable                                                  \
            ((tBoolean (*)(void))ROM_INTERRUPTTABLE[2])
    #endif

    My prototype is a board that contains (will contain) the processor LM4F232. Can someone tell me whether this will be a TEMPEST or a FIRESTORM? What I need is a simple address which is independent from TI's families of eval boards.

    I would also be happy to use the ROM library functions. But how? See above - it's impossible.

  • Hi,

    You need to add "TARGET_IS_BLIZZARD_RA1" to the predefined symbols in compiler options. 

    One thing more: to have an idea what is inside a function, look in the driverlib at the version without ROM_ prefix - in your case is in cpu.c file. 

    Petrei

  • Thanks Petrei,

    I disassembled this piece of code in ROM and yes, it is interesting. There are two separate ARM thumb orders for this purpose, CPSID and CPSIE.

    Step by step all these mysteries are unveiled. By the today's praxis I learned also how to call a ROM function. Thanks, it works now.