sterossi84 wrote on Wednesday, April 24, 2019:
Hi guys,
I’m using FreeRTOS on a Cortex A9 device (Xilinx ZYNQ).
The final application will be used in the context of electric motor control so, in order to reduce control-law interrupt latency, I’ve register the related handler with a priority that exceeds configMAX_API_CALL_INTERRUPT_PRIORITY.
Given the previous setting the interrupt is properly triggered also under FreeRTOS critical sections - exactly as it’s expected to.
I now intend to share data between application tasks and the aforementioned interrupt handler.
To avoid race condition I intend to mask core interrupt, write the data, and then re-enable core interrupts.
Something like the example reported below.
Is this possible /is there a better way to do it?
Does it interfere with FreeRTOS itself leading to system failure?
static uint32_t EM_PositionReferece = 0u;
/* run in the context of the task */
void EM_SetPositionReference(UINT32 user)
{
/* mask CPU interrupt */
__asm volatile ( "CPSID i");
__asm volatile ( "DSB" );
__asm volatile ( "ISB" );
/* set motor-control position reference to be used in interrupt */
EM_PositionReferece = user;
/*
* NO FreeRTOS API usage here!
*/
/* un-mask CPU interrupt */
__asm volatile ( "CPSIE i");
__asm volatile ( "DSB" );
__asm volatile ( "ISB" );
}
void EM_IRQHandler(void)
{
ControlLaw_Exec(EM_PositionReferece );
/*
* NO FreeRTOS API usage here!
*/
}
As last thing, in the previous example the interrupt are fully masked and then unmasked.
Is there a way (e.g. a dedicated CPU instruction) to get interrupt masking status and simultaneously disabling them?
What I want to achieve is something like the line below
/* mask interrupt and get previous masking status */
irqMask = _MaskIRQ();
/*
* set motor-control variable shared with IRQ
*/
/* restore interrupt masking status read at _MaskIRQ */
_RestoreIRQ(irqMask);
Thanks in advance,
Bucky