Forum Discussion
Altera_Forum
Honored Contributor
21 years agoIntterupt processing time
Hello!
I'd like to know how many clock ticks interrupt handler takes from the interrupt point to interrupt handler function? I created project, which includes following components: PIO(output) and Interval Timer. I set interval timer period 50 usec and 100 usec. I wrote interrupt timer handler: char uval=0; static void handle_timer_interrupt(void* context,alt_u32 id) { uval = ~uval; IOWR_ALTERA_AVALON_PIO_DATA( PIO_1_BASE , uval); IOWR_ALTERA_AVALON_TIMER_STATUS (TIMER_0_BASE, 0); return; } Then the simulation showed that the time between time interrupt (timestamp) and changed value at PIO_1 is about 5.4 usec. Is it notmal? How can I reduce this time? Thank you.3 Replies
- Altera_Forum
Honored Contributor
Kira,
It's hard to comment on your interrupt latency time, as all sorts of things will affect the time taken, clock frequency, version of processor, what memory your code is running from, the priority of the interrupt etc. Your time sounds quite long we have measured latency at between 81-83 cycles on a 1S10 full design which uses Nios II/f processor. Chapter 6 of the Nios II Software Developer's Guide has some documentation on Exceptions and tips on how to reduce interrupt latency Some things you could do to speed up your IRQ latency include: Use the highest priority interrupt available Place your interrupt handler into an on chip memory - Altera_Forum
Honored Contributor
Hi,
I did some test with "Nios II/fast core" and got those results: Between user space to enter the beginning of Irq sections code: 10 cycles. Then to came bame to user mode: 5 cycles. If you use HAL altera for interruption, you got 265 to enter the beginning of handler, and 100 to exit to user code. Sylvain - Altera_Forum
Honored Contributor
I think the HAL interrupt entry sequence is pretty good. I had a look at it and couldn't do much better than the compiler has[1]. If you want to write interrupt handlers in C you need to save all the registers which the C compiler will corrupt as otherwise your system won't work.
I assume you are measuring the time for interrupt 0 since that's fastest. By my calculations the current version should take about 59 cycles (I may be off by a few) to get to the start of the user routine for interrupt 0 (assuming cache hits each time). So if you are measuring much more (you don't say how you are measuring) then the slowdown is probably due to memory latencies, for icache fills and for saving registers onto the stack. This is why its so important to put your exception handler and stack into fast onchip memories. Once you've done that it may be possible to rewrite the interrupt handler in assembler to get even lower latencies for one interrupt. Here is my suggestion for a faster handler for interrupt 0. I think it will take 10 cycles to get to the point where you start saving registers. If you do this then you'll also have to change the C handler to handle interrupt 0 differently. But if you're worrying this much about interrupt latencies then you also need to worry about the time for which interrupts are disabled, either by foreground code or because another interrupt is being handled.
[1] I did manage to save about 5 clocks so this will be better in a future release..globl save_r2 // Define in a C file somewhere as: unsigned int save_r2; alt_irq_entry: rdctl et, estatus andi et, et, 1 beq et, zero, software_exception rdctl et, ipending andi et, et, 1 beq et, zero, notirq0 // 10 cycles to get here stw r2, %gprel(save_r2)(gp) // Save as many other registers as you need. Your assembler code // is allowed to use the registers you save here and et. If you're // really careful you could use bt and ba as well but then you won't // be able to debug this code. // Your assembler code goes here // Restore other saved registers ldw r2, %gprel(save_r2)(gp) eret notirq0: rdctl et, ipending beq et, zero, software_exception