C is a beautiful programming language, one that is close to the system and at the same modular, no wonder it lies at the heart of most embedded systems. Like most other languages it provides freedom in style of coding. This does not help when programs and number of programmers grow large. Therefore for ease of reading, understanding and sharing C programs among several team members, Mansi Engineering uses this simple style for C programming, which in our opinion is a good balance between simplicity and objectivity. Our programmers must print this document and have it with them at all times while coding in C.
Write clear code, using one statement per line indenting the program as shown in this example, where the opening brace of a scope starts right below the start of the scoping statement. In addition, closing brace must be in the same vertical line as its corresponding opening brace.
void Sleep(unsigned char curavg) { if (!curavg) { if (_Temp < 0) { ++_Temp; wdtcon = 0x08; //set watchdog to 0.132 sec } else { wdtcon = 0x17; //set watchdog to 2.11 sec Mode = SOUND; printf (“I am here.”); //debug } Bed(); //sleep for 0.264 sec or 4.22 sec } }
As shown above, temporary statements meant solely for one time debugging must have this associated comment: //debug
Names Avoid using underscore in a variable or function name as we recommend it to be prefixed to signed variables. Global and local constants and #define’s (including macros) must be in upper case. This rule is based on an easy to remember idea: fixed items are solid capitals. #define AGOODCONSTANT 5 const unsigned int ANOTHERCONSTANT = 6; Do not use constants other than 0 in statements without defining them. #define LIMIT 10 for (count = 0; count < LIMIT; ++count) DoSomething(); Signed variables and functions returning signed values must be prefixed with an underscore. signed float _temperature = -55; signed int _WriteTrack(unsigned char track); Global variables and functions must be named so that each word is in upper case. This alerts the reader that a variable is of global type and could be changed outside the scope of the function. This rule also separates functions supplied with standard C libararies (which are all in lower case) from user defined functions. signed int _GlobalVar = 5; unsigned char ReadDisk(unsigned char track); Local variables, other than constants must be all in lower case, and the reader could expect a sense of safety for variables in lower case. Structure member variables, other than constants must also be in lower case irrespective of the scope of the structure. signed long _localvar = 5; Array and memory block pointers must be named preferably according to what would be stored inside. Local Pointers must be suffixed with ptr and global pointers with Ptr. In addition, every array or block of allocated memory must have an associated plural variable for number of elements. unsigned char Note[] = {100,107,114,121,130}; //global array #define NOTES 5 signed char *_CommPtr = 0; //global pointer to signed char #define COMMS 100 Structure and classes must be suffixed with the word data or Data depending on whether they are local or global. Their member variables, other than constants, must all be in lower case. #define NAMES 64 #define COURSES 128 #define STUDENTS 100 struct { unsigned char name[NAMES]; unsigned char course[COURSES]; unsigned int age; unsigned int year; const unsigned int SOMECONSTANT; }*StudentDataPtr,StudentData[STUDENTS]; Typedefs must be global and suffixed with the word Type #define NAMES 64 #define COURSES 128 #define STUDENTS 100 typedef struct { unsigned char name[NAMES]; unsigned char course[COURSES]; unsigned int age; unsigned int year; const unsigned int SOMECONSTANT; }StudentType; StudentType StudentData[STUDENT]; If writing a library, prefix its name to each variable and function name (but not to structure member variables) without breaking the above rules: signed float _mylibtemperature; define MYLIBSOLID 5
typedef struct { signed char _dummy; signed char _seconddummy; }MyLibDummyType; MyLibDummyType MyLibDummyData; Inline function names must be suffixed with the word inline. Inline functions tend to bloat program memory requirements and this rule helps a reader easily identify and locate inline functions in a program. inline void ResetVarsInline(void) { DoSomething(); } Limit each variable to serve one purpose, unless short of RAM. Explicitly specify whether each variable is signed or unsigned. Do not use plurals in names except for variables that denote number of elements in an array or memory block. Do not use one letter names. For the purpose of elegance and convenience to a quick reader do not use numbers in names, rather the use of numbers must be reserved for the purpose of providing values only. There are further rules that can be devised, for example one to alert the reader the bit size of variables by suffixing something to their names, but in our opinion such rules clutter names and snatch away elegance of reading a C program.
Comments Single and multi line comments must be used freely in a C program. There should be sufficient comments to enable a reader to understand whats going on.
Documentation The main.c file must start with a brief but complete description of organization and logic and assignment of internal and external peripherals interfaced with the CPU. For example /* Project DSPPM The program runs its main thread, while timer1 and timer2 engage in their own threads. Timer1 senses and controls solenoid. Timer2 controls lights. The watchdog timer... */ Before each function a brief description of what it does, its parameters and return values must be presented.
Warnings The code must be free of compiler warnings, except that generated for a third party library. Type conversion warnings must be suppressed in full knowledge of them, using casts.
Filenames The full project must be contained in a single project folder with possible subfolders S-PROJECTNAME-2 – project folder indicating version main.c – contains the main() function, the entry point for the code main.h – main header file to be included in main.c obsolete – folder to collect obsolete files calculations.xls – calculations spreadsheet changes.txt – list of changes from previous version bugs.txt – list of known bugs status.txt – status of this version: under development, testable, frozen etc. |