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

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

[avr-gcc-list] Bug in avr-libc or?


From: Per Arnold Blåsmo
Subject: [avr-gcc-list] Bug in avr-libc or?
Date: Tue, 01 Jun 2004 09:41:59 +0200
User-agent: Mozilla Thunderbird 0.6 (X11/20040502)

Hi,

I have been doing a program  and got into a problem with a while loop.

Basically what I wanted to do was to do a while loop that waited until a variable changed and so go out of the while loop.
The variable was altered by a interrupt routine.

What happen was that the variable in the while loop was copied into a register and the while loop did test the register instead of the variable. Thereby never detecting any change of the variable done in the interrupt routine.

I made a test program to show the result:

avrtest.c :

#include <avr/io.h>
#include <avr/signal.h>

uint8_t var;

SIGNAL(SIG_INTERRUPT0){
var = 0;
}

int main(void){

var = 1;

while(var==1){
// do nothing but wait
}

//Now do sometning
var = 2;
}

I compiled the code with the following command:

avr-gcc -mmcu=atmega16 -I. -g -O1 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=avrtest.lst -std=gnu99 avrtest.c -o avrtest.o

And the resulting .lst file was like this:

  1                       .file    "avrtest.c"
  2                       .arch atmega16
  3                   __SREG__ = 0x3f
  4                   __SP_H__ = 0x3e
  5                   __SP_L__ = 0x3d
  6                   __tmp_reg__ = 0
  7                   __zero_reg__ = 1
  8                       .global __do_copy_data
  9                       .global __do_clear_bss
 12                       .text
 13                   .Ltext0:
 59                   .global    __vector_1
 61                   __vector_1:
  1:avrtest.c     **** #include <avr/io.h>
  2:avrtest.c     **** #include <avr/signal.h>
  3:avrtest.c     ****
  4:avrtest.c     **** uint8_t var;
  5:avrtest.c     ****
  6:avrtest.c     **** SIGNAL(SIG_INTERRUPT0){
 63                   .LM1:
 64                   /* prologue: frame size=0 */
 65 0000 1F92              push __zero_reg__
 66 0002 0F92              push __tmp_reg__
 67 0004 0FB6              in __tmp_reg__,__SREG__
 68 0006 0F92              push __tmp_reg__
 69 0008 1124              clr __zero_reg__
 70                   /* prologue end (size=5) */
  7:avrtest.c     **** var = 0;
 72                   .LM2:
 73 000a 1092 0000         sts var,__zero_reg__
  8:avrtest.c     **** }
 75                   .LM3:
 76                   /* epilogue: frame size=0 */
 77 000e 0F90              pop __tmp_reg__
 78 0010 0FBE              out __SREG__,__tmp_reg__
 79 0012 0F90              pop __tmp_reg__
 80 0014 1F90              pop __zero_reg__
 81 0016 1895              reti
 82                   /* epilogue end (size=5) */
 83                   /* function __vector_1 size 12 (2) */
 85                   .Lscope0:
 88                   .global    main
 90                   main:
  9:avrtest.c     ****
 10:avrtest.c     **** int main(void){
 92                   .LM4:
 93                   /* prologue: frame size=0 */
 94 0018 C0E0              ldi r28,lo8(__stack - 0)
 95 001a D0E0              ldi r29,hi8(__stack - 0)
 96 001c DEBF              out __SP_H__,r29
 97 001e CDBF              out __SP_L__,r28
 98                   /* prologue end (size=4) */
 11:avrtest.c     ****
 12:avrtest.c     **** var = 1;
100                   .LM5:
101 0020 81E0              ldi r24,lo8(1)
102 0022 8093 0000         sts var,r24
 13:avrtest.c     ****
 14:avrtest.c     **** while(var==1){
104                   .LM6:
105                   .L3:
106 0026 8130              cpi r24,lo8(1)
107 0028 F1F3              breq .L3
 15:avrtest.c     **** // do nothing but wait
 16:avrtest.c     **** }
 17:avrtest.c     ****
 18:avrtest.c     **** //Now do sometning
 19:avrtest.c     ****
 20:avrtest.c     **** var = 2;
109                   .LM7:
110 002a 82E0              ldi r24,lo8(2)
111 002c 8093 0000         sts var,r24
 21:avrtest.c     ****
 22:avrtest.c     ****
 23:avrtest.c     **** }
113                   .LM8:
114 0030 80E0              ldi r24,lo8(0)
115 0032 90E0              ldi r25,hi8(0)
116                   /* epilogue: frame size=0 */
117 0034 0C94 0000         jmp exit
118                   /* epilogue end (size=2) */
119                   /* function main size 16 (10) */
121                   .Lscope1:
123                       .comm var,1,1
125                       .text
127                   Letext:
128 /* File "avrtest.c": code 28 = 0x001c ( 12), prologues 9, epilogues 7 */
DEFINED SYMBOLS
                           *ABS*:00000000 avrtest.c
                           *ABS*:0000003f __SREG__
                           *ABS*:0000003e __SP_H__
                           *ABS*:0000003d __SP_L__
                           *ABS*:00000000 __tmp_reg__
                           *ABS*:00000001 __zero_reg__
    /tmp/ccolD0rF.s:61     .text:00000000 __vector_1
                           *COM*:00000001 var
    /tmp/ccolD0rF.s:90     .text:00000018 main
    /tmp/ccolD0rF.s:127    .text:00000038 Letext

UNDEFINED SYMBOLS
__do_copy_data
__do_clear_bss
__stack
exit


If you look at line 104-107 of the .lst file, you see that the variable is in the register. I know this is a very simple example program and may not be the best example, but in my real program the the variable is in a struct and the overall program is more complex. Still the same happen. It loads the variable from its address into the register and compares with the register.

I believed that this while loop is allowed in 'C', or am I wrong?

I tried the same with a Linux 'C' program and it seems to generate correct(?) assembler code.

Is it because the variable is within the same object file or what?

Regards
Per A.



reply via email to

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