...
OS_ENTER_CRITICAL()
and OS_EXIT_CRITICAL()
are always used in pair to wrap critical sections of code as shown below:
Code Block |
---|
{
.
.
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:
...
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.
...