Hello,
I am working with a Zynq-7000 and FreeRTOS 8.2.3. I would like to enable nested interrupts but I am experiencing some problems.
As Xilinx AR54128 (https://www.xilinx.com/support/answers/54128.html) says, I call XScuGic
CPUWriteReg(IntcInstancePtr, XSCGICBIN
PTOFFSET,0x03) during the interrupt controller initialization, before the XilExceptionInit().
Then, my ISR routine is something like this:
~~~
void Handler()
{
BaseType
t xTaskWokenByReceive = pdFALSE;
BaseTypet xHigherPriorityTaskWoken = pdFALSE;
Xil_EnableNestedInterrupts();
if(xQueueReceiveFromISR(<argA>, <argB>, &xTaskWokenByReceive) == pdTRUE)
{
vTaskNotifyGiveFromISR(<argC>, &xHigherPriorityTaskWoken);
}
else if(xQueueReceiveFromISR(<argD>, <argE>, &xTaskWokenByReceive) == pdTRUE)
{
vTaskNotifyGiveFromISR(<argF>, &xHigherPriorityTaskWoken);
}
else
{
// Do nothing
}
/* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch
* should be performed to ensure the interrupt returns directly to the highest
* priority task. The macro used for this purpose is dependent on the port in
* use and may be called portEND
SWITCHINGISR().
*/
Xil_DisableNestedInterrupts();
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
~~~
The priority of the related interrupt is equal to configMAX_API_CALL_INTERRUPT_PRIORITY.
During the execution I get two assert errors:
– Assert failed in file port.c, line 539
– Assert failed in file port.c, line 424
The first one comes from the first configASSERT of the function vPortValidateInterruptPriority():
~~~
void vPortValidateInterruptPriority( void )
{
/* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above
configMAX
SYSCALLINTERRUPT
PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below
configMAXSYSCALL
INTERRUPTPRIORITY.
Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY.
FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible. */
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
/* Priority grouping: The interrupt controller (GIC) allows the bits
that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority).
The priority grouping is configured by the GIC's binary point register
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
possible value (which may be above 0). */
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
}
~~~
The second one from the last configASSERT of the function vPortEnterCritical():
~~~
void vPortEnterCritical( void )
{
/* Mask interrupts up to the max syscall interrupt priority. */
ulPortSetInterruptMask();
/* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */
if( ulCriticalNesting == 1 )
{
configASSERT( ulPortInterruptNesting == 0 );
}
}
~~~
Does anyone know why I get those errors?
Am I making some mistakes while setting the interrupt’s priority?
Thank you for the help!
Enrico