AVR32 IRQ Handling

jhenshaw wrote on Saturday, August 16, 2008:

I’ve upgraded my Atmel UC3A0512 project to FreeRtos V5.0.2. My question regards interrupt handling when the ISR might awaken a different thread due to the ISR placing a message into a queue. The serial ISR example, which does exactly that, looks like this. The 2nd function, TerminalIsr() is the one that’s actually called when an IRQ occurs:

__attribute__((__noinline__))
static portBASE_TYPE TerminalIsrHandler( void )
{
    char                                     Byte;
    unsigned long                 Status;
    unsigned long                        IrqSource;
    portBASE_TYPE                     Qstatus;
    portBASE_TYPE                     HigherPriorityTaskWoken = pdFALSE;

    Code That Does Stuff Goes Here…

    /* The return value will be used by portEXIT_SWITCHING_ISR() to know if it
    should perform a taskYIELD_FROM_ISR(). Note that the macro explicitly
    checks for a 1 in order to do the yield operation. */
    return (HigherPriorityTaskWoken ? 1 : 0);
}

// Terminal interrupt service routine.
// Since we might switch tasks inside here, we have to give it the ‘naked’
// attribute rather than ‘interrupt’ and handle the stack via
// portENTER_SWITCHING_ISR & portEXIT_SWITCHING_ISR.
// In addition, because FreeRTOS is not supposed to run with nested
// interrupts, put all OS calls in a critical section.

__attribute__((__naked__))
static void TerminalIsr( 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();
   
    // Now go do the work
    TerminalIsrHandler();           
   
    /* 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();
}

My question is - Can I write a single function that handles ISRs rather than incurring the overhead of a 2nd function call? If so, what would the template be for that function?

Thanks !

jhenshaw wrote on Sunday, August 17, 2008:

I’ve dug a little deeper. The IRQ I need to do extra work is the OS Timer tick ISR which uses     portSAVE_CONTEXT_OS_INT() and portRESTORE_CONTEXT_OS_INT() and is structurally different than the serial port example I outlined earlier.

So, let’s change my question. I can define configUSE_TICK_HOOK to 1 to force the tick ISR to call out to my code. The question is, how do I in the hook routine post data into a queue - a “normal” queue, not a co-routine queue. I’m not using co-routines.

jhenshaw wrote on Sunday, August 17, 2008:

Since I’m about to write another serial port handler, I guess I’d still like my first question answered as well.

Thanks again!