Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

RE: [AVR-Chat] gcc compiler bad behaviour

2012-04-16 by Tim Mitchell

OK Thanks for the clarifications about volatile... what I was distracted by was that the variable in question was not being *changed* by an interrupt routine, it was only changed in mainline code. However it was being *read* in an interrupt routine. As the compiler couldn't see the variable being used in the current scope it optimised the code out.

However - the strange thing is why the compiler has only optimised part of it, it is still loading the value into a register, but then has removed the store instruction. If it had optimised the whole thing away it would seem a slightly more valid thing to do.

----Original Message----
From: AVR-Chat@yahoogroups.com
[mailto:AVR-Chat@yahoogroups.com] On Behalf Of Tim Mitchell
Sent: 13 April 2012 11:35 To: AVR-Chat@yahoogroups.com
Subject: [AVR-Chat] gcc compiler bad behaviour

> The GCC compiler optimiser seems to be doing a weird
> thing to me... I'd like to understand it. it seems to
> require a volatile qualifier when I am not expecting it.  
> 
> I have the following variables defined
> unsigned char LedLevel0=0;
> unsigned char LedLevel1=0;
> volatile unsigned char AdcVal[4];
> 
> AdcVal holds readings from the ADC and is loaded in an
> interrupt routine 
> 
> main loop:
> 
> 	//the main loop
> 	while(1)
> 	{
> 		LedLevel0=AdcVal[0];
> 		LedLevel1=AdcVal[1];
> 	}
> 
> compiler output:
> 
> 	//the main loop
> 	while(1)
> 	{
> 		LedLevel0=AdcVal[0];
>  3ea:	80 91 86 01 	lds	r24, 0x0186
> 		LedLevel1=AdcVal[1];
>  3ee:	80 91 87 01 	lds	r24, 0x0187
>  3f2:	fb cf       	rjmp	.-10     	; 0x3ea <main+0x8>
> 
> i.e. it's loading the AdcVal into r24, but never stores
> it into the other variable. 
> 
> if I change the main loop to add a call to a delay
> routine then it works correctly. Also if I declare
> LedLevel0/1 as volatile.  
> But in my mind it shouldn't need to be declared volatile,
> nothing else is changing it. 
> 
> 	//the main loop
> 	while(1)
> 	{
> 		LedLevel0=AdcVal[0];
> 		LedLevel1=AdcVal[1];
> 		TimeWait(1);
> 	}
> 
> compiler output:
> 	//the main loop
> 	while(1)
> 	{
> 		LedLevel0=AdcVal[0];
>  3ea:	80 91 86 01 	lds	r24, 0x0186
>  3ee:	80 93 06 01 	sts	0x0106, r24
> 		LedLevel1=AdcVal[1];
>  3f2:	80 91 87 01 	lds	r24, 0x0187
>  3f6:	80 93 07 01 	sts	0x0107, r24
> 		TimeWait(1);
>  3fa:	81 e0       	ldi	r24, 0x01	; 1
>  3fc:	90 e0       	ldi	r25, 0x00	; 0
>  3fe:	f4 cf       	rjmp	.-24     	; 0x3e8 <main+0x6>



-- 
Tim Mitchell

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.