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: Theodore A. Roth
Subject: Re: [avr-libc-dev] [RFC] passing port info to a function
Date: Fri, 4 Oct 2002 10:18:06 -0700 (PDT)

On Fri, 4 Oct 2002, E. Weddington wrote:

:) > 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? ;-)

Well, as I wrote the example, I didn't get any warnings. :-)

:)
:) 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.)

Ick! Probably not a good idea to hide the volatile in a typedef (or
#define for that matter).

I like the use of "&PORTB" in the call and volatile in the function
prototype since it gets rid of the use of _SFR_ADDR() macro in your code
(bad form to use internal library macros in your code since they _could_
change on you).

So here's the code for the example I'm working on:

cat <<EOF > example.c
#include <inttypes.h>
#include <avr/io.h>

void
set_bits_func_wrong (volatile uint8_t port, uint8_t mask)
{
    port |= mask;
}

void
set_bits_func_correct (volatile uint8_t *port, uint8_t mask)
{
    *port |= mask;
}

#define set_bits_macro(port,mask) ((port) |= (mask))

int main (void)
{
    set_bits_func_wrong (PORTB, 0xaa);
    set_bits_func_correct (&PORTB, 0x55);
    set_bits_macro (PORTB, 0xf0);

    return (0);
}
EOF

This seems to follow the correct C idioms more closely than the original.

Thanks for calling me on that Eric.

Ted Roth





reply via email to

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