avr-libc-dev
[Top][All Lists]
Advanced

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

Re: [avr-libc-dev] [RFC] passing port info to a function


From: E. Weddington
Subject: Re: [avr-libc-dev] [RFC] passing port info to a function
Date: Fri, 04 Oct 2002 10:57:27 -0600

On 4 Oct 2002 at 9:22, Theodore A. Roth wrote:

> 
> 
> On Fri, 4 Oct 2002, E. Weddington wrote:
> 
> :) Caveat, add volatile:
> :) #define PORTB_ADDR ((volatile uint8_t *)_SFR_ADDR(PORTB))
> :)
> :)
> :) > void
> :) > set_bits_func_correct (uint8_t *port, uint8_t mask)
> :) > {
> :) >     *port |= mask;
> :) > }
> :)
> :) And here:
> :) set_bits_func_correct (volatile uint8_t *port, uint8_t mask)
> :)
> 
> I don't think "volatile" is needed in this instance. The reason is you
> are passing the reference to the port, not the port. The compiler will
> not optimize this away because it's smart enough to know that you are
> changing what the pointer refers to which could affect the caller of
> the function.
> 
> The volatile is needed in set_bits_func_wrong() because port is passed
> by value, the local _copy_ is changed, and the change can never make
> it out of the function. Thus, the compiler thinks that the func does
> nothing which can affect the caller, so just optimizes out the func
> completely. Making port volatile, tells the compiler not to do that.
> 
> This is my interpretation of what happens when using various
> optimization levels and looking at the disassembly of the object file.
> Feel free to prove me wrong. ;-)
> 
> Ted Roth

If you take the address of PORTB like this:

&PORTB

or the equivalent of the macro PORTB_ADDR you have a type that is a 
pointer to volatile uint8_t.

If you pass this pointer to the port parameter in:

set_bits_func_correct (uint8_t *port, uint8_t mask)

you will get a compiler warning about discarding qualifier from 
pointer target type.

You wouldn't want to provide examples to users that cause compiler 
warnings would you? ;-)

So to get around that, you'd have to change the definition of the 
function:

set_bits_func_correct (volatile uint8_t *port, uint8_t mask)

or typecast the passed parameter.

Or, which would be more work, typedef an AVR register type and use 
that type everywhere (example):

typedef avrreg8   volatile uint8_t;
typedef avrreg16 volatile uint16_t;

(Don't treat the above as an argument for doing it. It's just one 
possible solution.)

Eric






reply via email to

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