Reply by Paul Curtis August 2, 20032003-08-02
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.

Beginning Microcontrollers with the MSP430

Reply by onestone August 2, 20032003-08-02
Now now, you know I'm only joking ;@}. I should have said how having a
standard clarified and simplified things.

Al
Reply by Paul Curtis August 2, 20032003-08-02
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.
Reply by onestone August 2, 20032003-08-02
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
Reply by Paul Curtis August 1, 20032003-08-01
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.
Reply by Preston Gurd August 1, 20032003-08-01
> (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)
Reply by Martijn Broens August 1, 20032003-08-01
Thans Paul,
exactly my point but can anyone tell me why IAR thinks otherwise??


thanks,
Martijn
Reply by Paul Curtis August 1, 20032003-08-01
Hi Martijn,

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

-- Paul.
Reply by Paul Curtis August 1, 20032003-08-01
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.
Reply by Martijn Broens August 1, 20032003-08-01
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