Fundamental principles that benefit greatly from being tackled early on in the development cycle. What separates a good enough design from a great design in embedded software? A reusable, testable and maintainable code base generates tremendous value because it accelerates client support cases and new product development. Therefore, it is crucial to approach these points as soon as possible in the development cycle, as the refactoring effort increases as the code base grows.
A modular design to encapsulate components based on their responsibilities
Some may recognize this as the first of the SOLID principles. Even though the tools available to us for embedded software do not always allow us to use an object-oriented programming language, the base concept remains valid: distinct and simple components are not only more robust, but easier to modify in case of project requirement changes.
Let’s look at a typical example: a product presents a human-machine interface in the form of push-buttons and a basic, low-cost LCD that can display two rows of characters. The client for which this product was designed wants to refresh the product and replace this interface with a high resolution, tactile LCD display. If the software components responding to button events, menu navigation and information generation are all tightly coupled, the development effort for this refresh is much greater than if these responsibilities were encapsulated in separate modules.
Make the high-level logic platform-agnostic
To push the code base to the next level of reusability, the next goal is to implement the applicable modules in a way that does not depend on the architecture of the microcontroller or microprocessor of the initial project the code is developed for. Even with or without an operating system, many methods exist to allow us to reach this goal: dynamic system configuration on boot-up, pre-compiler options or simply separate system-specific access in a separate file that must be implemented when porting the code to a new architecture.
The code base can then be reused on any embedded system architecture and even in a PC application. This strategy is especially useful for serial or network communication protocols. Quickly, a developer can test a communication protocol with his embedded system by designing a simple PC-based simulator application that reuses a large part of the same code base.
An easily reusable code base accelerates new product development
This is where we reap the benefits of our diligence: a synergic effect is created from the modularity and reusability of our code base. By reusing code from previous projects, the development effort of subsequent projects is considerably reduced. Additionally, potential risks can also be mitigated because we know that the reused code is tested and works as intended.
Let's look at a generic example:
The design for a product for a client uses a serial communication protocol to exchange data between a user interface and another embedded system featuring an array of actuators and sensors. Since the embedded software developer designed this protocol as an independent module, the same protocol can then be reused in the same project to create a bootloader used to update the firmware of the embedded systems in the field.
At a later time, the same client wants to create a new product that is very similar to the previous one, but will be sold in a different market sector. Just like the previous product, there is a need to exchange data between a user interface and an embedded system. However, this new product necessitates a new type of low-cost microcontroller with bluetooth and wi-fi communication. Since the communication protocol designed in the previous project was designed in a platform-agnostic way from the start, it can be ported to the new micro controller architecture with very little effort. What’s more, as the bootloader module was also designed in a modular and generic way, it can also be reused in the new project. Thus, we now have two functional, tested and reliable modules before we even started the development for the new product.
About the author
Renaud Paquet Faucher is a embedded software developer at NOVO. What motivates him most is the opportunity to collaborate with all kinds of different expertises.