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

Atomic sections of code

There are several possibilities to protect critical sections of code from being interrupted:

1. Temporarily disabling and enabling interrupts:

void function(void)
{
    EA = 0;
    // atomic_section...
    EA = 1;
}

Disadvantage:
This will change the status of EA if interrupts had not been enabled before.

2. Saving and restoring EA:
http://www.keil.com/forum/1080/

bit ea_saved;

void function(void)
{
    ea_saved = EA;
    EA = 0;
    // atomic_section...
    EA = ea_saved;
}

Disadvantage: if this code can be interrupted between ea_saved=EA and EA=0. If the interrupt service routine decides to disable interrupts, the interrupts will become enabled again when doing EA=ea_saved after the critical section.

3. Using #pragma disable
http://www.keil.com/support/man/docs/c51/c51_disable.htm
http://www.keil.com/forum/1080/

#pragma disable
void function (void)
{
    // atomic_section...
}

Advantage:
Avoids the above problem because the JBC opcode is used to evaluate the current state of EA and clear EA with the same instruction:

; FUNCTION function (BEGIN)
          SETB    C
          JBC     EA,IS_CLEARED
          CLR     C
IS_CLEARED:
          PUSH    PSW

    // atomic_section...

          POP     PSW
          MOV     EA,C
          RET
; FUNCTION function (END)

Disadvantage:
Can be applied to whole functions only.
Requires 1 Byte on the stack.

4. Combination of 2. and 3.

#include <intrins.h>

#define ATOMIC_SECTION_BEGIN    { ea_saved = 1; if (!(_testbit_(EA))) { ea_saved = 0; } }
#define ATOMIC_SECTION_END      { EA = ea_saved; }
#define INTERRUPTS_DISABLE      { EA = 0; ea_saved = 0; }
#define INTERRUPTS_ENABLE       { EA = 1; ea_saved = 1; }

bit ea_saved;

void function(void)
{

ATOMIC_SECTION_BEGIN

    // atomic_section...

ATOMIC_SECTION_END
}

This results in

ATOMIC_SECTION_BEGIN
        SETB    ea_saved
        JBC     EA,?C0007?HB
        CLR     ea_saved

?C0007?HB:

    // atomic_section...

ATOMIC_SECTION_END
        MOV     C,ea_saved
        MOV     EA,C

Advantages:
Pure source code, no inline assembly.
Atomic section can remain inline, no sub-function required.
Only one bit for status saving required.

Parents
  • thr OP:

    Erik, when you write a one-line reply to a 100-line posting, your reply only relates to one aspect of one of its paragraphs, you really should leave some indication what you're referring to. Otherwise how was anyone (e.g. me) supposed to know that "no need" referred to that small shred, instead of the whole posting?

    Human language creates enough unavoidable misunderstandings --- no need to make it worse by being obscure.

Reply
  • thr OP:

    Erik, when you write a one-line reply to a 100-line posting, your reply only relates to one aspect of one of its paragraphs, you really should leave some indication what you're referring to. Otherwise how was anyone (e.g. me) supposed to know that "no need" referred to that small shred, instead of the whole posting?

    Human language creates enough unavoidable misunderstandings --- no need to make it worse by being obscure.

Children
No data