Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Code Styling Guide for embedded systems

Status
Not open for further replies.

Mikebits

Well-Known Member
This is not a how to, rather a request. I look at some people code and it looks so organized and nice, where my code works, but is a total disarray. I tend to put most of my code in the main, guess I should use more functions and such. Would someone mind posting an example of how code should be organized and look, and maybe show some things not to do. Some things I wonder, where do you place your functions? In the C++ class I took I was told that functions go after main, but I have seen other code where they were at the beginning. Also, how about naming variables? I think all lower case or upper case is not good right, one exception I think is Constants. How about using 0x10C7 instead of 400d.
Do you get what I am looking for? Sort of like the do's and don't of code writing. We sort of have unwritten guidelines for schematics, but have not seen much for code. Thanks for any input.
P.S. Please use C or C++ examples, I don't know assembly:)
Mucho Gracias

Almost forgot, what about indents?
 
Last edited:
There are conventions; right and wrong ways to do it, for every language. Some wrong ways work, but they're still wrong.
If you want to do it "by the book" then you need to study the book, not other people's examples. They might be doing it wrong, even if it looks right, and works.
have a look at this. I don't do C++ so I'm not sure if that's "the book" you should be referencing, but it's somewhere to start.
 
"Spaghetti" code, a term I do not like, but which is used freely on some forums. To me there are only two metrics of performance, speed of execution and number of instructions. Number of registers used is usually a secondary consideration. One also needs to consider readability. A jump of the program counter takes the same time regardless of whether the jump is to the end of the program or something much closer. Yet for the reader, such illogical jumps can be an added source of difficulty in understanding the code.

Many programmers are excellent at meeting both standards. I have done programming for just 10 years, and very part time. Nevertheless in that time, I have seen a progression of chips. Many years ago and still with some chips, program memory is at a premium. Today, that is not of such importance, so I would put more emphasis on execution speed for chips with effectively unlimited program memory. I know that results in redundancies, but one has to set his priorities and live by them.

Except for revisions, there is no disadvantage to lengthy code that is fast.

John
 
Everyone has his/her own style. If you feel your code is disorganized, very good. This means you'll try to do better next time. One important thing is to make sure that code organization and style doesn't make code function worse.

Do: Think before you write. Test every little bit you have written as soon as possible. Use modules which you can re-use later - as time goes by and you get lots of them, the programming gets much quicker. Use the same naming convention throughout all the projects and modules. Use formatting and white space so that what you write is readable.

Don't: Listen to other people when they tell you that you must write in some particular way. Try to make your code portable to other platforms just in case. Use comments which repeat what the code does.
 
I like to stick to convention for naming variables, uppercase for constants and lowercase for variables. This way I know that LCDPORT is the address of the port and lcdport is where I write the values to - i.e. it points to LCDPORT. BTW, Microchip chose to put variables all in uppercase!! For functions I tend to capitalize individual words - WriteData, SortValues etc.

For clarity, I always use indentation and avoid superfluous comments such as var = var-2 \\subtract 2 from var
Such comments mean that you miss comments that are important.

Wherever possible I try to make the code self commenting. For this reason you end up with lots of functions with a name that describes what it does.
I put main first as that is normally the code most programmers look for first.

Mike.
 
Use comments which repeat what the code does.
NOOooo. I agreed with everything you said until this point. Comments that repeat what the code does are just clutter and dangerous as they hide the important comments.

Mike.
 
These are all great input. Although I have been in the engineering field I never really had to write code, as we had a software group that did that, and I mainly focused on the HW side of things. Now I am having to play catch up which I regret now...
 
This is a topic I love. Somebody should write a good book about this. About style and structuring code. Especially about structuring code. Some organizations have strict guides that everybody must use inside the house.
This is good reading for example: **broken link removed**
And this.. **broken link removed**
and this: http://www.literateprogramming.com/indhill-cstyle.pdf

