Well, as I already said in my question I just tried to switch the context inside the asm statement (Call c function with an inline assembler instruction). So, using "RCALL" (Relative call to subroutine):
"RCALL vPortEnterCritical\n\t"
"RCALL vTaskSwitchContext\n\t"
"RCALL vPortExitCritical\n\t"
the hole code would look like this:
#define portRESTORE_CONTEXT_OS_INT()
{
extern volatile unsigned portLONG ulCriticalNesting;
extern volatile void *volatile pxCurrentTCB;
/* Check if AVR32_INTC_INT0 or higher were being handled (case where the OS tick interrupted another */
/* interrupt handler (which was of a higher priority level but decided to lower its priority */
/* level and allow other lower interrupt level to occur). */
/* In this case we don't want to do a task switch because we don't know what the stack */
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */
/* will just be restoring the interrupt handler, no way!!! */
__asm__ __volatile__ (
"ld.w r0, sp[9*4]\n\t" /* Read SR in stack */
"bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)"\n\t"
/* Else */
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */
"RCALL vPortEnterCritical\n\t"
"RCALL vTaskSwitchContext\n\t"
"RCALL vPortExitCritical\n\t"
/* Restore all registers */
/* Set SP to point to new stack */
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)")\n\t"
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)")\n\t"
"ld.w r0, r8[0]\n\t"
"ld.w sp, r0[0]\n"
"LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":\n\t"
/* Restore ulCriticalNesting variable */
"ld.w r0, sp++\n\t"
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)")\n\t"
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)")\n\t"
"st.w r8[0], r0\n\t"
/* Restore R0..R7 */
"ldm sp++, r0-r7\n\t"
/* Now, the stack should be R8..R12, LR, PC and SR */
"rete"
);
/* Force import of global symbols from assembly */
ulCriticalNesting;
pxCurrentTCB;
}
This worked for me and I did not see so far any differences in the behavior of our system. I hope this can help someone wo has to migrate from IAR Workbench 4.10 to 4.20.