I know this is stale, and the issue seems to be widely known, but I'd like to highlight that the counter method proposed unconditionally enables interrupts when the outermost critical section is left. This makes it unuseable in interrupts or any function which might be used in an interrupt. I spent a weekend working this out when we tried to port to using FreeRTOS critical sections. It is pretty easy to fix though.
I've attached my alternative which can be used with interrupt code and ordinary code. This is coded for an MSP430F5438A on an IAR SBW development system. It's tested and works. It also has the advantage of working independantly of FreeRTOS, so can be used before starting the task scheduler. The disadvantage is that for portable code, a generic means to test the current interrupt state would be needed; I think it would be worth doing though.
#define portENTER_CRITICAL() \
{ \
extern volatile unsigned short usCriticalNesting; \
\
if (__get_SR_register() & __SR_GIE) \
{ \
__disable_interrupt(); \
/* If interrupts are set, start at zero. We then know to reenable interrupts */ \
/* when the count returns to zero. If interrupts are disabled, we have no */ \
/* way of knowing if this is a first call, or a nested call. just increment. */ \
usCriticalNesting = 0; \
} \
usCriticalNesting++; \
} \
#define portEXIT_CRITICAL() \
{ \
extern volatile unsigned short usCriticalNesting; \
\
usCriticalNesting--; \
if (usCriticalNesting == 0) \
{ \
/* About to leave the outermost critical section; the next critical section */ \
/* started might be with interrupts enabled or might not, so set to 1. */ \
usCriticalNesting = 1; \
__enable_interrupt(); \
} \
} \