[Top][All Lists]

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

[avr-gcc-list] Re: What Happened to the sbi() and cbi() Macros????

From: Joerg Wunsch
Subject: [avr-gcc-list] Re: What Happened to the sbi() and cbi() Macros????
Date: Mon, 31 Jan 2005 11:10:55 +0100
User-agent: Mutt/

As Erik Walthinsen wrote:

> E. Weddington wrote:

> >Well, the problem is that it's not the avr-gcc list is where this
> >stuff is usually discussed, it's the *avr-libc-dev* list.

> Perhaps it would be good to create a single list, independent of
> gcc, libc, avrdude, etc. where developers can ask general questions
> (such as the issues re: atmega48/88/168), and leave the
> avr-libc-dev, avr-gcc-list, and avrdude-dev lists for people
> developing and debugging specific issues related to those packages?

I basically always thought that address@hidden constitutes that
list.  As all the current maintainers of avr-libc follow that list, it
IMHO suffices.

But of course, I'm closer in time in following avr-libc-dev, but then,
that's a developer's list.

> >It was discussed on avr-libc-dev a while ago. These macros were

s/a while/more than two years/

We have been telling *everyone* ever since that they are deprecated,
and it had been clear from the beginning that the intention is to
eventually remove deprecated interfaces after a long enough warning

> I noticed the intent to deprecate in the documentation when I first
> started using this stuff, but I guess I figured the concept of
> removing sbi/cbi seemed so ludicrious that someone must have been
> joking.

Why does it seem to be so ludicrious to remove private hacks when the
respective functionality could now appropriately be expressed using
standard C notation?

No other architecture needs a hack like this one in order to set or
clear bits.  Please go and read any hardware-related C program (Unix
kernel drivers etc.), as a C programmer who wants to handle hardware,
you basically have to be aware of the bit manipulation operators that
are part of the C language.

That's the same situation now for the AVR.

The old sbi/cbi etc. macros have only once been needed when the GCC
toolchain wasn't ready yet to handle the preferrable `direct
assignment' for for IO ports (which is not only preferred by us, keep
in mind that this is the way Atmel documents their usage of the C
language).  By that time, they were crude hacks needed in order to get
access to the SBI/CBI instructions at all (where the developer was
held responsible to care for the allowable argument domain for these

That's about three years ago now.  Since then, there have been
replacement macros that just transformed the old (gone) sbi/cbi macros
to standard C bit manipulation.  It was always intented to only supply
them to ease the transition for users.  Yet, it also turned out they
weren't only a help to users, but a constant source of confusion as
well.  First, there were many people who blindly believed these macros
would *always* turn into SBI/CBI instructions, which they don't.  They
only translate into them when optimization is turned on, *and* the
args are in the domain of SBI/CBI (port number sufficiently low,
right-hand side must be a compile-time constant).  Second, it seems to
have stopped a lot of AVR-GCC developers from thinking about their
code.  Not only that the AVR-GCC community now seems to be the only
community of hardware-related C developers who still didn't grok the
bit manipulation operators, but I've also seen code like:

sbi(DDRB, 0);
sbi(DDRB, 1);
sbi(DDRB, 2);
sbi(DDRB, 3);

when someone thinking more about their code could simply write

DDRB |= 0x0f;

(or maybe even DDRB = 0x0f;)

For a decent editor (i.e. one that understands regular expressions),
it's a matter of five minutes to convert old code from
inb/outb/sbi/cbi to the new form.  Been there, done that.  OK, if you
chose an editor that doesn't handle REs, where you have to click and
cut'npaste everything, it might take a bit longer, but that's
everyone's decision.

Finally, if you say ``Yeah, I'm aware of all these implications, I do
know about the C operators, I don't write inefficient code anyway.'',
what's wrong with stuffing

#define sbi(a, b) (a) |= (1 << (b))
#define cbi(a, b) (a) &= ~(1 << (b))

into your application's header file if that makes you more
comfortable?  It would have taken you a lot less time than it takes me
to write this mail (as you said you understand the bit manipulation
operators, so you could write the above within say 15 seconds).

Btw., I'm not entirely happy with Atmel defining bit numbers instead
of bit values in their datasheets, so we need all that 1<< shifting
around.  Supposedly, they did it in order to be able to use the same
header file for assembler programming together with the SBI/CBI
instructions, I don't know.  Any decent C programmer would have called
e.g. the RXC macro 0x80 instead of 7 in their header files.  But as we
do want to follow Atmel's definitions, we're stuck with it (that's why
we do have the _BV macro for convenience).

> On that topic I will again mention that I haven't seen a single one
> of my emails come through to the avr-gcc list, with error messages
> from my mail server indicating that it simply cannot talk to the
> avr1.org SMTP server.

There's no use to discuss this on the list itself, you need to discuss
this with avr1.org's postmaster.  I'm not entirely happy with
avr1.org's mail setup either, they get out with an invalid HELO

>  Where it gets really screwy is that I just successfully
> telneted into port 25 on avr1.org from the same IP...

That doesn't mean anything.  You also need to be able to succeed in an
SMTP conversation afterwards.  Of course, you could use that method in
order to send a mail to their postmaster if all else fails.  The
basics of SMTP are rather easy to handle (which is the root of all
that email worm evil, alas).

> But it seems from your above comments that the only reason for
> removing sbi/cbi was in order to remove potential confusion among
> users as to what the routines did, whether they used the assembly
> instructions of the same name or not, etc.

> Why then can't the documentation simply be updated to explain this?

Because people don't read docs.  Trust me, I *do* support the user
base on various occassions, and unless you point people with your
fingers, they don't even pretend to understand (and 5 minutes later,
they have forgotten it again, as nobody bothers to do a search in a
forum's or mailing list's archive either).

See above, the AVR-GCC community is now the only community of C
programmers who operate close on the hardware I know of that still
hasn't groked how bit manipulation works in C.  I've never seen a
request for a macro that would replace |= and &=~ in the FreeBSD
mailing lists.  Actually, it turns out anyone who needs a macro for
this rather writes their customized version, which is closer to his
problem.  For the AVR, this could e.g. mean that you rather decide
to have

#define LED_ON(nr) PORTB &= ~(1 << (nr))
#define LED_OFF(nr) PORTB |= (1 << (nr))

instead.  Note the more explanatory name, as well as the possibility
to hide the negated logic for a LED that is connected against Vcc.

> The people reading this documentation aren't stupid, they're
> developing firmware for a microcontroller.

Sorry, after following forums like avrfreaks.net and
mikrocontroller.net, I have completely lost this impression. :-(

I'm so disappointed about the sillyness of so many of these
wannabe-developers that I'm almost opposed to the idea of supplying a
compat/iomacros.h, as this will be IMHO the best guarantee that the
AVR-GCC community at large will *never* learn about the bit
manipulation operators of the C language afterwards.

(Note that it hasn't been me who once deprecated these macros, it's
IMHO been Marek Michalkiewicz who maintained avr-libc by that time.
But I fully support the deprecation and removal right now.)

cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)

reply via email to

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