I found that macros: portCLEAR_INTERRUPT_MASK_FROM_ISR
and
portCLEAR_INTERRUPT_MASK() are not fully implemented. It is shame because I need such macros to create function what call FreeRTOS API and could be used from interrupts and tasks. In my example: ===========================================================
uxSavedInterrup = portSET_INTERRUPT_MASK_FROM_ISR();
{
// <- proper BASE priority
queueSendStatus = xQueueSendFromISR(xQue_PRINT_SERVER,
&print_mes, &pxTaskWoken);
// UNSAFE LINE HERE and below
//<- due not fully implemented portCLEAR_INTERRUPT_MASK_FROM_ISR() base priority back to 0
if ( pdTRUE == queueSendStatus )
(print_mes->something)++;
queueSendStatus = xQueueSendFromISR(xQue_PRINT_SERVER,
&print_mes, &pxTaskWoken);
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterrup); // in fact not needed, xQueueSendFromISR()
// clear base priority to 0!
See line with comment: UNSAFE LINE HERE. Interrupts back to zero, not to configMAX_SYSCALL_INTERRUPT_PRIORITY.But there is no big issue to implement such macros. What I did: based on core_cm3.c and core_cm3.h (CMSIS 1.20) from http://www.onarm.com/download/download389.asp created functions to put in to portmacro.h ===============================================================================
static inline void __cortexM3__enable_irq() { __asm volatile (”cpsie i”); }
static inline void __cortexM3__disable_irq() { __asm volatile (”cpsid i”); } static inline void __cortexM3__set_BASEPRI(unsigned portBASE_TYPE value)
{
__asm volatile (”MSR basepri, %0″ : : “r” (value) );
}// static inline unsigned portBASE_TYPE __cortexM3__get_BASEPRI(void)
{
unsigned portBASE_TYPE result = 0U; __asm volatile (”MRS %0, basepri_max” : “=r” (result) );
return(result);
}// static inline unsigned portBASE_TYPE portSET_INTERRUPT_MASK(void)
{
unsigned portBASE_TYPE uxSavedInterruptStatus;
__cortexM3__disable_irq(); /* need atomic execution !*/
{
uxSavedInterruptStatus = __cortexM3__get_BASEPRI();
__cortexM3__set_BASEPRI(configMAX_SYSCALL_INTERRUPT_PRIORITY);
}
__cortexM3__enable_irq();
return uxSavedInterruptStatus;
}// static inline void portCLEAR_INTERRUPT_MASK(unsigned portBASE_TYPE uxSavedStatus)
{
__cortexM3__set_BASEPRI(uxSavedStatus);
}// #define portSET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK(x) #define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK(0U)
GCC 4.4.1With flag -O1 portSET_INTERRUPT_MASK() evaluate to only 5 instructions: ================================================================
0x080002bc <print_server_Message+164>: cpsid i
0x080002be <print_server_Message+166>: mrs r4, BASEPRI_MASK
0x080002c2 <print_server_Message+170>: mov.w r3, #191 ; 0xbf
0x080002c6 <print_server_Message+174>: msr BASEPRI, r3
0x080002ca <print_server_Message+178>: cpsie i
With flag -O1 portCLEAR_INTERRUPT_MASK_FROM_ISR() only one instruction 0x080002f0 <print_server_Message+216>: msr BASEPRI, r4 Obviously optimization O1 or higher need to be used.1. Is it correct?
2. Any chance to implement this or similar solution for this macros? Regards