Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() are always used in pair to wrap critical sections of code as shown below:

Code Block
CaptionTextNO NAME
{
    .
    .
    OS_ENTER_CRITICAL();
    /* µC/OS-II critical code section */
    OS_EXIT_CRITICAL();
    .
    .
}

...

The second way to implement OS_ENTER_CRITICAL() is to save the interrupt disable status onto the stack and then disable interrupts. OS_EXIT_CRITICAL() is simply implemented by restoring the interrupt status from the stack. Using this scheme, if you call a µC/OS-II service with interrupts either enabled or disabled, the status is preserved across the call. In other words, interrupts would be enabled after the call if they were enabled before the call and, interrupts would be disabled after the call if they were disabled before the call. Be careful when you call a µC/OS-II service with interrupts disabled because you are extending the interrupt latency of your application. The pseudo code for these macros is shown below:

Code Block
CaptionTextNO NAME
#define OS_ENTER_CRITICAL()   \
        asm(" PUSH   PSW")    \
        asm(" DI")
#define OS_EXIT_CRITICAL()    \
        asm(" POP    PSW")

...

Because I don’t know what the compiler functions are (there is no standard naming convention), the µC/OS-II macros are used to encapsulate the functionality as follows:

Code Block
#define OS_ENTER_CRITICAL()    \
  cpu_sr = get_processor_psw(); \
  disable_interrupts();
#define OS_EXIT_CRITICAL()     \
  set_processor_psw(cpu_sr);

Tasks

Alternatively, the task can delete itself upon completion as shown in Listing 3.3. Note that the task code is not actually deleted; µC/OS-II simply doesn’t know about the task anymore, so the task code will not run. Also, if the task calls OSTaskDel(), the task never returns.

...