[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [avr-gcc-list] bug with bitfields in (volatile) registers?
From: |
Ben Mann |
Subject: |
RE: [avr-gcc-list] bug with bitfields in (volatile) registers? |
Date: |
Fri, 7 Jan 2005 15:29:17 +0800 |
Hi Ned,
I did a couple of little experiments. It looks like the problem is in the
treatment of the bitfield.
For example, changing the struct to
{ unsigned char uartState; }
works fine.
int main(void)
{
0: c0 e0 ldi r28, 0x00 ; 0
2: d0 e0 ldi r29, 0x00 ; 0
4: de bf out 0x3e, r29 ; 62
6: cd bf out 0x3d, r28 ; 61
for (;;)
{
while (state.uartState == 10)
8: 8a e0 ldi r24, 0x0A ; 10
a: 38 16 cp r3, r24
c: e9 f3 breq .-6 ; 0x8
;
c = 'A';
e: 01 e4 ldi r16, 0x41 ; 65
while (state2 == 10)
10: 1a 30 cpi r17, 0x0A ; 10
12: f1 f3 breq .-4 ; 0x10
;
while (state3 == 10)
14: 8a e0 ldi r24, 0x0A ; 10
16: 98 16 cp r9, r24
18: e9 f3 breq .-6 ; 0x14
1a: f6 cf rjmp .-20 ; 0x8
A big clue was when I (stupidly) tried:
volatile register state_t state __asm__("r3");
...it gives an error about not having the address of the variable -
something only required by the bitfield.
Maybe this will help, I'm sure however that someone will have some more to
say about it.
Ben Mann
-----Original Message-----
From: address@hidden [mailto:address@hidden
On Behalf Of Ned Konz
Sent: Friday, 7 January 2005 2:44 PM
To: address@hidden
Subject: [avr-gcc-list] bug with bitfields in (volatile) registers?
I was just bit by this surprise with registers suddenly being treated as if
they were not volatile (in avr-gcc 3.4.3). I'm using a chip with no RAM, so
I
would like the registers to work properly.
// avr-gcc -Os -mmcu=avr2 -mcall-prologues -mint8 -mtiny-stack -save-temps
-Wall -g -Wa,-almshd=registerbug.lst -Wl,--oformat=ihex -o registerbug.hex
registerbug.c
// avr-objdump -h -S registerbug.o > registerbug.lss
typedef struct
{
unsigned char uartState:4;
unsigned char unused:4;
} state_t;
register unsigned char c __asm__("r16");
register state_t state __asm__("r3"); // actually volatile... register
unsigned char state2 __asm__("r17"); register unsigned char state3
__asm__("r9");
int main(void)
{
0: c0 e0 ldi r28, 0x00 ; 0
2: d0 e0 ldi r29, 0x00 ; 0
4: de bf out 0x3e, r29 ; 62
6: cd bf out 0x3d, r28 ; 61
// look what's happening here: r3 is getting copied to r24...
8: 83 2d mov r24, r3
a: 8f 70 andi r24, 0x0F ; 15
for (;;)
{
// and then the comparison is being done on r24.
// however, meanwhile an interrupt handler is changing r3, and we // get
stuck in this loop forever:
while (state.uartState == 10)
c: 8a 30 cpi r24, 0x0A ; 10
e: f1 f3 breq .-4 ; 0xc
// that should be a branch back to 0x8 instead of 0xc!
;
c = 'A';
10: 01 e4 ldi r16, 0x41 ; 65
// here everything is fine because we can do a cpi:
while (state2 == 10)
12: 1a 30 cpi r17, 0x0A ; 10
14: f1 f3 breq .-4 ; 0x12
;
// and here everything is fine because the generated code
// branches to the right place:
while (state3 == 10)
16: 9a e0 ldi r25, 0x0A ; 10
18: 99 16 cp r9, r25
1a: c1 f7 brne .-16 ; 0xc
1c: 9a e0 ldi r25, 0x0A ; 10
1e: 99 16 cp r9, r25
20: d1 f3 breq .-12 ; 0x16
22: f4 cf rjmp .-24 ; 0xc
;
}
}
Are registers supposed to be treated as if they were volatile?
Is this a bug?
Thanks,
--
Ned Konz
http://bike-nomad.com
_______________________________________________
avr-gcc-list mailing list
address@hidden http://www.avr1.org/mailman/listinfo/avr-gcc-list