This article is for embedded software developers with good knowledge of C or C++, but struggle with large and complex projects.
If you learn developing embedded code, e.g. using the Arduino IDE, you find plenty of small example programs. It is helpful for a quick start, but as soon your project grows, help about software design is rare.
In contrast, if you learn software development for desktop applications, project structures and software design is an integral part of the learning process.
With this short article, I will give you a simple guideline, how you can build a modular structure for your firmware, which will keep your code clean and maintainable for large and complex projects.
Refactor your Code
If you start a new project, you can already prepare the structures as described. I assume in this article you already have a working firmware but need to improve the code quality.
Improving the code in an iterative process is called refactoring. Testing is an integral part of this process. After each small change, you test if the software is still working as expected.
In desktop application development, there are unit tests to ensure the integrity of smaller modules. I found it difficult to apply unit tests to embedded code, if not for small independent functions or modules. Therefore you have to use a simple run-time test of your software, to make sure it is still working as expected.
Refactoring only changes the code, but not the functionality. Even if you change names, move code around and change implementations, the function of your code stays exactly the same. It is important you either change or extend functionality or do refactoring, but never do both at the same time (or in the same commit).
Use a Version Control System
Changing your code without version history is a bad idea. If you do not already manage your code in a version control system, now it is the time to start using one.
If you never used a version control system before, use GIT and read one of the many tutorials on how to use it. There are graphical user interfaces for any operating system, so you do not have to work on the console. It does not matter how you manage your code – it is important that you use a version control system.
After each small successful change, you should commit a new version. If you run into troubles at a later stage, you can easily analyse every change you did on the code and go back to the last working version.
The Demo Setup
If you like to follow along using the real demo setup, you will need an Arduino Uno, three LEDs with matching resistors and two pushbuttons. The example code expects a circuit shown in the next illustration.
A Shockingly Bad Example to Start With
The example code to start with is something I sadly see often. Please open a second browser window with the code at the following URL:
I can not use a really complex firmware for this article, and your source code may be in a different state. Nevertheless, this example code contains most of the elements I like to discuss.
Because of the length of the code, I will just link to the full examples. The code snippets in the article should have the correct line numbers, so you can easily find the locations.Continue reading Guide to Modular Firmware