Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

To bit pack or not

To bit pack or not

2005-04-01 by peterburdine

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?

For those who don't know bit packing it allows you to do this (for
example the ADDR Register):

struct	ADDR_REG {
	unsigned	pad0:6;  // not used
	unsigned	V_V3A:10;
	unsigned	pad1:8; // not used
	unsigned	CHN:3;
	unsigned	pad2:3; // not used
	unsigned	OVERRUN:1;
	unsigned	DONE:1;
};

#define ADDR           (*((volatile struct ADDR_REG *) 0xE0034004))

while(!ADDR.DONE); // spin
adcVal = ADDR.V_V3A; // read value

Re: [lpc2000] To bit pack or not

2005-04-01 by Robert Adsett

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/

Re: [lpc2000] To bit pack or not

2005-04-01 by Charles Manning

On Friday 01 April 2005 13:00, 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 you should always target portability. Code has a habit of outlasting 
its original programming. I'm using some code that has been through 15 years 
and 6 projects.

Also, compilers can vary with versions and compile options. To depend on 
specific non-define behaviour is asking for trouble.


>
> For those who don't know bit packing it allows you to do this (for
> example the ADDR Register):
>
> struct	ADDR_REG {
> 	unsigned	pad0:6;  // not used
> 	unsigned	V_V3A:10;
> 	unsigned	pad1:8; // not used
> 	unsigned	CHN:3;
> 	unsigned	pad2:3; // not used
> 	unsigned	OVERRUN:1;
> 	unsigned	DONE:1;
> };
>
> #define ADDR           (*((volatile struct ADDR_REG *) 0xE0034004))
>
> while(!ADDR.DONE); // spin
> adcVal = ADDR.V_V3A; // read value

One of the problems with bit packing is that is encourages you to abstract 
away what is happening on the registers.

In some devices/peripherals, you should read-modify-write and in some you 
just set a bit (eg IO setting clearing).

It is not apparent what bitfields will do.

Sure you can test it on a particular compiler but they might change it in the 
next version (or with different compile options).

with

  REGX |= REGX_FLAG5;

or 
  REGX = FLAG5;

You **definitely** know what the compiler will do.

I regularly use bitfields for software variables, but I'd never use them for 
peripherals.

RE: [lpc2000] To bit pack or not

2005-04-01 by Tim Wade

I noticed that there were two other posts on this that were pretty much
down on the idea and they raise a lot of vaild points; if you know what
you are doing it can actually make the code a lot cleaner but there is
that issue of R/W vs RO or WO and other interesting side effects to do
with packing and order.

Having said all of that I quite like doing it and have used the an
compiler ages ago that had the registers of the chip I was using all
nicely provided as bit fields and it all worked fine. The job was a
quick in and out and I doubt it was ever ported to anything if it was
ever looked at again... But I thought at the time it made it a lot
easier to understand... (It was packing all the LUN and other weird bits
in SCSI packets).

If you are a bit worried about it then I have also seen some fairly
"intersting" definitions of bits within a register using #define macros;
it went something like:

BIT_DEFINTION(parity_bit, 4, 1);

Which made the variable parity bit the 4th bit of a register for 1 bit
and it generated a MASK and some other stuff but it was all a bit
confusing and probably more obvious long hand. I will have look to see
if I can find if if you are interested.

Cheers
Tim
Show quoted textHide quoted text
-----Original Message-----
From: peterburdine [mailto:lordofdawn@...] 
Sent: Friday, 1 April 2005 9:01 AM
To: lpc2000@yahoogroups.com
Subject: [lpc2000] To bit pack or not



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?

For those who don't know bit packing it allows you to do this (for
example the ADDR Register):

struct	ADDR_REG {
	unsigned	pad0:6;  // not used
	unsigned	V_V3A:10;
	unsigned	pad1:8; // not used
	unsigned	CHN:3;
	unsigned	pad2:3; // not used
	unsigned	OVERRUN:1;
	unsigned	DONE:1;
};

