In NIOS2 port queueYIELD_IF_USING_PREEMPTION expanded into TRAP instruction. This instruction immediatelly call task switching, not pending like PendSV on Cortex-M.

Look at code. In xQueueGenericSend we can see this sequence:


After expanding macros:

    asm volatile ( "trap" ); // task switching

Let’s insert body of vTaskEnterCritical/vTaskExitCritical:

	 ( pxCurrentTCB->uxCriticalNesting )++;
// pxCurrentTCB->uxCriticalNesting == 1
    asm volatile ( "trap" ); // change pxCurrentTCB !!!
// pxCurrentTCB->uxCriticalNesting == 0
	if( pxCurrentTCB->uxCriticalNesting > 0U )
// Not executed!
		 ( pxCurrentTCB->uxCriticalNesting )--;
		if( pxCurrentTCB->uxCriticalNesting == 0U )

It’s clear?
We disable interrupt and increase uxCriticalNesting for first task. Then we switch to second task with zero uxCriticalNesting. We NOT enable interrupt at return from xQueueGenericSend. Application hang.

Workaround: Do not use portCRITICAL_NESTING_IN_TCB for port with immediate task switching.
Remark: Ports for Cortex-M do not affected.

Ports that have immediate (synchronous) task switching save the interrupt enable status (enabled/disables) as part of the task’s context. So if a TaskA has interrupts disabled, its context is saved with interrupts disabled. If the next task to run in TaskB, and TaskB’s interrupts were enabled when its context was saved, then restoring the context of TaskB will result in interrupts becoming enabled. Likewise, when TaskA is next restored, because its context was saved with interrupts disabled, when its context is restored, interrupts will again become disabled.

This is the port layer for the NIOS II - which register has the interrupt enable/disable status? https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/master/portable/GCC/NiosII/port_asm.S

I am sorry for false report.

My project use incorrect port of FreeRTOS for NIOS, probably taken from https://github.com/EngineeringSpirit/FreeLwIP-Nios-II/tree/master/nios2_freertos_port
This port use incorrect implementatios of portENABLE_INTERRUPTS. Two consecutive calls of portENABLE_INTERRUPTS make interrupt disabled.

Sorry again.