[Tinyos-devel] Nested interrupts

John Regehr regehr at cs.utah.edu
Wed Aug 15 09:24:04 PDT 2007


> 1/3 to 1/10 seems reasonable.

Ok, Michael and I argued about this a bit more off-list, and I wrote a bit 
of code, and the conclulsion seems to be as follows.

If the goal is to read an AVR I/O port with as little latency as possible, 
both a reentrant and non-reentrant interrupt can read the port in the 10th 
cycle following the interrupt trigger, including the 7 cycles that the 
processor requires to take the interrupt and jump to the handler.  Of 
course this requires bypassing the compiler.

Then, the fastest non-reentrant interrupt enables subsequent interrupts 
after 45 cycles (when it returns) and the reentrant one does this after 11 
cycles.  So the worst-case sampling latency is roughly 55 cycles vs. 22, 
for a 2-3x improvement.

This improvement is only useful if the rest of the program keeps its 
critical sections in the same ballpark as 11 cycles.

Code attached is my fastest non-reentrant handler which assumes a 
32-element ring buffer for samples.  I expect someone clever could shave a 
few cycles off this but it seems pretty close to optimal in terms of both 
sampling latency and overall cycles.

Hopefully this is useful for people doing tight sampling...

John
-------------- next part --------------
	.file	"irqs.c"
	.arch atmega128
__SREG__ = 0x3f
__zero_reg__ = 1
	.text
.global	__vector_4
	.type	__vector_4, @function
__vector_4:						       /* 7 cycles */
	
	/* save r24, take the sample and leave it in r24 */
	push r24                                               /* 2 cycles */
	in r24,82-0x20					       /* 1 cycles */

	/* save r25 and SREG */
	push r25					       /* 2 cycles */
	in r25,__SREG__                                        /* 1 cycles */
	push r25                                               /* 2 cycles */

	/* increment idx mod 32, leave it in r25 */
	lds r25,idx                                            /* 2 cycles */
	subi r25,lo8(-(1))                                     /* 1 cycles */
	andi r25,lo8(31)                                       /* 1 cycles */
	sts idx,r25                                            /* 2 cycles */

	/* store sample from r24 into samples[idx] */
	push r30                                               /* 2 cycles */
	push r31                                               /* 2 cycles */
	ldi r30,lo8(samples)                                   /* 1 cycles */
	ldi r31,hi8(samples)                                   /* 1 cycles */
	add r30,r25                                            /* 1 cycles */
	adc r31,__zero_reg__                                   /* 1 cycles */
	st Z,r24                                               /* 2 cycles */

	pop r31                                                /* 2 cycles */
	pop r30                                                /* 2 cycles */
	pop r25                                                /* 2 cycles */
	out __SREG__,r25                                       /* 1 cycles */
	pop r25                                                /* 2 cycles */
	pop r24                                                /* 2 cycles */
 
	reti                                                   /* 4 cycles */

	.size	__vector_4, .-__vector_4
	.comm samples,32,1
	.comm idx,1,1



More information about the Tinyos-devel mailing list