EmbeddedRelated.com
Forums

Using Bit Field structures to access LPC-2000 registers

Started by jdauchot May 27, 2009
Jean-Jacques Dauchot wrote:

> I am starting get very interested with this debate.
>
> What if someone or lots of people (including me) could come up with a
> standard to usie this bit field thing to access the registers on LPC2000
> chips as IAR has obviously managed in some obscured way .

You would be met with smug nods from experienced embedded guys
as they think about how they will enjoy their beer on the back
patio over the weekend while you are in the lab chasing down
mysterious bugs.

What is it with bitfields that leads young or inexperienced
programmers down this path?

Is it the incessant teaching of clean abstractions by their
professors?

Is it that nobody uses them for register access so they think
that they have found the holy grail of embedded programming?

Are their girlfriends impressed by the size of the brain that
must deal with the headaches and insanity that comes from
using these bitfields?

What is is, exactly?

For me bitfields are like an old Jaguar or MG. Nice to look
at, but in the garage more than they are on the road.

Ralph

An Engineer's Guide to the LPC2100 Series

> OK
>
> I am starting get very interested with this debate.
>
> What if someone or lots of people (including me) could come up with a
> standard to usie this bit field thing to access the registers
> on LPC2000
> chips as IAR has obviously managed in some obscured way .
>
> Please comments?
I have not read this whole thread so maybe am just repeating what other
people have said, but 'standard' and 'bitfield' are incompatible terms.

