[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