From time to time, I like to offer a little guidance to embedded software developers on various aspects of coding. As always, they are not hard and fast rules, just my suggestion for the best way to do something. I am always open to comments and suggestions and other tips to share. Please comment or get in contact via email or social media. I have 3 tips today …
If an external variable is local to a module, make sure that you declare it as static
As a general rule, global variables are not considered to be a Good Thing. They represent a very fuzzy interface between different parts of a software application. It is usually suggested that passing data using function parameters or using RTOS inter-task communication objects is much cleaner, clearer and maintainable. However, there is a possible exception. A group of related functions within a C module [file] may benefit from sharing some key data. If you employ this approach, make sure that you qualify the declarations with the keyword static to localize them to the module. This keyword is somewhat confusing, as it is used in a number of ways in C/C++. I wrote about this in more detail a while ago.
In a real time system a delay loop is rarely the best approach to timing
If you are constructing a very simple embedded application by hacking some assembly language, there are many shortcuts to just getting something to work. A common factor of many such practices is a lack of scaleability and maintainability. Making a small change somewhere in the system can damage its functionality. As soon as an application goes beyond being quite trivial, it is essential to focus on maintainability and scalability. A good example is the implementation of a time delay. In hacked code, a simple loop does the job – you know the timing of instructions and the clock frequency, so it is quite easy. In a more complex application, where an RTOS is in use, it is essential to use the facilities provided by the kernel. This is a topic that I covered in more detail recently.
In a C function prototype, always give the parameters names and make them meaningful
In C it is really good practice to include prototypes for all functions; in C++ it is mandatory. Their use helps avoid errors and provides additional readability. There are basically two ways to draft a prototype. You can just show the parameter data types:
void setaxis(int, int, int);
Or you can also provide dummy parameter names:
void setaxis(int x, int y, int z);
IMHO, the latter approach is an aid to readability, as you can give a clue as to the functionality of each parameter, so I strongly favor it. This is the view taken by some programming standards, like MISRA C. On the other hand, the CERT C standard does not like this form. I guess you choose which works best for you.