Even if you come up with your own 'standard' and it matches what IAR do, as
far as I'm aware there is nothing in what is commonly accepted as the C
standard for embedded (please don't start a debate on that!) compilers that
defines how bitfields should work. Therefore IAR are free to change how
they use them (not that they would as their libraries are littered with
them), and other compilers are free to do as they please. Reliance on
bitfields mapping into register bits is, in my humble opinion' a very bad
idea and one that will eventually lead to pain.

I am by no means an expert on this, but I am lead to believe that bitfields
were in the C language to assist on severely RAM limited machines where a
variable can be just one bit (Boolean) rather than taking up a whole word.
This is presumably why there was never anything standardised on how the bits
actually map to anything.

Besides that, bit fields are ugly, make debugging difficult, unnecessary,
and against most coding standards, etc.

For me there is no debate, I just won't use them.
Regards,
Richard.

+ http://www.FreeRTOS.org
Designed for Microcontrollers. More than 7000 downloads per month.

+ http://www.SafeRTOS.com
Certified by T as meeting the requirements for safety related systems.
--- In l..., "Jean-Jacques Dauchot" wrote:
>
> OK
>
>
>
> I am starting get very interested with this debate.
>
>
>
> What if someone or lots of people (including me) could come up with a
> standard to usie this bit field thing to access the registers on LPC2000
> chips as IAR has obviously managed in some obscured way .
>
>
>
> Please comments?
>
>
>
> Regards
>
>
>
> Jean-Jacques

Who would care?

The problem isn't with the language and it probably isn't with the compiler. The problem is with hardware registers not reacting in the same way a memory location would react. Read-modify-write works perfectly for RAM (assuming the compiler understands the access rules) but hardware designers create a huge problem when a register read clears certain flags as a side effect. Or the more general problem where read-modify-write doesn't work at all.

So, bit fields won't work perfectly against all hardware. Therefore, they should be ignored and hardware compliant methods used instead. For some processors, it is common to have a register 'shadow' value in RAM. This shadow value is updated and the result written to the register without a read-modify-write operation.

At least limit bit fields to RAM. There is some possibility that this might be portable. More or less...

Richard

Hi Jean-Jacques,
could you please send me your LED sample with Yagarto.

how different is WINARM from Yagarto?
I think I'll do some code converting too.
Regards,
Daniel

________________________________
From: jdauchot
To: l...
Sent: Wednesday, May 27, 2009 11:32:36 PM
Subject: [lpc2000] Re: Using Bit Field structures to access LPC-2000 registers

Hi Daniel

Effectively the LPC2478 and LPC2378 have the same register set apart from the LCD interface

I have got a basic LPC2478 project working OK based on LPC2378 code. Flashing LEDs etc

I would like to convert IAR LPC2478 LCD code projects to Yargarto tool chain.

But IAR uses those bit field structures to access registers that nobody likes for some good reasons it appears.

I have a lot work to do the convert the bit field code to more conversional instructions

Regards

Jean-Jacques

--- In lpc2000@yahoogroups .com, "Jean-Jacques Dauchot" wrote:
>
> Well I better start converting all those bit field instruction to normal
> ones.
>
> I want to convert several LCD drivers etc for the LPC-2478 STK sample code
>
> Regards
>
> JJ
>
> _____
>
> From: lpc2000@yahoogroups .com [mailto:lpc2000@yahoogroups .com] On Behalf Of
> Paul Curtis
> Sent: 27 May 2009 17:04
> To: lpc2000@yahoogroups .com
> Subject: RE: [lpc2000] Using Bit Field structures to access LPC-2000
> registers
> Hi,
>
> > I presume you had a go at this?
>
> Nope. I know better.
>
> > I had a very brief go at it and got very confused.
> >
> > So I am asking if anyone had a go
>
> As you have chosen GCC as your compiler, I suggest you do not even try. GCC
> will optimize writes to bitfields and will happily use a reduced-width
> instruction if it pleases. Like I said, don't do this.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.
> co.uk
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>
>
>



Jean-Jacques Dauchot wrote:
> What if someone or lots of people (including me) could come up with a
> standard to usie this bit field thing to access the registers on LPC2000
> chips as IAR has obviously managed in some obscured way .
>
> Please comments?

Then they would no longer be bitfields.

You would need to add ways of specifying read-only, write-only, or
read-write (probably on a per field basis), constant write(IE field
always written to a particular value), and write width at a minimum.
That's almost certainly only complete enough to be annoying.

Robert

--
http://www.aeolusdevelopment.com/

From the Divided by a Common Language File (Edited to protect the guilty)
ME - "I'd like to get Price and delivery for connector Part # XXXXX"
Dist./Rep - "$X.XX Lead time 37 days"
ME - "Anything we can do about lead time? 37 days seems a bit high."
Dist./Rep - "that is the lead time given because our stock is live....
we currently have stock."
--- In l..., Ralph Hempel wrote:
>
> What is it with bitfields that leads young or inexperienced
> programmers down this path?
>

Presumably for the same reason that they would prefer to write:

pi = 3.14159265;

instead of

pi = 0x40490FD8; // sic ;-)

Unfortunately, as many have pointed out, it is not feasible to use C
bitfields as a means of manipulating bits of hardware-mapped
registers in an unobfuscated way.

If you are interested in an alternative solution to this problem I'd
refer you to the Oberon-07 programming language - I currently am
responsible for maintaining and supporting the LPC2xxx Oberon-07
compiler.

Oberon-07 has a built-in 'SET' data type that allows you to access
individual bits by their number (i.e. MSB = 31, LSB = 0). This
allows you to go straight from the definitions in the NXP LPC2xxx
User manuals to writing code without having to do the mental
gymnastics involved in converting from bit numbers to a Hex
representation. e.g.
(* P0.2 Bits 5:4 = 01 TXD UART0 *)
(* P0.3 Bits 7:6 = 01 RXD UART0 *)
SYSTEM.GET(LPC.PINSEL0, select);
SYSTEM.PUT(LPC.PINSEL0, select - {5, 7} + {4, 6})

i.e. to clear a bit, subtract that bit number, to set a bit, add
that bit number.
The use of the pseudo-functions GET and PUT make it clear that you
are either reading a register or writing a register. They actually
generate in-line code so there is no loss of efficiency.

SET constants are versatile e.g.

{} == 0x0
{0..31} == 0xFFFFFFFF
{0..7, 24..31} == 0xFF0000FF
{0} == 0x00000001
{31} == 0x80000000

-x gives the complement of set x e.g.

-{0} == 0xFFFFFFFE

ABS(x) returns the number of elements in set x e.g. given

s := {3, 7, 10..12, 15)

then

ABS(s) == 6

The 'IN' operator lets you test for the presence of a bit e.g.

IF 3 IN set THEN ...

The inline pseudo-function SYSTEM.BIT returns TRUE if a
particular bit is SET e.g.

PROCEDURE SendChar*(CONST ch: CHAR);
BEGIN
REPEAT UNTIL SYSTEM.BIT(LPC.U0LSR, 5);
SYSTEM.PUT(LPC.U0THR, ch)
END SendChar;

etc, etc.

--
Chris Burrows
CFB Software
Armaide v2.0: LPC2xxx Oberon-07 Development System
http://www.cfbsoftware.com/armaide