EmbeddedRelated.com
Forums

IAR V2.20

Started by Martijn Broens August 1, 2003
Hi All,

A little question about IAR V2.20;
I've downloaded an example project from IAR (MSP430_C) which toggles the
LED (simple)
The thing is that IAR now uses the peripherals different than before
example.

NEW:
void a_turn_led_on (void){ P1OUT_bit.P1OUT_0=1; }

OLD:
void a_turn_led_on (void){ P1OUT |=0x01; }

Does anyone know which way would now be preferable? And why? Because
they also changed the usart registers, Timer regs etc. BTW both ways
work.


thanks,
Martijn

Beginning Microcontrollers with the MSP430

Hi Martijn,

It's a question of taste. Personally I prefer not to use bitfields for
two reasons:

(a) You're at the mercy of the compiler when assigning bitfields:

struct { unsigned int x : 1; unsigned int y : 2 } foobar;

Now, which bit is 'x' assigned to in a word? Is it bit 0 or bit 15?
You need to look up the manual for the compiler to figure out how to lay
out your structs. Also, note that ANSI C does *not* allow you to use
anything other than *int* when assigning bits to a bitfield so the
following is a NON-PORTABLE extension:

struct { unsigned char x : 1; unsigned char y : 2 } foobar;

It means that you won't be able to move your code to an ANSI-conformant
compiler. If this doesn't bother you, then by all means use those
extensions if you feel brave.

(b) Doing multiple things at once.

Say I want to flip bits 4 and 7 of P1OUT simultaneously, this is what
I'd have to write with bitfields:

P1OUT_bit.P1OUT_4 = ~P1OUT_bit.P1OUT_4;
P1OUT_bit.P1OUT_7 = ~P1OUT_bit.P1OUT_7;

Now, you're depending upon your optimizer to figure out that this can be
done with two XORs. However, as P1OUT is volatile, the optimizer can't
contract this to a single XOR because two reads are required and two
writes are required, this is the whole point of volatile. So, the best
the compiler could do is:

xor.w #1<<4, &P1OUT
xor.w #1<<7, &P1OUT

But why not write the C code like this:

P1OUT ^= 0x90; /* Flip bits 4 and 7 of P1OUT */

The compiler has zero trouble converting that to:

xor.w #(1<<4)|(1<<7), &P1OUT

It's not uncommon to use a certain set of pins on a port as a group,
e.g. bits 0-3 of P1. Say I have a keyboard column select on bits 4-7 of
P1 and a keyboard row select on bits 0-3 of P1. I'd be setting some
output and reading some inputs to scan the keyboard, wouldn't I? I've
dedicated port 1 as a keyboard port.

Now, let's write the code:



The ... isn't important, I just need to decode the assigned character
from the row & column.

Now, writing it with a set of bits is just plain unweildy:



I know which I'd use, which is more readable, which generates smaller
code, and which is more common. I don't see the worth of bitfield
assignment to port or special function registers.

-- Paul.
Hi Martijn,

Because they need to justify the prices they charge with the extra
headers that come with bugs thrown in? ;-) Just joking.

-- Paul.
Thans Paul,
exactly my point but can anyone tell me why IAR thinks otherwise??


thanks,
Martijn
> (a) You're at the mercy of the compiler when assigning bitfields:
>
> struct { unsigned int x : 1; unsigned int y : 2 } foobar;
>
> Now, which bit is 'x' assigned to in a word? Is it bit 0 or bit 15?
> You need to look up the manual for the compiler to figure out how to lay
> out your structs. Also, note that ANSI C does *not* allow you to use
> anything other than *int* when assigning bits to a bitfield so the
> following is a NON-PORTABLE extension:
>
> struct { unsigned char x : 1; unsigned char y : 2 } foobar;
>
> It means that you won't be able to move your code to an ANSI-conformant
> compiler. If this doesn't bother you, then by all means use those
> extensions if you feel brave.

Hello Paul,

Your points concerning bit fields are certainly well taken!

However, I should like to point out that your suggested extension
can be handled in a standard way, since C compilers are free to make the size
of

struct { unsigned int x : 1; unsigned int y : 2 } foobar;

be one 8 bit byte.

However, very few C compilers actually do this, so you cannot use
this method to portably describe 8 bit hardware registers such that all C
compilers will do the same thing.

Regards,

Preston Gurd
Archelon Inc.
(AQ430 C compiler)
Hi Preston,

> Hello Paul,
>
> Your points concerning bit fields are certainly well taken!

Oh, incontrovertible I'd say... ;-)

> However, I should like to point out that your suggested
> extension can be handled in a standard way, since C compilers
> are free to make the size of
>
> struct { unsigned int x : 1; unsigned int y : 2 } foobar;
>
> be one 8 bit byte.

They are, indeed.

> However, very few C compilers actually do this, so you cannot
> use this method to portably describe 8 bit hardware registers
> such that all C compilers will do the same thing.

That's right--a C compiler is at liberty to lay out and reorder members
of a struct exactly how it sees fit. As such, consider a machine that
can do nibble extraction easily (there are a few) and:

typedef struct { unsigned int y : 4; unsigned int x : 1; } foobar;

Now, the compiler can place x at bit 0 and y in bits 1-4 of foobar. But
why do that? Why not make y go in bits 0-3 of the byte which can the be
extracted with a nibble operation and place x in bit 7 so it's the sign
bit of the word? Then the optimizer can easily test x without
extracting it in many cases. The MSP430 architecture doesn't make this
sign bit optimization much of a a win, but shuffling things around in
the structure almost certainly will be a win in many cases.

Could always move the discussion to comp.compilers...
-- Paul.
Paul Curtis wrote:
> That's right--a C compiler is at liberty to lay out and reorder members
> of a struct exactly how it sees fit. As such, consider a machine that
> can do nibble extraction easily (there are a few) and:
>
> typedef struct { unsigned int y : 4; unsigned int x : 1; } foobar;
>
> Now, the compiler can place x at bit 0 and y in bits 1-4 of foobar. But
> why do that? Why not make y go in bits 0-3 of the byte which can the be
> extracted with a nibble operation and place x in bit 7 so it's the sign
> bit of the word? Then the optimizer can easily test x without
> extracting it in many cases. The MSP430 architecture doesn't make this
> sign bit optimization much of a a win, but shuffling things around in
> the structure almost certainly will be a win in many cases.
>
> Could always move the discussion to comp.compilers...
> -- Paul.

No! No! keep it here, I love to see how portable C is, and how having an
international standard compiler makes things so readily portable.

;@}

Couldn't leave it alone now could I?

Al
Al,

> No! No! keep it here, I love to see how portable C is, and
> how having an
> international standard compiler makes things so readily portable.
>
> ;@}
>
> Couldn't leave it alone now could I?

You can write non-portable code in any language. Using a high-level
language does not guarantee portability, as we're all aware.

And anyway, I don't see MSP430 assembler as any more portable.

-- Paul.
Now now, you know I'm only joking ;@}. I should have said how having a
standard clarified and simplified things.

Al
Al,

> Now now, you know I'm only joking ;@}. I should have said how
> having a
> standard clarified and simplified things.

I don't think the C90 standard clarifies all that much for implementors
or users. :-( The death of Modula-2 I lay directly at the feet of the
ISO standard which meant that implementors needed to understand VDM-SL.
And even the VDM-SL wasn't bug free. The C++ standard is a mere bagatel
in comparison.

Standards are all well and good, but all MSP430 compilers have sprouted
extensions to do things you want to do with a micro. I can't see these
things ever getting standardised. I'd rather knaw off my own right leg
than go to another ISO standards meeting. ;-)

-- Paul.