[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [avr-gcc-list] Bug in avr-libc or?
From: |
Rune Christensen |
Subject: |
RE: [avr-gcc-list] Bug in avr-libc or? |
Date: |
Tue, 1 Jun 2004 09:55:30 +0200 |
Hello
Look below
> -----Original Message-----
> From: address@hidden
> [mailto:address@hidden On Behalf Of Per Arnold Blåsmo
> Sent: Tuesday, June 01, 2004 9:42 AM
> To: address@hidden
> Subject: [avr-gcc-list] Bug in avr-libc or?
>
>
> 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;
// change the variable to volatile
volatile 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 mailing list
> address@hidden
> http://www.avr1.org/mailman/listinfo/avr-gcc-list
>
> ---
> Incoming mail is certified Virus Free.
> Checked by AVG anti-virus system (http://www.grisoft.com).
> Version: 6.0.692 / Virus Database: 453 - Release Date: 28-05-2004
>
>
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.692 / Virus Database: 453 - Release Date: 28-05-2004