I use a FreeRTOS queue and in the application task is used the following code to access the queue and the flag: Note that I use the xQueueReceiveFromISR() although it is inside the application task, but IRQ’s are disabled so I should’nt call xQueueReceive() – anyway thats my hyposis. The code in the task reads:
portDISABLE_INTERRUPTS(); // Here we are sure to have the queue for ourselves, IRQ handler is off
if(THR_IsEmpty=TRUE)
{//Ok tx irq is stuck. Need a kick-off by a write of the queue front byte to THR transmit register. I must NOT enable IRQ yet!
if( xQueueReceiveFromISR( xCharsForTx, &uChar, &xHigherPriorityTaskWoken_BUT_NOT_USED_HERE_AS_I_AM_ONLY_USER ) == pdTRUE )
{
/* A character was retrieved from the queue so it can be send to the THR now.... */
LPC_USART->THR = uChar; //Send it
THR_IsEmpty=FALSE; //More data
}
else
{
THR_IsEmpty=TRUE; //No more data - its empty
}
}
portENABLE_INTERRUPTS();
It appears to work but I am a bit skeptic as to the robustness due to the following:
portDISABLE_INTERRUPTS expands to __asm volatile ( ” cpsid i ” ) /* =Interrupt disable */but when I see the code for xQueueReceiveFromISR() it holds the lines uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
which expands to
uxSavedInterruptStatus = 0;__asm volatile ( ” cpsid i ” )
(note the current state of Interrupt is ignored! (is’nt that a port issue?) and the call is matched with the reenable..
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
which expands to
portCLEAR_INTERRUPT_MASK();(void)x
or simply
__asm volatile ( ” cpsie i ” ) /* =Interrupt enable – unconditionally*/ In other words at the exit of the xQueueReceiveFromISR() interrupt is enabled – this will break the logic in the above task code. A) Is it ok to call xQueueReceiveFromISR() from a task provided interrupts are disabled?
B) Should’nt the portSET_INTERRUPT_MASK_FROM_ISR()/portCLEAR_INTERRUPT_MASK_FROM_ISR() pair in the LPC1114 port recall the
interrupt state such that it does not enable the interrupt if it was originally disabled when portSET_INTERRUPT_MASK_FROM_ISR()
was called?. I.e. properly restore the state as it was on entry.
C) Better ways? Thanks for any advice you may have.
henning