[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-libc-dev] Re: What Happened to the sbi() and cbi() Macros????
From: |
E. Weddington |
Subject: |
[avr-libc-dev] Re: What Happened to the sbi() and cbi() Macros???? |
Date: |
Sun, 30 Jan 2005 23:25:13 -0700 |
User-agent: |
Mozilla Thunderbird 1.0 (Windows/20041206) |
Bruce D. Lightner wrote:
E. Weddington wrote:
Erik Walthinsen wrote:
E. Weddington wrote:
They've been deprecated for a long time. They were finally removed
in the 1.2.x series. They're gone for good.
I still have not figured out what the logic is behind removing two
of the most useful macros possible on a machine where ALL IO is
preformed by setting and clearing bits.
Please, enlighten me.
Go look at the implementation of the sbi and cbi macros and you'll
see why. ;-)
Eric
I just looked at the file "sfr_defs.h" where sbi() and cbi() macros
are defined and I don't see what the problem is, nor do I see anything
humorous about the code or the situation...
Eric, please enlighten me! Exactly why were the "sbi() and cbi()
macros removed?!!
Are *all* the "input/output" macros gone (e.g., bit_is_set(),
bit_is_clear(), inb(), inw(), outb(), outw()...)?
AFAIK, bit_is_set, bit_is_clear are both still in. But sbi, cbi, inb,
inw, outb, outw, outp, inp are all gone now.
If you need someone to "maintain" the file "sfr_defs.h", then I'm sure
you can find lot's of volunteers...like me!
I've followed the "avr-gcc" mailing list every day for many years and
I don't remember *any* inquiries, surveys, or votes regarding this
recent "improvement" to avr-gcc, namely removing "depricated" I/O marcos.
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.
So, please enlighten us as to why these macros cannot remain in the
library. I for one am ready listen to reason, but please also think
long and hard about what removing them does to many of us long time
end-users of avr-gcc. And don't get me wrong, we folks that make
daily use of the wonderful things that the maintainers of "avr-gcc"
and it's libraries have created truly do appreciate your hard work!
And, we thank you!!
However, as the comments in the "sfr_defs.h" source code say regarding
the "missing" macros, they are included for...
"For backwards compatibility"
I personally have created well over 100 "avr-gcc" projects that make
use of one or more now "depricated" I/O macros. I have hundreds of
thousands of AVR-based devices in the field that use avr-gcc source
code that references these macros. Responsibility for supporting that
installed base resets with me.
Although I, like most(?) others make less and less use of "depricated"
macros for new code, I do not want to be forced to revisit perfectly
fine, field-proven, debugged and tested avr-gcc code just because a
macro was "depricated" and I (or one of my customers) has decided to
(or has been forced to) upgrade the "avr-gcc" toolset. I don't know
about you, but I know that "fixing" working source code is an
invitation for new bugs. And, bugs cost time to fix, and time is
money...to anyone but a hobbyist.
Does anyone else want to comment? Am I overreacting?
Sure. I definitely understand, especially from a commercial point of view.
It was discussed on avr-libc-dev a while ago. These macros were
deprecated and have been that way for a while. Yes, it was even in the
documentation that they were deprecated.
Victoria Welch wrote:
E. Weddington wrote:
Go look at the implementation of the sbi and cbi macros
and you'll see why. ;-)
Perhaps some of us just use the sbi/cbi macros (quite
successfully, I might add) and have been since we started
using the avr-gcc toolchain.
Personally, I take that comment as elitist, arrogant,
patronizing and insulting to those of use the language and
are not low level gurus.
LOL! Geez, all I said was to go look at how they were implemented. The
source code is available to all. It certainly had nothing to do with me
being arrogant and elitist. It had more to do with me not having enough
time to explain it; I assumed that by looking at how they were
implemented, the reason for removal would become self-evident.
I'm certainly not against having a non-confrontational discussion about
this, so let's revisit the subject. To this end, I've included Joerg
Wunsch in the CC list as he's also now co-maintaining avr-libc and I've
also cross-posted this to the avr-libc-dev list, where it really belongs.
.....
From what I remember, is that avr-libc was originally using macros to
do IO, such as outb(), inb(), outp() and inp(). These were originally
modeled after the Linux environment. It was pointed out that this was
not really necessary, and not typical in an embedded environment. Most
cross-compilers would define registers and use "direct access" to write
and read from them, for example:
PORTA = 0x01;
PORTB |= 0x02;
PORTC &= ~0x04;
var = PIND;
This was adopted as what should be used, so outb(), inb(), outp(), and
inp() were deprecated. In fact, the later versions of those macros were
implemented as the "direct access" show above.
cbi() and sbi() were similarly implemented, and it was thought instead
of having a somewhat "redundant" macros was rather pointless, and they
too were deprecated.
Now before anybody gets up in arms about this, I just want to point out,
that these macros were labeled as deprecated in the avr-libc user manual
for some time. There are many open source projects where items that are
deprecated in one or two releases, are removed in later releases, for
example: gcc, gdb, binutils, etc.
There were many instances where Joerg or I would point out to users that
all of these macros were deprecated and should not be used. And we
pointed this out on the avr-gcc list and at AVR Freaks.
We are certainly not unwilling to listen, but honestly, we never got any
feedback from people who wanted to keep it. What were we supposed to do?
Now, on moving forward...
Bruce, for "legacy" code that must require cbi() and sbi(), would it be
reasonable to patch your own version of avr-libc to provide these
macros? The implemenations are not that hard.
As to the idea that these were very useful macros, then I have a
counter-proposal:
I would like to create an API that can be used to operate on bits. I
propose that this would be a new header, <avr/bit.h>. In this header,
would be macros that would set, clear, toggle, read, and test bits in a
variable. These macros would also be defined to work on variables of
size 8 bit, 16 bit and 32 bit. For example:
----------------------------------------------------------------
#include <inttypes.h>
#define bit_set_8(var, mask) ((var) |= (uint8_t)(mask))
#define bit_clear_8(var, mask) ((var) &= (uint8_t)~(mask))
#define bit_toggle_8(var, mask) ((var) ^= (uint8_t)(mask))
#define bit_read_8(var, mask) ((var) & (uint8_t)(mask))
#define bit_set_16(var, mask) ((var) |= (uint16_t)(mask))
#define bit_clear_16(var, mask) ((var) &= (uint16_t)~(mask))
#define bit_toggle_16(var, mask) ((var) ^= (uint16_t)(mask))
#define bit_read_16(var, mask) ((var) & (uint16_t)(mask))
// 32 bit versions here
// Shorter named versions for the common operation.
#define bit_set(var, mask) bit_set_8(var, mask)
#define bit_clear(var, mask) bit_clear_8(var, mask)
#define bit_toggle(var, mask) bit_toggle_8(var, mask)
#define bit_read(var, mask) bit_read_8(var, mask)
----------------------------------------------------------------
There are several reasons why I think this would be useful:
- Doing bit operations with the C language bit operators is confusing to
most newbies. This usually has to be explained again and again. These
macros make it easier for newbies.
- It's makes it easier to read what operation is happening rather than
trying to remember the bit operations themselves.
- The typecasts are in there to workaround the C language Standard of
promoting the operands of bit operaters to ints, which are 16 bits for
the AVR (see the avr-libc FAQ for more discussion of this). If these
macros are used, then users don't have to remember to do the typecasts,
which should, in theory, help with the size of their code.
I would also like to propose two other macros for this file:
#define BIT(x) (1 << (x))
#define LONGBIT(x) ((uint32_t)1 << (x))
Yes, the BIT() macro is the same as _BV(). The _BV() macro is confusing
in two ways: one has to remember that "BV" stands for Bit Value. The
name BIT is slightly more descriptive. And _BV() has a leading
underscore, which technically is supposed to be reserved for the
"implementation" according to the C Standard (in this case the library).
Having to type out the underscore is annoying. I feel that it's easier
to just write out "BIT".
The LONGBIT macro is needed to provide a conversion from a bit number to
a 32-bit mask.
Personally, I don't care whether the macro names are upper or lower
case. I'm fine with bit() and longbit() too.
I feel that it is important that the bit macros supply a bit "mask" and
not just a bit number because a bit mask is more flexible in defining
non-contiguous bits to operate on. This means that one can do this:
bit_set(PORTD, BIT(0) | BIT(2) | BIT(4) | BIT(7));
bit_clear(PORTG, BIT(1) | BIT(6));
bit_toggle(PORTE, BIT(5) | BIT(3));
bit_read(PORTF, BIT(7));
Would this proposal be useful?
Comments welcome.
Thanks
Eric