[Top][All Lists]

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

Re: [avr-gcc-list] Re: optimizer removes volatile pin access code. why?

From: df_welch
Subject: Re: [avr-gcc-list] Re: optimizer removes volatile pin access code. why?
Date: Wed, 28 Oct 2009 11:14:08 -0700
User-agent: Thunderbird (Windows/20090812)

I'm mainly an assembly language user and not a heavy weight C user but this thread has peaked my interest. I'm currently working with the ATmega 2561 and in the course or reading and re-reading the data sheet I found an example on page 72,73 and an example on page 74 showing that there are some issues with the IO Ports that may be part of the issue here. the discussion is in section 13.2.4 "Reading the Pin Value" starting on page 72 of the 2549L–AVR–08/07 preliminary data sheet.

Basically as shown below in the Data sheet excerpt, a NOP is necessary following a write to DDRB(n), and prior to seeing the change on pin(n).

I'm not sure that this extends to the entire 8 bit family but it might be worth looking at.

Excerpt follows ==========================================
The following code example shows how to set port B pins 0 and 1 high, 2 and 3 low, and define the port pins from 4 to 7 as input with pull-ups assigned to port pins 6 and 7. The resulting pin values are read back again, but as previously discussed, a NOP instruction is included to be able
to read back the value recently assigned to some of the pins.

Assembly Code Example(1)
; Define pull-ups and set outputs high
; Define directions for port pins
ldi r16,(1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0)
ldi r17,(1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0)
out PORTB,r16
out DDRB,r17
; Insert NOP for synchronization
; Read port pins
in r16,PINB
C Code Example
unsigned char i;
/* Define pull-ups and set outputs high */
/* Define directions for port pins */
PORTB = (1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0);
DDRB = (1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0);
/* Insert nop for synchronization*/
/* Read port pins */
i = PINB;

Note: 1. For the assembly program, two temporary registers are used to minimize the time from pullups are set on pins 0, 1, 6, and 7, until the direction bits are correctly set, defining bit 2 and 3
as low and redefining bits 0 and 1 as strong high drivers.
13.2.5 Digital Input Enable and Sleep Modes
As shown in Figure 13-2, the digital input signal can be clamped to ground

Hope this sheds some light on what is going on.

Dan welch
David Brown wrote:
Erik Christiansen wrote:
On Wed, Oct 28, 2009 at 02:08:05PM +0100, Joerg Desch wrote:
I've played with "inline" and with "__attribute__((gnu_inline,
always_inline))" to avoid this overhead, but it doesn't work as expected.

#if defined(__GNUC__)
# define ALLWAYS_INLINE inline __attribute__((gnu_inline, always_inline))
ALLWAYS_INLINE int foo (void)
  // ...

I've tried it with -Os and foo() is still called.

Was this from a mail from Joerg Desch that did not make it to the mailing list? It is hard for others to comment - perhaps you or Joerg could re-post the problem code.

Ah, yes, optimisation needs to be used for inline to work. If the above
fails on a small test case, "avr-gcc -v" and the command-line don't show
a lurking "-fno-inline", and "-Wall -Wextra" doesn't provide any clues
either, I'd pretty soon be tempted to report it as a bug, unless a magic
method is revealed on the list. You've probably tried other
optimisations? (Just in case the size optimisation is absolute in its

I believe you need the -Winline to get a warning about functions declared "inline" that could not be inlined.

And an __attribute_((always_inline)) function will be inlined, regardless of the optimisation levels.

As you can see it receives in the list. But with 1/2 hour delay.

Oh goody, it works again! :-)


AVR-GCC-list mailing list


No virus found in this incoming message.
Checked by AVG - www.avg.com Version: 8.5.423 / Virus Database: 270.14.34/2463 - Release Date: 10/27/09 15:50:00

reply via email to

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