C embedded programming books?

Hi all

I have experience with Assembler programming on embedded system, and now going to learn some C embedded programming.

Can anyone recommend some good books?

Thanks

Je-Rock

Reply to
Je-Rock
Loading thread data ...

Kernighan & Ritchie 2nd edition. The End.

Differences: - Avoid the heap. Embedded and heap are tricky bed-partners. - File I/O is usually irrelevant. Not always; usually. - putchar, printf, getchar (etc) are provided by user-supplied routines, often using serial comms. - Hardware I/O will again be user-supplied. (Avoid bit-fields; use masks.) - You'll have more control over physical placement in memory, and you'll need to understand the compiler-specific directives that place things. - As always, use module scope as a means of decoupling, and avoid global variables where possible. - Otherwise, C is C.

Must dash. Someone is playing "Freebird" in my kitchen.

Steve

formatting link

Reply to
Steve at fivetrees

In article , Steve at fivetrees writes

I think I'd make that clearer for the less experienced reader by saying "avoid C bit-fields", not to be confused with bit types in some C compilers that allow generation of code that uses the underlying bit addressing instructions offered by some architectures - something which is highly recommended for efficiency.

Reply to
Bob

If I am not mistaken, K&R2 doesn't cover C99 which has lots of good stuff (var-sized arrays, designated initializers, to name a couple). Is there a decent C99 text? Please, share.

- Ark

Reply to
Ark

c99 is irrelevant for embedded work. There are not any compilers that implement c99. That includes compilers who do use a C99 compliant front end.

Embedded compilers work around C95. K&R 2nd Ed is what most people used before there was anything better. In the intervening 15+ years since it was published the language has moved on there are many better books.

For embedded you will probably need a book that is chip specific as the compilers for most embedded work have many extensions that are requir4ed to make good use of the hardware.

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
/\/\/ chris@phaedsys.org      www.phaedsys.org \/\/\
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris Hills

Sorry, I must remember to remove all the C99 stuff from my code, since my compilers apparently don't support it. I can't imagine how I've managed to persuade a range of embedded compilers to accept things like // comments, or mixing declarations with statements and other such C99 features. And I'll have to cut out all my "static inline" functions and go back to good old macros.

Back here in reality, a lot of embedded compilers support most of the useful enhancements of C99. There are few (if any) that could claim complete C99 support, but in practise many C99 features are not needed in embedded systems.

But Chris is right that you need to read details for your specific compiler. There are always target-specific features (such as for hardware access, data in flash, interrupt routines, and inline assembly), and different compiler vendors have different general-purpose extensions (gcc, for instance, has a number of very useful extensions - using them makes the code non-portable, but perhaps smaller, faster, or easier to write).

Reply to
David Brown

Grow up.

There are VERY few ( I think 4) compilers that are C99 compliant. The rest work around C95 That is C95 with C99 few bits added. The // is one of the few things they all support. Though I have come across some differences on how they handle the line ends with defines and macros.

However depending on which compiler you have some support some bits of C99 others don't.

Those two well defined terms "most" and "useful" :-)

I think 4 do.

So they are not implemented and back to my original point that was you are better off looking at C95 and your compiler documentation for the extensions.

Yes... and C95 NOT C99.

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
/\/\/ chris@phaedsys.org      www.phaedsys.org \/\/\
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris Hills

An almost universally overlooked issue which alone calls for some C99: In the embedded world, we all use static const data structures, arrays in particular. This saves runtime initialization (speed and footprint) and RAM (footprint and, arguably, robustness). So, say foo[] in foo.c contains the good stuff and the useful indices into it are published in foo.h. The trouble is, there is no guarantee whatsoever that those indices remain correct in the course of maintenance (additions and deletions): nothing in the build will break. Instead of C

Reply to
Ark

Huh?

I don't get it. If the indices are defined (once) in foo.h, foo.c *surely* depends on foo.h.

If they're defined twice, all bets are off. (Indeed, I'd fire the programmer, and find somone to write good code.)

Am I missing something?

Steve

