First, some context: we're compiling our application with CCS compiler version 4.2.1 for an MSP430F5528. I have also tested this with version 4.3.3 and see the same behavior.
Our application uses a lightweight scheduler to manage the power state of the hardware. Tasks request service from an interrupt context, and it's the scheduler's responsibility to exit low power mode if appropriate. By design, the scheduler will only attempt to exit low power mode from an interrupt context.
To manage our low power state, we use methods similar to the following:
#include <intrinsics.h>
static void schedulerSleep(void)
{
_bis_SR_register(LPM3_bits);
_no_operation();
}
static void schedulerWakeup(void)
{
if (schedulerIsSleeping()) {
_bic_SR_register_on_exit(LPM3_bits);
_no_operation();
}
}
Again, I should reiterate that our design guarantees that schedulerIsSleeping() returns true iff called from an interrupt context.
This code does not compile. It fails with the error:
error #1358: intrinsic (_bic_SR_register_on_exit) only available within interrupt routines
Through some trial-and-error engineering, we have found that the only way to avoid this compiler error is to include the _bic_SR_register_on_exit call within the ISR. (If wrapped in a #define, the code compiles, but wrapped in an inline function - even with the FUNC_ALWAYS_INLINE #pragma - compilation fails.)
According to "MSP430 Optimizing C/C++ Compiler v4.4 (Rev J.) - slau132j.pdf" Section 5.11.8, we should be able to suppress this error with:
#pragma diag_suppress=1358
However, even with this #pragma in place, compilation fails with the same error.
Given these results, I believe this is either a bug in the compiler's handling of this #pragma directive, or a bug in the intrinsics implementation of _bic_SR_register_on_exit (which should emit a warning, not an error).