A quick c programming survey question

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
A quick question I would like to collate answers from.

As an embedded engineer you have to access individual bits
from hardware registers (or similar) from time to time (up
to, very often).

Do you (your company) prefer to:

a) Create a 'bits' structure for each register and access using
the dot or arrow operator.

b) Create a set of bit access functions (or perhaps macros)
and access using those?

For now, please confine your answer to simply 'a' or 'b',
don't attempt to justify it, as I don't want other's to be influenced
by your reasoning.

Once I have a few answers I will explain why I have asked
the question in this way

tia

tim











Re: A quick c programming survey question

Quoted text here. Click to load it

  Tim,

  We use A and B.

  Our embedded code is largely Forth so hiding some bits with a name
makes sense.  At other times knowing bit relationships takes precedence
and that method is used.  'Bits' is a nice concept to discuss, but there
are many ways to group and access 'bits' so it seems fair to report
that both methods (and perhaps others) have their uses too.

  David

Re: A quick c programming survey question

Quoted text here. Click to load it

inline!?  Surely this is what 'b' does except that you hide the
complexity


Quoted text here. Click to load it

Assuming that you are sure you can do this.
I think that here in Europe there is much less of a 'hire the
previous guy again' culture (it happens, but it isn't the 'normal'
mode).  Most external resources are people new to the manager
and how can he tell if he can trust the guy (or gal) to 'do the right
thing' - except by asking him "what's the best way to..." questions
similar to this one at interview :-)


Quoted text here. Click to load it

"don't worry" because you know that they will do it right,
or because it doesn't matter (as long as it works)?

tim





Re: A quick c programming survey question

Quoted text here. Click to load it

What planet do you live on, where this comes as a surprise?  I would be very
surprised if the most popular method was not something like "PORTB |=
LEDMASK" or "PORTB &= ~(1 << LEDBIT)", closely followed by the ever popular
"PORTB |= 0x02; /* Turn led on */".

Remember also that your sample audience here is biased - you are asking
those embedded programmers who are smart enough to discuss and share ideas,
and who are therefore more likely to use better solutions.  The vast
majority of embedded development tools and example programs encourage
bitmasks (just look at the compiler/library header files), and for many
compilers and targets it is the method that generates most efficient code.
Wrapping these constructs in functions is often painfully inefficient and
run-time, and using macros is an *extra* level of complexity, not a
reduction of complexity (although it is a great boost to the readability and
reliability of the code).

Quoted text here. Click to load it



Re: A quick c programming survey question

Quoted text here. Click to load it


It didn't come as a suprise that people use it.

It comes as a suprise that people would 'recommend' it.

Quoted text here. Click to load it
like

two code lines when it could be one.  Reading and testing is even more
messy

Quoted text here. Click to load it

No comment.:-)

Quoted text here. Click to load it
ideas,

I am (sometimes painfully) aware of that, (and thus all the more suprised
that someone would recommend the above)

Quoted text here. Click to load it

I never said anything against bit masks.   It's the and-ing and or-ing
inline that I have a problem with.  This complexity can easily be
'hidden' in a function or macro (the parameters to which can be
the masks if you wish) and experience tells me that an optimising
compiler (plus auto-inlining) can produce *exactly* the same assembler
code as your method.

Quoted text here. Click to load it

it should not be.

Quoted text here. Click to load it
and

Exactly.

The macros are a once-only process, yes this is relatively complex
but you only have to get it right once.

Reading source is an everyday occurrence,  IMHO you should handle
complex tasks once and not move then to the everyday function.

tim



Re: A quick c programming survey question

Quoted text here. Click to load it


You don't understand.  That was two separate examples.  The
first one set a bit.  The second one cleared a bit.  The two
examples use slightly differnt semantics for creating the
bitmask.

If you can reduce that to 1 line of code, that means that
you've figured out how to either set a bit or clear a bit using
zero lines of code.

Quoted text here. Click to load it

I didn't have any problem reading it.  I guess you did, so
you're point may be valid.  However, I expect all competent
embedded devlopers to know what both

 varible |= whatever;
 
and

 variable &= ~whatever;

There's really no excuse for not understanding what those two
lines of code were doing.

Quoted text here. Click to load it

I don't see any difference at all in comlexity between:

  variable |= something;

and

  SetBits(variable,something);

Both have two values and one operator.  One is infix notation,
the other is prefix/functional notation.  I, for one, recognize
the first form more quckly than the second.

--
Grant Edwards                   grante             Yow!  I guess you guys got
                                  at               BIG MUSCLES from doing too
We've slightly trimmed the long signature. Click to see the full one.
Re: A quick c programming survey question

Quoted text here. Click to load it

Sorry, I realised that later.  I though that you were describing
the clear-set operation required of a generic multi-bit field.

Quoted text here. Click to load it

I'm counting source lines,  I agree there will be a number
of assembler lines as a result

Quoted text here. Click to load it

I meant reading the bit.  If you require a 'normalised'
result it requires more source lines.

Quoted text here. Click to load it

There is still scope for someone making a mistake and it then
being passed over as correct in a desk check.

No-one is going to read:

SetBit(...)    /* clear bit x */

without passing comment.

Quoted text here. Click to load it

As above setting a bit is the easiest of the required operations.

tim


Quoted text here. Click to load it
got
too



Re: A quick c programming survey question
I'd probably take it one step further:

#define    sbit(bit,port)     port  |=  (1 << bit)
#define    cbit(bit,port)     port &= ~(1 << bit)



#define    LED_ON          cbit(LED,PORTB)
#define    LED_OFF         sbit(LED,PORTB)

#define    SPI    PORTB

