Yahoo Groups archive

Lpc2000

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

Message

Re: Looking to buy compiler

2005-11-09 by Alan Strickland

I'm aware of what IAR provides.  I have worked with IAR.  In fact I
had compiled and ran my code under IAR when I got bit.  However, the
code had been originally developed with ARM-ELF-GCC, so I didn't use
the IAR defined registers.  Anyway we aren't using IAR.

I wont use bitfields, mainly because their behavior is not standard. 
What is their endianness?  Are they signed/unsigned?  What code is the
compiler going to emit?  Will the code really work with the peripheral?

IAR and GreenHills (and I believe GCC) give options to define this,
but why use it.  I've moved code from GCC to IAR to GreenHills, and
once I punted bitfields the code ported without issue.  If I had I'd
have to remember to set options with each program I create, or futz
around with pragma's or whatever the vendor's decide to do this
week/version.  

Keeping the code as portable as possible using appropriately sized
data types helps eliminate those issues by avoiding the problem to
begin with.


--- In lpc2000@yahoogroups.com, Mike Nelson <m1k3n3ls0n@y...> wrote:
>
> IAR's Embedded Workbench for ARM provides the 
> bit field definitions for the Special Function 
> Registers for most popular derivatives in C 
> header files.  No need to worry about C compiler 
> support.
> 
> Here is the list of Philips LPC2000 derivatives
> supported:
> 
> lpc210x
> lpc2114
> lpc2119
> lpc2124
> lpc2129
> lpc2130
> lpc2131
> lpc2132
> lpc2134
> lpc2136
> lpc2138
> lpc2142
> lpc2148
> lpc2194
> lpc2212
> lpc2214
> lpc2292
> lpc2294
> 
> Also, there is debugger register display down to 
> the bitfield for all the special function registers 
> in the listed derivatives.
> 
> --- Alan Strickland <thestricnine@y...> wrote:
> 
> > I agree, avoid using bit fields.  How bit fields are
> > implemented is
> > compiler dependent.  Granted many (all?) compilers
> > give the option of
> > signed/unsigned and such, but I'd prefer to avoid
> > that issue entirely.
> >  Plus accessing individual bits can be wasteful as
> > far as code size is
> > concerned, and flat out may not give the results you
> > want.
> > 
> > Last year I had one piece of code that crashed the
> > system when it ran.
> >  I was setting up the EMC register and GPIO for
> > external RAM by using
> > bit fields, and the code died a miserable death. 
> > After I replaced it
> > with simple register assignments it worked. I
> > learned my lesson and
> > ripped out every bit field definition I had.  Bit
> > fields are in the
> > grey area of C/C++ standards and are probably best
> > left out of code.
> > 
> > 
> > David
> > 
> > --- In lpc2000@yahoogroups.com, "brendanmurphy37"
> > <brendan.murphy@i...> wrote:
> > >
> > > 
> > > At the risk of adding yet more controversy to what
> > is getting to be a 
> > > somewhat heated discussion, can I suggest that
> > access to hardware 
> > > registers is best done using something like:
> > > 
> > > 1. Define general MACRO in some hardware-specific
> > include file:
> > > 
> > > #define REG(addr) (*(volatile unsigned int
> > *)(addr))
> > > 
> > > 1. Define machine registers in some include file:
> > > 
> > > /* example is I2C control register */
> > > 
> > > #define I2C_I2CONSET  (0xE001C000) /* ctrl set reg
> > */
> > > 
> > > 3. Use as follows:
> > > 
> > > REG(I2C_I2CONSET) = 0x44;   /* set I2EN and AA */
> > > 
> > > As an alternative, you can define extra values as
> > follows:
> > > 
> > > #define	I2C_BIT_AA   (0x04)
> > > #define	I2C_BIT_SI   (0x08)
> > > #define	I2C_BIT_STO  (0x10)
> > > #define	I2C_BIT_STA  (0x20)
> > > #define	I2C_BIT_I2EN (0x40)
> > > 
> > > and use as follows:
> > > 
> > > REG(I2C_I2CONSET) = I2C_BIT_I2EN | I2C_BIT_AA;
> > > 
> > > This has the advantage of:
> > > 
> > > - it always works, regardless of compiler,
> > optimisation settings, 
> > > time of day,....
> > > - it's easy to follow (or as easy as any other
> > alternative)
> > > - it's invariably efficiently encoded by the
> > compiler
> > > 
> > > Contrast this with the number of questions you see
> > on why particular 
> > > bit-field constructs mapped to hardware registers
> > don't work, and it 
> > > might change your mind on how to do this.
> > > 
> > > Regards
> > > Brendan Murphy
> > > 
> > > P.S. On the main topic, I've used GCC on and off
> > for maybe ten years 
> > > now. I find it fine for professional development,
> > PROVIDED someone 
> > > else has set it up for the development system
> > being used (we use 
> > > Ashling for LPC2000 developments, which package it
> > nicely with their 
> > > IDE and ICE). It's not worth the time and effort
> > of doing it 
> > > yourself, unless you're into that sort of thing
> > (maybe you should get 
> > > out more if you are?). We don't use any built-in
> > library functions, 
> > > so library size isn't an issue for us. The reason
> > I like it (apart 
> > > from the cost!) is the lack of bugs in the code
> > generation, unlike 
> > > ither commercial compilers I've used. Reasons for
> > not liking it are 
> > > the usual (limited support, overwhelming
> > documentation etc. etc.). 
> > > 
> > > --- In lpc2000@yahoogroups.com, Sten <list@n...>
> > wrote:
> > > >
> > > > Àëåêñàíäð Áîðèñîâ wrote:
> > > > >>Alex, 
> > > > >>
> > > > >>
> > > > >>>b> Just one data point, but: I'm a
> > professional developer (30 
> > > > >>>years s/w 
> > > > >>>b> development experience from micros to
> > mainframes).  Now 
> > > working 
> > > > >>>on 
> > > > >>>b> third LPC-based commercial product. 
> > Compared Keil, IAR, 
> > > > >>>and gcc and 
> > > > >>>b> chose Rowley Crossworks (gcc-based).
> > > > >>>
> > > > >>>Oh, I can't hold out from the reply.
> > > > >>>I tried to use Crossworks in the begining to
> > explore LPC2xxx.
> > > > >>>It ugly work with the structures. I tried to
> > define T0MCR like
> > > > >>> struct:
> > > > >>>{{
> > > > >>>typedef struct
> > > > >>>  { 
> > > > >>>    __REG32 MR0I :1;
> > > > >>>    __REG32 MR0R :1;
> > > > >>>    __REG32 MR0S :1;
> > > > >>>
> > > > >>>    __REG32 MR1I :1;
> > > > >>>    __REG32 MR1R :1;
> > > > >>>    __REG32 MR1S :1;
> > > > >>>    
> > > > >>>    __REG32 MR2I :1;
> > > > >>>    __REG32 MR2R :1;
> > > > >>>    __REG32 MR2S :1;
> > > > >>>    
> > > > >>>    __REG32 MR3I :1;
> > > > >>>    __REG32 MR3R :1;
> > > > >>>    __REG32 MR3S :1;    
> > > > >>>    __REG32      :4;    
> > > > >>>} __txmcr_bits;
> > > > >>>
> > > > >>>#define T0MCRbits (*(volatile __txmcr_bits
> > *)0xE0004014)
> > > > >>>
> > > > >>>}}
> > > > >>>
> > > > >>>but when I handle to it, Crossworks GCC
> > compile it to this code:
> > > > >>>
> > > > >>><<T0MCRbits.MR0I = 1;>>
> > > > >>>
> > > > >>>mov r3, #0xE0000000
> > > > >>>add r3, r3, #0x00004000
> > > > >>>add r3, r3, #0x00000014
> > > > >>>ldrb r2, [r3]
> > > > >>>orr r2, r2, #0x00000001
> > > > >>>strb r2, [r3]
> > > > >>>
> > > > >>>so, I get change in LSB and
> > _in_the_second_byte_!.
> > > > >>
> > > > >>And you tell me *why* this is incorrect code
> > generation?  You 
> > > might 
> > > > >>not
> > > > >>like what is generated, but is is *not*
> > incorrect according to the
> > > > >>standard.  It is only incorrect *if* you think
> > volatile has some 
> > > > >>extra
> > > > >>meaning above what it does in the standard. 
> > Or *if* you think an
> > > > >>"unsigned long" bitfield is somehow
> > "standard".  That is why the
> > > > >>Embedded C TR has I/O support.  Volatile does
> > *not* mean "I'm 
> > > > >>dealing
> > > > >>with a device" or "Access this data
> > atomically".  Far from it.
> > > > > 
> > > > > 
> > > > > I tried to explain my point of view in other
> > mail.
> > > > > The generated code works incorrectly because
> > it use BYTE 
> > > instructions. 
> > > > > You can compile it, load into the chip and
> > debug. 
> === message truncated ===
> 
> 
> 
> 		
> __________________________________ 
> Yahoo! FareChase: Search multiple travel sites in one click.
> http://farechase.yahoo.com
>

Attachments

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.