[Top][All Lists]
[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.
- [avr-gcc-list] Bug in avr-libc or?,
Per Arnold Blåsmo <=