I also love the book "21st Century C, O'Reilly" .. not necessarily about style, but "expert details" about using the language. It is not a book for experts. It is a book that pushes you to the right direction if you want to became an expert.

I try to keep my Main as short as possible. Separate "business logic"-code from the code that access hardware directly. Write as much re-usable modules as possible (data structures, data manipulation, math, etc..).


NOOooo. I agreed with everything you said until this point. Comments that repeat what the code does are just clutter and dangerous as they hide the important comments.

I think what NorthGuy meant was comments that tell you what the code does. Example from my current project at work:
C:
void
data_update_evdd(uint16_t value)
/* Update global data with new evdd reading */
{
    data.evdd_raw = value;

    /* This is the conversion (raw->volt) math ((value*4.8)/1024.0)
       Combined with conversion to 1.7.8 fixed point (multiply by 2^8)
       ((4.8)/1024.0)*2^8 = 1.2 */
    data.evdd_volt = fpmuldiv(value, int2fp(12), int2fp(10));
    rolling_median_update(&(data.evdd_stat), data.evdd_volt);
}
/******************************************************************************/

I tried to use doxygen in my comments for a while, but I hated it and never actually compiled my code into doxygen documentation. But, I am still looking for a nice way to manually write html documentation with syntax highlighting etc. I don't know any good editors that could make it easy.
 
Last edited:
I read "Use comments which repeat what the code does" as
Code:
        iorlw    0x00        ;inclusive or with zero
;rather than the more useful
        iorlw    0x00        ;set status flags

BTW, there was a very good book published in 1993 called Code Complete which we used as a standard when I was writing commercially. I see it's now been reprinted and is available as a pdf for download. Not sure on the legal status of downloading it but it's on the wordpress site which suggests it's legit.

Mike.
 
BTW, there was a very good book published in 1993 called Code Complete which we used as a standard when I was writing commercially. I see it's now been reprinted and is available as a pdf for download. Not sure on the legal status of downloading it but it's on the wordpress site which suggests it's legit.

If the pdf of the book is directly in google search results, then I think you can download it without worries. Another such book is "Expert C Programming - Deep C Secrets". Ugly book, but contains lots of interesting reading for c-programmer.
 
One tip came to my mind. I have not seen this in any books. This is for embedded programming where the main-function tends to get long and contains lots of initialization code etc.

You can structure your code into code blocks. This makes the code more readable. It also makes it easy to separate blocks into functions when they come too long. You can also enable/disable some parts of the code by adding if(1) or if(0) in front of the block.
Declaring variables inside a code block restricts their scope to that block only. In this case the pairing_timeout lives only for a short time. If it was declared at the top of the main, the variable would take up memory for the whole lifetime of the program. And, if you want to skip radio pairing, just add if(0).
C:
int main(void)
{ 
    { /* Initialize IO */
        DDRE =  0b10101100;
        PORTE = 0b00000000;
 
        DDRF =  0b10000110;
        PORTF = 0b00000000;
 
        DDRG =  0b00000010;
        PORTG = 0b00000000;
    }
 
    { /* Find radio pair */
        uint32_t pairing_timeout;
        pairing_timeout = clock_gettime();
     
        while ((clock_gettime()-pairing_timeout) < 60) /* 60 second timeout */
        {
            radio_pair();
        }
    }
 
    while(1)
    {
       /* Main-loop */
    }
}
 
Don't: Listen to other people when they tell you that you must write in some particular way.

Unless...
  1. Those other people are your employers and your company has a source compliance program you have to adhere to.
  2. You go on a forum, asking in what particular way you should be writing code, and other people provide answers.
 
NOOooo. I agreed with everything you said until this point. Comments that repeat what the code does are just clutter and dangerous as they hide the important comments.

That's why I have put them on the "don't" list :)
 
'C for dummies' by Dan Gookin is my bible , I understand a few % of it.... I work on the theory keep trying till it works...
My 'Style' could be called random....

Q should multiple { and } be in line or offset , down the code ?
 