#define    ASSERT_CS        cbit(SS,SPI)
#define    DEASSERT_CS    sbit(SS,SPI)
#define    CLOCK_HIGH    sbit(SCK,SPI)
#define    CLOCK_LOW     sbit(SCK,SPI)
#define    SPI_OUT(data)    {   if(data & 0x80) {\
                                                    sbit(MOSI,SPI);\
                                                } else {\
                                                    cbit(MOSI,SPI);\
                                                }\
                                                data += data;\
                                            }

Then coding becomes much nicer.

            ASSERT_CS;
            for(i = 0; i < 8; i++) {
                CLOCK_HIGH;
                SPI_OUT(data)
                CLOCK_LOW;
            }
            DEASSERT_CS;



--
Best Regards,
Ulf Samuelsson   ulf@a-t-m-e-l.com
We've slightly trimmed the long signature. Click to see the full one.
Re: A quick c programming survey question
You'd really write code like that?  I dislike having computers shout at me.
All caps macros may be traditional in C programming, but so are missing
declarations defaulting to "int", lack of comments, and "if (x = 1)" bugs.

Sometimes it is useful to write individual macros like these (especially
when you are not sure of the polarities of signals before testing), but I
think it is a help to consistency if you use parenthesis on all macros:

#define ledOn() cbit(ledBit, PORTB)

That way you can more easily change things in the future, such as changing a
macro definition to an inline function call (I mostly prefer "static inline"
functions to macros, if the compiler handles them well).

And put parenthesis around "bit" in your bit macros, for safety (that's one
of the reasons I prefer static inline functions).


Quoted text here. Click to load it



Re: A quick c programming survey question

Quoted text here. Click to load it

That makes a lot of difference ...

Quoted text here. Click to load it

They were meant as two seperate examples.

Quoted text here. Click to load it
code.

Which "optomising compiler plus auto-inlining" can produce exactly the same
assembler code when using function wrappers?  I have close to a dozen
compilers, used for various different processors, and *some* will do this
well.  Others won't.  If I had an unlimited tool budget, then I guess I
could get compilers that have good enough optomisers for many of the
targets, but I don't always get everything that I would like.  Thus I might
use functions on one target and macros on another - I'm not interested in
trying to get perfect consistency to match the myth of C portability
(although the macros I use most of the time are actually quite portable in
use, though not in definition, across several compilers and even several
assemblers).

Quoted text here. Click to load it
and

Complain to the compiler vendors, or write better tools yourself - or work
round it by learing to know your compiler and your target processor, and
adjusting code to suit.

Quoted text here. Click to load it

They are not a once-only process - they are a once-per-compiler-target-pair
process, since the constructs needed to generate good code while retaining
the ideal of having both the byte address and bit number (or bit mask)
paired in the same definition will vary too much.

Quoted text here. Click to load it

Close, but not quite (IMHO, of course :-) - readability is paramount, and
complex tasks should be handled as often as necessary, but not more often.
Trying to reduce the complexity too much is counter-productive - it's like
setting the national speed limit to 30 miles per hour in the hope of
reducing road deaths (beneath all arguements lurks a car analogy...).

Quoted text here. Click to load it



Re: A quick c programming survey question

Quoted text here. Click to load it

Yes.


Yes.

Your point?

--
Grant Edwards                   grante             Yow!  Are you still
                                  at               SEXUALLY ACTIVE? Did you
We've slightly trimmed the long signature. Click to see the full one.
Re: A quick c programming survey question

Quoted text here. Click to load it

so why not just select 'b'?

Read the summary to be posted shortly and you'll see why
it is important.


Quoted text here. Click to load it
you
REINFORCEMENTS?



Re: A quick c programming survey question
Quoted text here. Click to load it

Because I find that the forms

 port |= whateverBit;

and
 
 port &= ~whateverBit;

to be the most clear and readible.

However, if setting a multi-bit field, then the struct
bit-field approach or the macro approach is often more readble:

 value.clockSel = 2
or
 SetBitField(value,ClockSel,2)

rather than

 value &= ~(7<<3)
 value |=  (2<<3);

--
Grant Edwards                   grante             Yow!  BARRY... That was
                                  at               the most HEART-WARMING
We've slightly trimmed the long signature. Click to see the full one.
Re: A quick c programming survey question
Quoted text here. Click to load it

B.



Re: A quick c programming survey question

Quoted text here. Click to load it

d) All of the above (including c, for some various values of c), depending
on the target.




Re: A quick c programming survey question

Quoted text here. Click to load it

I know that I missed it out of the question but there is no 'depending
on the target' allowed.

The requirement is for a method that you always use for all platforms
and  the question is really one of "which is the best compromise".

This will all be clear when I post the summary shortly

tim


Quoted text here. Click to load it



Re: A quick c programming survey question

Quoted text here. Click to load it

I hope I never have to work with you.  Absolute rules like that
are a sure way to produce bad results.

--
Grant Edwards                   grante             Yow!  My mind is making
                                  at               ashtrays in Dayton...
We've slightly trimmed the long signature. Click to see the full one.
Re: A quick c programming survey question

Quoted text here. Click to load it

Sometimes perhaps, but in this case I think it justified.
It isn't just the portability of absolute code that is important.
It is the portability of the ideas across a department.
If the team of people working on one processor use a different
method to the team working on a different processor it makes
it much harder for individuals to review code across projects

tim


Quoted text here. Click to load it



Re: A quick c programming survey question
Quoted text here. Click to load it
depending

I'm certainly curious about what you're looking for!  I wonder how much it
relates to real-world embedded programming, where there is always a great
deal of target-dependant variation in programming methods, or to some ideal
world in which the lowest common denominator of all targets is good enough
(and thus you end up with an Arm processor controlling a light switch...)




Re: A quick c programming survey question



Quoted text here. Click to load it
ideal

If youb haven't now seen the answer ask again

tim




Site Timeline