At 01:00 AM 4/1/05 +0000, peterburdine wrote:
>While not lpc2000 specific, I wanted to see if anyone else here was
>using bit packing to access registers or if they were writing macros
>or just doing to shifts and masking (w/o macros).
>
>I spoke with the software guys here where I work (I'm and EE) and 2
>out of 3 of them didn't think that using bit packing was a good idea
>for any application, but the 1 thought that using it to access fields
>with a register was a great idea. I know that portability is a
>concern of theirs, but since this is a device driver for 1 chip and
>the code already has extensions which force it to be compiled with a
>specific compiler (Keil's in the case) that I don't see that as a
>valid argument. What do you think?
I think the usual term is bitfields (I've not seen it called bit packing
before).
I've run hot and cold on using bitfields in the past. The conclusions I've
come too are
- Fine, maybe even great for logically packing in small integer
values into a structure with minimal wasted ram, provided the extra code
and time overhead is acceptable.
- A bad (sometimes a very bad) idea for hardware access.
The later point deserves some explanation. There are a couple of issues
involved. The first set of issues is the minimal guarantees you can get
across compilers. The standard basically only guarantees that the bits
will be placed in some order and take no more than a single integer per
bitfield. Granted implementations usually do better than that and they
have to define the order of allocation but we are treading on thin
ice. This is more than a portability of code issue. It's a portability of
knowledge issue. Unless you spend a great deal of time immersed in the
bitfields of the particular compiler it is necessary to verify the
behaviour each time they are revisited to deal with the hardware. If the
code is ever going to be maintained I'd recommend against bitfields for a
hardware interface on that basis alone.
The second set of issues is the read/write behaviour of bitfields. There
is no way to be certain of how they will be implemented. A read of a
bitfield might read a full 32 bits, or only 16 or 8. Some HW cannot
support reading except on certain boundaries and there is no way to enforce
that behaviour with bitfields. Similarly with a write. In addition there
is the (unfortunately common) read only and write only registers. Read
only registers often clear on reading, so the read of a single bitfield on
the register may clear all the other fields in the register. On a write
only register there is no way for the compiler to know what the current
value of the register is so on the write of a bitfield the generated code
usually reads the location fist and then does the appropriate masking,
shifting etc.. Since the read operation is not reading the same register
there is every likelihood that updating one bitfield will scramble others.
And of course many people miss the implications of the fact that int c :
2; is in fact signed.
There was at one point a proposal for a common set of library routines and
macros to provide a portable interface for this kind of manipulation so
that it was not constantly re-invented. I don't know what has become of
that though. Perhaps someone else does.
Robert
" 'Freedom' has no meaning of itself. There are always restrictions, be
they legal, genetic, or physical. If you don't believe me, try to chew a
radio signal. " -- Kelvin Throop, III
http://www.aeolusdevelopment.com/