Page 1 of 1

FIQ handling

Posted: Mon Jun 27, 2011 1:18 am
by liamstask
Hi, I'm getting some fast interrupt handling into my ChibiOS project (SAM7X256/GCC), but am running into a little trouble. I'm setting up one of the timer/counters to be routed through the FIQ.

I have the interrupt working OK - I can increment a counter indefinitely - but the rest of the OS doesn't seem to continue running. I have and ISR that looks roughly like:

Code: Select all

int fasttimer_counter = 0;
static CH_IRQ_HANDLER(FiqHandler) {
  fasttimer_counter++;
  asm volatile ("SUBS PC, LR, #4");
}


I only have the main thread running blinking an LED, but that does not continue running once I start up the fast timer. I couldn't find too much info on what's required to implement the FiqHandler within ChibiOS - is there a guide that I missed, or any info you can suggest? Thanks!

Re: FIQ handling

Posted: Mon Jun 27, 2011 6:19 am
by Giovanni
Hi Liam,

Declare your handler using CH_FAST_IRQ_HANDLER(), it is translated as:

__attribute__((interrupt("FIQ"))) void id(void)

Do not return using "subs", the compiler should generate proper code.

CH_IRQ_HANDLER() does not generate proper entry/exit sequences for FIQs (does not save registers modified by C code).

Giovanni

Re: FIQ handling

Posted: Mon Jun 27, 2011 7:09 am
by liamstask
Hi Giovanni,

I've tried that as well - at the highest level, I see the same result: the ISR seems to function OK, but my main task no longer runs (ie, the LED no longer blinks). Is there any other integration that needs to happen to allow normal systick handling to proceed? Thanks!

Re: FIQ handling

Posted: Mon Jun 27, 2011 7:45 am
by Giovanni
I can think of two possible causes:
1) The compiler generates wrong entry/exit sequences (you could post the generated code).
2) The interrupt is not served within the handler so it is immediately re-triggered.

Giovanni

Re: FIQ handling

Posted: Mon Jun 27, 2011 4:05 pm
by liamstask
OK - I'll dig into it a bit further. Thanks!

Re: FIQ handling

Posted: Tue Jun 28, 2011 6:34 am
by liamstask
Looks like the interrupt was not getting cleared, so it was constantly re-triggering as you suspected. By reading the timer/counter status register, the interrupt source is cleared and processing proceeds as normal - problem solved. So, now my slightly modified code looks like:

Code: Select all

static CH_FAST_IRQ_HANDLER(FiqHandler) {
  if (AT91C_BASE_TC2->TC_SR & AT91C_TC_CPCS) {
    fasttimer_counter++;
  }
}


By the way, the compiler does generate the same 'subs' instruction to return from the FIQ handler in this case :)