[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 11:37:14 -0600 |
On 4 Oct 2002 at 10:18, Theodore A. Roth wrote:
> Well, as I wrote the example, I didn't get any warnings. :-)
You didn't?.........
Huh. Well, I know that I'm using an older compiler but not that old
(3.2 experimental). I got warnings because I do something similar to
access 16-bit timer registers.
>
> Ick! Probably not a good idea to hide the volatile in a typedef (or
> #define for that matter).
Well, that doesn't particularly bother me. But I'm sure it's just
personal taste. I would only include the volatile in a type if
defining a type for registers / register access.
> 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.
Looking at this closer, this is basic C pointer stuff, y'know.
Replace the PORTB with any other variable and you have the classic
case of updating an external variable in a function, where you show
passing by value (which doesn't work) and passing by reference (which
does work).
The trick is getting over the idea that the register definitions act
any differently. The whole point of defining the registers in this
manner *is* to use the C idioms in this manner when accessing the
registers. The registers become (similar to) a global C variable
which gets passed around, assigned to, assigned from, taken the
address of, pointed to, etc.
Anyhow, looks good to me. Ship it.
Eric