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();
    .
    .
}

Your application can also use OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() to protect your own critical sections of code. Be careful, however, because your application will crash (i.e. hang) if you disable interrupts before calling a service such as OSTimeDly() (see chapter 5). This happens because the task is suspended until time expires, but because interrupts are disabled, you would never service the tick interrupt! Obviously, all the PEND calls are also subject to this problem, so be careful. As a general rule, you should always call µC/OS-II services with interrupts enabled!

...

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")

Here, I’m assuming that your compiler will allow you to execute inline assembly language statements directly from your C code as shown above. You will need to consult your compiler documentation for this.

...

Some compiler provides you with extensions that allow you to obtain the current value of the PSW (Processor Status Word) and save it into a local variable declared within a C function. The variable can then be used to restore the PSW back as shown in listing 3.1 Below.

Listing 3.1 Saving and restoring the PSW

void Some_uCOS_II_Service (arguments)

{   
    OS_CPU_SR  cpu_sr      (1)
    
    
    .
    cpu_sr = get_processor_psw(); (2)
    disable_interrupts();  (3)
    .
    /* Critical section of code */      (4)
    .
    set_processor_psw(cpu_sr);   (5)
    .
}

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:

...

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:

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.

...