'
My 'Style' could be called random....
I try to keep to a fixed style for appearance, but my programming skills would best be described as a "stochastic" approach. That makes it sound scientific.

I did violate one of my style requirements last weekend and paid the price of wasted time trouble shooting to find the error. Of course, this style applies to Assembly coding and mid-range and lower PIC chips. In the right-hand margin, I keep track of the Bank used for various registers, i.e., ; <spaces> |B1 . Learned that from Pommie. Well, Saturday morning, I decided to quickly change a TMR0 counter in a subroutine and didn't follow that style. Short story, I hadn't switched to Bank1 to load Option_Reg .

John
 
Q should multiple { and } be in line or offset , down the code ?

I prefer,
Code:
    if(something){
        DoSomert();
    }
I prefer this as you can fit more code on a page (less vertical whitespace) and therefore see more without scrolling. Also, you can instantly match closing braces with the line that opened them.

Mike.
 
Q should multiple { and } be in line or offset , down the code ?
I usually write them in line (aligned vertically). That way you can instantly match closing braces with the opening braces.

if/else if/else -structure is exception to this. I use whatever is most readable. Depends how long and complex the code is.

C:
if(something) {
/* We have something */
    react_to_something();
} else {
/* We do not have something */
    take_action();
}

/* I rarely use switch/case structure. I use if/else-if instead */
if     (input == 'c') { subroutine_for_c(); }
else if(input == 'b') { subroutine_for_b(); }
else if(input == 'a') { subroutine_for_a(); }
else { }

if(data_ready)
/* We have new data, process it in this complex routine */
{
    for(i=0; i<length; i++)
    {
        if (data == 0)
        {
            /* Do something */
        }
    }
}
Important thing is to always use braces. I hate to see loops and conditional structures without braces.
 
Last edited:
My code is the same as Mr T's... I like to see the curly brace pairs each one indented one tab... Identifiers that make sense.. I nearly always make my function headers the functions themselves... ie... functions first!! Function headers are wasted typing time... Remarks only where needed.. ( Some of my tutorials are way over the top, for learning purposes )..

NEVER USE GOTO....
I have never liked using goto in C... When downloading "generic" code with millions of "ifdef" statements, get rid of the ones you don't need... These are device dependent code paths, you are usually compiling for a specific device... All the if defines just clutter the works..

Most of the code you write will be for you alone, so all you need to do is make it memorable so when you return to the code in xxx years, you will be able to follow it...
 
Most of the code you write will be for you alone, so all you need to do is make it memorable so when you return to the code in xxx years, you will be able to follow it...
aint that the truth.. even return in 'x' months
Don't think I have used goto with C , sort of harps back to basic... although my assembler was littered with it... to jump out of one routine and land in another and use that code and return .... scary.
switch I like
 
NEVER USE GOTO....
I have never liked using goto in C....

I TOTALLY agree - although not just in C either, assembler is a VERY different thing, and it's an absolutely essential instruction (and of course C source produces loads of 'gotos' in the assembler code as well).

For an example I did a version of WinPicProg that contained a simple BASIC compiler, in response to a user asking me to do so, and providing me his crude Visual Basic example code for a PIC compiler. The VB code was absolutely littered with gotos, and I had to completely rewrite the code (and improved it beyond all recognition) in Delphi, getting rid of 'almost' all the gotos in the process - unfortunately there were a couple I couldn't get rid of, but by consulting the Delphi help system I was able to find that gotos are 'actually possible' in Delphi, something I never knew before :D

However, been a 'simple' BASIC goto was an important part of it :D Here's a simple code example from it:

Device 16F628
Define PortB=%00000000
Dim A, C, B
Start:
A=1
For C=1 To 8
OutB(A)
A=A<<1
Delayms(200)
Next C
A=128
For B=1 To 8
OutB(A)
A=A>>1
Delayms(200)
Next B
Goto Start
End
 
Status
Not open for further replies.

Latest threads

Back
Top