Sure, I know about such abstract like "mask".
But maybe I want to use struct...
Regardless of this, thank you for your answer.
> 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:
>>
>> \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd 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/
>>
>> ************************************************/
>>
>
>
>
>
>
>
>
> ------------------------ Yahoo! Groups Sponsor
>
>
> Yahoo! Groups Links
>
>
>
>
>
>
>Message
Re: [lpc2000] Re: Looking to buy compiler
2005-11-08 by ????????? ???????
Attachments
- No local attachments were found for this message.