Is it AVR-GCC bug?

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
I have written a simple program by GCC-AVR to detect key press. I
found the debounce loop cannot be break.

In file main.c:

extern unsigned char timerDebounce=0;

:
:
            c=pressKey();
            if(c==-1)
            {
            }
            else
            {
                timerDebounce=5;
                while(timerDebounce!=0);//cannot break here
                col=pressKey();
:
:


In file timer.c:


unsigned char timerDebounce=0;

void SIG_OVERFLOW0 (void) __attribute__ ((signal));

void SIG_OVERFLOW0 (void)
{
    timerCounter25ms=(timerCounter25ms+1)%50;
    if(timerCounter25ms==0)
    {
        if(timerDebounce==0)
        {
        }
        else
            timerDebounce--;

:
:

Then I disasmbler the program and found:

timerDebounce=5;
+0000006D:   E085        LDI     R24,0x05         Load immediate
+0000006E:   93800071    STS     0x0071,R24       Store direct to data
space

while(timerDebounce!=0);
+00000070:   2388        TST     R24              Logical AND
+00000071:   F7F1        BRNE    -0x02            Branch if not equal

Obviously the "timerDebounce" is saved at SRAM location 0x71. I have
traced the program and found the value at the location is 0 during
looping , and the looping is caused by the program continues test the
register R24 rather than the SRAM location 0x71 for branching if zero.

Is it a bug in GCC-AVR? Thanks!

Re: Is it AVR-GCC bug?

Quoted text here. Click to load it

No, it's a bug in your code.

Ian

Re: Is it AVR-GCC bug?
Please show where the code is wrong.

Re: Is it AVR-GCC bug?
Quoted text here. Click to load it

Lookup the keyword volatile.

timerDebounce=5;
while(timerDebounce!=0);//cannot break here

The compiler doesn't know that 'someone else' is going to change
TimerDebounce, so it is perfectly okay to use a register for the
time being. I guess that a few more lines down in your assembly,
the compiler has created lines to store the TimerDebounce at
locaction 0x71. Of course, that is not going to happen, as it
keeps locked up in the loop.

BTW, please realize that your while loop is a great time waster.
If you can afford that, no problem.

I'm not an GCC-AVR expert, but it doesn't look like a compiler bug.


--
Thanks, Frank.
(remove 'x' and 'invalid' when replying by email)








Re: Is it AVR-GCC bug?
Quoted text here. Click to load it

Lose the =0 here. It's not causing the bug, but initialization should really be
with the definition, not the declaration. Right now, you have to places where
timerDebounce is initialized. There should be only one.

What you need to do is to declare timerDebounce as "volatile". This will force
the while loop to read the SRAM variable. Any variable that can change via an
interrupt or via a change in hardware needs to be declared as volatile. You
also should not have any sort of compiler optimization turned on when
developing code. Get it working right, then turn optimization on and see the
results.


Re: Is it AVR-GCC bug?
snipped-for-privacy@yahoo.com (terry) wrote in message

Quoted text here. Click to load it

Make that timerDebounce a volatile variable so the compiler will
check the timerDebounce value from the SRAM in every loop rather than
store the timerDebounce into the register before the loop.

Search from this newsgroup with the keyword "volatile" if you are not
familiar its usage.

Re: Is it AVR-GCC bug?
Quoted text here. Click to load it

To avoid GCC optimization code you should declare timerDebounce variable
as static. <<static unsigned char timerDebounce=0;>>


Re: Is it AVR-GCC bug?
Quoted text here. Click to load it

Declaring it static doesn't avoid optimization. Declaring it volatile will.
It's what volatile is meant to do. Declaring something static means he can't
export the name by using extern. When the compiler sees something declared as
static, it doesn't generate an exportable symbol for the linker to use (it
restricts visibility). If you try to to use:

extern static unsigned char timerDebounce;

you will get a compiler error like "declaration syntax error".


Re: Is it AVR-GCC bug?
Quoted text here. Click to load it

oops ! my apologies i didn't read timerDebounce variable is also
declared in main as extern. So you're right, static modifier on
variables makes them unvisible by other modules (*.c) static variables
are remanent also
I think that the prob is timerDebounce always 0 on main function but it
depends on where located that inst

extern unsigned char timerDebounce = 0;

void main()
{
...
}

IS VERY DIFFERENT FROM

void main()
{
extern unsigned char timerDebounce = 0;

...
}

I'm not sure that volatile modifier on that var would be the solution,
locals vars are stored in regs AVR and be destroyed after exec
functions. volatile modifier force GCC to read var in loops statements
sensitive with asynchronous events (PORTS, INT's)

Tell me how the problem was fixed

bye


Re: Is it AVR-GCC bug?

Quoted text here. Click to load it





Indeed.  Because the latter won't even compile as C code.  "extern"
inside blocks may only be used to code declarations, but not
definitions.  The presence of the "= 0" initializer, OTOH, turns this
into a definition.

Actually, good C programming style effectively bans all use of the
'extern' qualifier outside header files.  Whenever you think you want
to use 'extern' in a source file, you should really #include a header
file that holds the needed declaration, instead.

Quoted text here. Click to load it

Then let me be one more person to ensure you that it is.  This is
*exactly* the situation the 'volatile' modifier was originally created
for.  If making this variable 'volatile' doesn't suffice to fix the
problem at hand, that would be a compiler bug.

--
Hans-Bernhard Broeker ( snipped-for-privacy@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Site Timeline