formatting link

Reply to
Steve at fivetrees

Yes you are. In C

Reply to
Ark

Why?

-Le Chaud Lapin-

Reply to
Le Chaud Lapin

Not if you do it the simple, naive way, right. But it's quite possible to get the C89 preprocessor to fix this problem for you, by a slight detour. So no need for C99 or yet another preprocessor:

foo_init.h: EXP(GOOD) EXP(BAD) EXP(INDIFFERENT)

proprecess this one with a definition of EXP that is

#define EXP(foo) INDEX_##foo

and let the result of this preprocessor run become part of foo.h:

enum { # include "processed_foo_init.h" };

or even do it in place:

#define EXP(foo) INDEX_##foo enum { #include "foo_init.h" };

In foo.c, #include foo_init.h again, but this time like this:

#define EXP(foo) foo const foo_t foo[] = { #include "foo_init.h" };

And that's before you consider that, if you're going to address the elements of that data structure by what is effectively a *name*, rather than by an actual computed number, then an array may not be the right data structure to begin with, and a struct would be in order.

--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker

Because it depends on the compiler how the elements of a bit field are aligned in memory.

I think it's sad that even 30 years after its invention C does not have a usable implementation of bit exact placement of variables. Compare Ada:

for SPI_Config use record CPOL at 0 range 0..0; CPHA at 0 range 1..1; CLKDIV at 0 range 5..10; end record;

...

SPI_Config := (CPOL => 1, CPHA => 0, CLKDIV => 4);

SPI_Config.CLKDIV := 4;

Reply to
Andreas Schwarz

Their is a downloadable embedded C book on our website

"First Steps with Embedded Systems"

formatting link

Walter Banks Byte Craft Limited

Je-Rock wrote:

Reply to
Walter Banks

Dear Banks,

Thanks very much for the book.

--shankar

Reply to
Shankar Pokharel

Dear Banks,

Thanks very much for the book.

--shankar

Reply to
Shankar Pokharel

Nor does it allow you to lay out other types of fields within structures. When I complain about that the proponents of C usually berate me for trying to do low level stuff in C. They seem to think it's a high-level application development language rather than a device-driver and hardware-bashing language. I think they're deluded. It's understandible that a language like Python wouldn't support user-specified bitfields or structures.

"C: it sucks at both high-level _and_ low-level stuff"

--
Grant Edwards                   grante             Yow!  By MEER biz doo
                                  at               SCHOIN...
                               visi.com
Reply to
Grant Edwards

Parsing from the end: arrays were just an example: Structures have the same initialization problem if the (some) members have same types. Defining the same macro name differently is a cure much worse than the disease. All regulated industries prohibit this outright AFAIK. Same goes for file inclusion inside a statement. The mere fact that it is technically possible does not mean it's a good idea, like, say, letting a fart out on a job interview. Cf. Safer C and lots of other sources. All I was saying is C99 is not insignificant to be brushed off.

Regards, Ark

Reply to
Ark

Hello Chris. You say you know of 4 C99 compilers..... lets list them here for the C. A. E. members. Imagecraft has a new C99 preprocessor for their family of compilers... AVR, HC12, ARM, MSP430. GCC has many C99 things like and 64 bit longs. Anyone add to the list?

Reply to
BobG

... snip ...

Maybe I don't see the problem, but it sounds to me as if the definition of INDEX_GOOD doesn't belong in any .h file, but with the definition of foo[], right in the c source file. If other modules need access to those particular indexed entries, then they should do so via a function, again in the .c file, and that function can be propagated via the .h file.

static int foo[FOOSIZE]; enum foodex {FOOBAD, FOOGOOD, FOOINDIFFERENT};

int *foobad(void) {return &foo[FOOBAD]} etc.

Now all the .h file needs is prototypes for foobad and friends. The users can use:

if (*foobad(void)) .... or *foobad(void) = something;

and you can absorb the void etc in

#define BADFOO *foobad(void)

although I would recommend not doing so.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
More details at: 
Also see
Reply to
CBFalconer

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.