Yahoo Groups archive

Lpc2000

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

Message

Re: Looking to buy compiler

2005-11-08 by brendanmurphy37

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. We discuss 
compiler 
> > for ARM core, or what? I think IAR, Keil compilers know about 
data 
> > access in the ARM core.
> > 
> 
> This behaviour is not bug, it's really a feature. GCC is optimizing 
the
> accesss to this bit-field to a minimum. Loading and storing only 
_one_
> byte for modifing only _one_ bit is a very good optimization on 
designs
> with external memory, which is not 32bit wide, to minimize memory 
access
> cycles. GCC doesn't know that a certain register _must_ be accessed 
with
> 32bit (with or without "volatile") and C standard does not say that 
a
> bit field manipulation is forced to be a 16bit or 32bit access. What
> should happen, in your opinion, if you declare a bit field with more
> than 32 bit??? How should it be handled?
> With other words: Compiler which are using a 32bit access for such 
a bit
> field manipulation lacks an optimization feature!!!
> 
>   Sten
> 
> -- 
> /************************************************
>  Do you need a tiny and efficient real time
>  operating system (RTOS) with a preemtive
>  multitasking for LPC2000 or AT91SAM7?
> 
>    http://nanortos.net-attack.de/
> 
>  Or some open-source tools and code for LPC2000?
> 
>    http://www.net-attack.de/
> 
> ************************************************/
>

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.