avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Global variables and ISRs ???


From: David Brown
Subject: Re: [avr-gcc-list] Global variables and ISRs ???
Date: Wed, 7 Sep 2005 09:20:00 +0200

> Hello Vincent,
>
> To be able to modify/access a variable in interrupt,
> declare it as "volatile".

That's not good advice - there is no reason to use "volatile" on all
variables used by interrupt routines.  That would lead to unnecessarily
slower code.  All you need to do is remember what "volatile" really means,
and then use it appropriately.  If you declare a variable "volatile", you
are telling the compiler that something else may change its value or read
its value, without the compiler knowing about it.  Thus it must read the
data from memory exactly as often as is specified in the C code, and it must
write it exactly as often as is specified.  Normally the compiler can assume
that after it has read a variable into a register, the data read is valid
until the function itself writes new data, or until it calls a second
function (which may change the value).  Making the variable volatile says
this assumption is not valid.

> Secondly, to test your code,
> turn off optimization (s=0) in your make file. There

Code that works with optomisation off, yet fails with optomisation on, is
incorrect code (assuming a bug-free compiler :-).  Code generated with
basic -O optomisation is far easier to read and understand than code
generated with -O0, since it keeps variables in registers instead of the
stack.  Occasionally, debugging with a debugger that doesn't work well with
optomised code can be easier with optomisation off, but that's for debugging
the logic of your program.

> is a problem in your code also - you are not making
> flag=0 after you send back the character. HTH.
>

That's certainly true - I suppose he'd have noticed if his program had got
far enough...

mvh.,

David


> Nayani
>
>
> --- Vincent Trouilliez
> <address@hidden> wrote:
>
> > Hi gents,
> >
> >
> > After the highly technical thread that just ended
> > today, I would like to
> > pick your brains on something much lower flying so
> > to speak, sorry for
> > that ! ;-)
> >
> >
> > Problem : on my ATmega32, after several experiments
> > (only just started
> > using it, learning...), I am suffering a big
> > problem. It seems that when
> > I declare a variable as global, then modify it
> > within an interrupt
> > routine, the 'main' function can't see that the
> > variable has been
> > modified, as if it weren't a global variable...
> > hmmm.
> >
> > The concrete case at hand, was that I tried to
> > implement a buffer for
> > incoming data on the UART. The ISR would fill the
> > buffer and update the
> > buffer pointer accordingly. The program in 'main'
> > was checking to see if
> > the pointer was non-zero and if yes, would send
> > characters back to the
> > serial port for me to see/check.
> > I proved that all was working fine, interrupts etc,
> > but somehow, 'main'
> > would always see the buffer pointer as zero (hence
> > would never react),
> > as if the ISR didn't update it.
> >
> > I simplified the program as much as I could, and the
> > problem is still
> > there. Could anyone have a look at the code below ??
> >
> > It receives characters on the serial port, toggle sa
> > LED to prove that
> > the ISR did get serviced, and sets flag to try and
> > communicate with the
> > 'main' function.... which fails. 'main' never sees
> > the flag as
> > set.... :-/ Any help welcome, because I started
> > scratching my head an
> > hour ago, and now I don't have many hair left to
> > pull !! ;-)
> >
> >
> > Regards,
> >
> >
> > --
> > Vince, extremely annoyed...
> >
> >
> >
> > #include <avr/io.h>
> > #include <avr/interrupt.h>
> > #include <avr/signal.h>
> >
> >
> > unsigned char flag, bin;  //global variables
> >
> >
> > void ioinit (void){
> >
> > DDRD = 0x20; //PD5 as output for the LED
> > PORTD = 0x00; //turn LED off at boot.
> > //set up USART
> > UBRRH = 0x00;
> > UBRRL = 12; //Baud Rate = 9600
> > UCSRA = 0x02; //mode asynchrone, fast clock
> > UCSRC = 0X86; //asynchronous, no parity, one stop
> > bit, 8 data bits
> > UCSRB = 0x98; //transmitter and receiver enabled,
> > interrupts on
> > receiver
> > flag = 0;
> > sei();
> > }
> >
> > SIGNAL (SIG_UART_RECV){
> >
> > bin = UDR; //read incoming character to clear
> > interrupt
> > PORTD = ~PORTD; //toggle LED to prove ISR was
> > serviced
> > flag = 1; //tell 'main' about the event
> > }
> >
> >
> > int main (void){
> >
> > ioinit ();
> > while(1){
> > if (flag){
> > UDR = 'A';  //print a character to prove that the
> > flag was set.
> > }
> > }
> > }
> >
> >
> >
> >
> > _______________________________________________
> > AVR-GCC-list mailing list
> > address@hidden
> >
> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
> >
>
>
> __________________________________________________
> Do You Yahoo!?
> Tired of spam?  Yahoo! Mail has the best spam protection around
> http://mail.yahoo.com
>
>
> _______________________________________________
> AVR-GCC-list mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
>





reply via email to

[Prev in Thread] Current Thread [Next in Thread]