#define ADDR           (*((volatile struct ADDR_REG *) 0xE0034004))

while(!ADDR.DONE); // spin
adcVal = ADDR.V_V3A; // read value





 
Yahoo! Groups Links



 



--
This email is confidential and intended solely for the use of the individual to whom it is addressed.  
Any views or opinions presented are solely those of the author and do not necessarily represent those of NAUTRONIX LTD.

If you are not the intended recipient, you have received this email in error and use, dissemination, forwarding, printing, or copying of this email is strictly prohibited.  If you have received this email in error please contact the sender.   

Although our computer systems use active virus protection software, and we take various measures to reduce the risk of viruses being transmitted in e-mail messages and attachments sent from this company, we cannot guarantee that such e-mail messages and attachments are free from viruses on receipt.  It is a condition of our using e-mail to correspond with you, that any and all liability on our part arising directly or indirectly out of any virus is excluded.  Please ensure that you run virus checking software on all e-mail messages and attachments before reading them.

Re: [lpc2000] To bit pack or not

2005-04-01 by Arie de Muynck

From: "peterburdine"
> 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).

Bitfields for I/O access are a definite no-no when using GCC (at least the
GCCgcc-arm-xxx versions I tried). They are optimized into smaller width
accesses, and trying to R/W a byte on a 32-bit wide I/O register will cause
major problems.

Thus, I use macro's, or just write all the low-level stuff into a heavily
commented low-level driver (with shifts and masking).
Of course I first create a header file with #defines for all bit positions
and register addresses.

Regards,
Arie de Muynck

Re: To bit pack or not

2005-04-01 by Ken Wada

For 8-bit values; your scheme will work fine. For 16 and 32-bit 
values...your scheme will not work at all! Read page 34 of the LPC2214 
users manual:
"This eliminates the need for byte lane mapping hardware that would be 
required to allow byte (8-bit) or half-word (16-
bit) accesses to occur at smaller boundaries. An implication of this 
is that word and half-word registers must be accessed all at
once. For example, it is not possible to read or write the upper byte 
of a word register separately."

This implies all registers must be accessed as a single 32-bit word. 
If you look closely at the memory map, most the registers are exactly 
organized, (LITTLE ENDIAN), as 8-bit octets using the 
least-significant-byte on 32-bit boundaries.

Ken Wada

--- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
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
Show quoted textHide quoted text
> 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?
> 
> For those who don't know bit packing it allows you to do this (for
> example the ADDR Register):
> 
> struct	ADDR_REG {
> 	unsigned	pad0:6;  // not used
> 	unsigned	V_V3A:10;
> 	unsigned	pad1:8; // not used
> 	unsigned	CHN:3;
> 	unsigned	pad2:3; // not used
> 	unsigned	OVERRUN:1;
> 	unsigned	DONE:1;
> };
> 
> #define ADDR           (*((volatile struct ADDR_REG *) 0xE0034004))
> 
> while(!ADDR.DONE); // spin
> adcVal = ADDR.V_V3A; // read value

Re: To bit pack or not

2005-04-01 by peterburdine

Well, I'm certainly glad I starting asking about this instead of just
doing it.  It seems that all around it can be a very bad idea at least
when using them to read and sometimes write to registers.

Thanks for all the advice.

--- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> wrote:
Show quoted textHide quoted text
> 
> 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?
> 
> For those who don't know bit packing it allows you to do this (for
> example the ADDR Register):
> 
> struct	ADDR_REG {
> 	unsigned	pad0:6;  // not used
> 	unsigned	V_V3A:10;
> 	unsigned	pad1:8; // not used
> 	unsigned	CHN:3;
> 	unsigned	pad2:3; // not used
> 	unsigned	OVERRUN:1;
> 	unsigned	DONE:1;
> };
> 
> #define ADDR           (*((volatile struct ADDR_REG *) 0xE0034004))
> 
> while(!ADDR.DONE); // spin
> adcVal = ADDR.V_V3A; // read value

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.