[chbot] AVR external interrupt and Makefile example

Col colp at paradise.net.nz
Mon Nov 16 04:51:12 GMT 2009


Charles Manning wrote:
> sei()/cli() is not necessarily non-portable because you generally use a macro 
> that you can redefine whereever it is needed.
> 
> What is important though is to guard against reenabling interrupts when not 
> intended.
> 
> For example consider:
> 
> void clear_counter(void)
> {
> 	cli();
> 	temp = counter;
> 	sti()
> 	return temp;
> }
> 
> int a_n_other(void)
> {
> 	cli();
> 	...A...
> 	clear_counter()
> 	...B...
> 	sti()
> }
> 
> or
> 
> main()
> {
> 
> 	/* initialisation  at start with interrupts off */
> 	...C..
> 	clear_counter();
> 	...D...
> 	/* Everything set up OK, now turn on interrupts */
> 	sei();
> 	...
> }
> 
> 
> At first glance that looks like the code section ..B.. in a_b_other is 
> protected by the cli()/sti(). Nope. The sti() in clear_counter() reenabled 
> interrupts.
> 
> Same with using clear_counter() during start up. It would have turned on 
> interrupts too soon!
> 
> ATOMIC_BLOCK can help, but there is a way to do this manually too by 
> remembering if interrupts were on or off.
> 
> eg
> void clear_counter(void)
> {
> 	uint8_t istate = interrupt_GetAndDisable()
> 	temp = counter;
> 	interrupt_Enable(istate);
> 	return temp;
> }
> 

or using the avr-libc macros already provided.

void clear_counter(void)
{
	ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
	{
		temp = counter;
	}
	return temp;
}


I prefer this way as the protected code is indented.


Cheers
Col.



More information about the Chchrobotics mailing list