xTaskNotifyFromISR crash on portEXIT_SWITCHING_ISR() on AVR32 with freeRTOS 10.0.0

As the title says, when i notify a task from the ISR call, i get an exception on the portEXIT_SWITCHING_ISR() call.
If i comment out the notification it runs fine.

Here’s the code for the creation of the task to be notified:

> 
> static TaskHandle_t testTaskHandle = NULL;
> 
> portTASK_FUNCTION( vMyTestTask, pvParameters )
> {
>   uint32 testVal;
>   for( ;; ) // Loop forever
>   {
>     xTaskNotifyWait( 0x00000000,              /* Don't clear any notification bits on entry. */
>                      0xFFFFFFFF,              /* Reset the notification value to 0 on exit. */
>                      &testVal,                /* Get notification value. */
>                      portMAX_DELAY );         /* Wait indefinitely. */
>   }
> }
> 
> void taskStart(unsigned portBASE_TYPE uxPriority)
> {
>   if (xTaskCreate( vMyTestTask, ( const portCHAR * )"BEAMSEQ", configMINIMAL_STACK_SIZE + 256, NULL, uxPriority, &testTaskHandle ) == pdPASS) {
>     if (beamSeqTaskHandle) {
>       isrSetBeamSeqTaskHandle(beamSeqTaskHandle);
>     }
>   }
>   else {
>     // error!
>   }
> }

And here is the interrupt:

#pragma shadow_registers = full   // Naked.
static void myInt( void )
{
  portENTER_SWITCHING_ISR();     /* This ISR can cause a context switch, so the first statement must be a call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any variable declarations. */
  
  BaseType_t pxHigherPriorityTaskWoken = 0;
  
  xTaskNotifyFromISR(testTaskHandle,  // notify 
                     1,     
                     eSetValueWithoutOverwrite,   // without overwrite, we can check if task was already busy - this should not happen
                     &pxHigherPriorityTaskWoken); // in case of success, this should always be set to true, resulting in a context switch
      
  // pxHigherPriorityTaskWoken <-- PLACE THIS IN R12!
  portEXIT_SWITCHING_ISR();    /* Exit the ISR.  If a task was woken then a context switch will occur. */
}

Am i doing something wrong?

The AVR32 port in the FreeRTOS download was designed for ES chips, so please use the port provided by Atmel (now Microchip) themselves.

Besides that, just looking at the example we provide, I see that the interrupt handler has to be a naked function that just calls a non-naked C function between the entry and exit macros, as per:

/*
 * USART interrupt service routine.
 */
#if __GNUC__
	__attribute__((__naked__))
#elif __ICCAVR32__
	#pragma shadow_registers = full   // Naked.
#endif

static void vUSART_ISR( void )
{
	/* This ISR can cause a context switch, so the first statement must be a
	call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any
	variable declarations. */
	portENTER_SWITCHING_ISR();

	prvUSART_ISR_NonNakedBehaviour();

	/* Exit the ISR.  If a task was woken by either a character being received
	or transmitted then a context switch will occur. */
	portEXIT_SWITCHING_ISR();
}

(cut from our demo code).

The comment in your code implies the shadow_registers pragma is doing the same thing - but try using the naked attribute instead just in case.

Does the pragma set up a stack frame? If so, then it is not a naked function. If not, then you can’t define a variable on the stack as you are (the pxHigherPriorityTaskWoken variable) - that would have to be done inside the non-naked C function called from the naked function.

Thanks for the quick reply.

I should have mentioned this, but i’m using the IAR compiler which does NOT have the naked attribute, but uses the shadow_registers instead (http://ftp.iar.se/WWWfiles/AVR32/webic/doc/EWAVR32_CompilerReference.pdf).

As far as port goes, i’m using a very recent version for AVR32 made by Amazon (for freeRTOS V10.1.1).

It also says here https://www.freertos.org/portAVR32.html that it is okay to declare variables AFTER the portENTER_SWITCHING_ISR.

I’ll try to pack up everything in a non-naked function and see what happens.

I also have to add, that i tried substituting a binary semaphore (take and giveFromISR) for the notify, and that works without a problem.

Solution has been found. It IS necessary to wrap a non-naked function between the portEnter / portExit pair.

It is necessary to declare the non-naked function with the pragma:
#pragma optimize = no_inline
So it is not optimized into the function