3 Overlooked Embedded Software Elements
Have you ever wondered, while you and your team are busy writing software if the foundation of how embedded software systems are built has changed and left you in the dust? What if while you were busily focusing on getting your product out the door, fighting bugs, and dealing with supply issues, there were techniques and processes that you completely overlooked that could save the day? I’ve found three elements embedded software teams often underutilize that could dramatically improve their software.
The overlooked elements can be seen below in Figure 1. Take a moment to look at the figure and identify the missing pieces from your software.
Figure 1 – Modern embedded software is built upon several layers of autogenerated tools that configure the platform, software model, and product features.
I suspect many of you have the blocks in gray that include Platform Configuration and the light blue section labeled Handwritten Application Code. But what about the rest? Now, let’s dig in and explore how the three overlooked elements, Configuration Management, Modeling Tools, and Test Harnesses, can help you.
Element #1 – Model Generated Code
A modeling tool can help you build out a visualization of critical pieces of your software system. From that model, it can be possible to simulate the behavior off-target to tweak behavior, features, etc. You can then convert the model to target-specific code with a functional model! If the model needs to be tweaked, it can be done off-target, and then a button click or two can regenerate the target code.
You can gain a huge advantage in development costs and time-to-market by leveraging tools that model embedded software; However, many teams overlook their use. There are a few outdated arguments developers use, such as:
- The generated code is garbage
- The tools are too complex
- The tools cost too much
Perhaps some tools still have these issues, but over the last few years, I’ve seen tremendous strides being made that have decreased costs, simplified the tools, and dramatically improved the autogenerated code. Even when some of these arguments hold, is the overall net benefit still in your best interest? You’d have to do a trade study, but I would put money on it that it probably still is.
Element #2 – Configuration Generated Code
The second often overlooked element in modern embedded software is how teams configure their products. During my many hours reviewing code for dozens of companies, I often see teams failing to develop a strategic method for configuration management. Most companies have multiple products SKUs that reuse significant portions of their code. I often see code that uses copy and pastes and many conditional statements to compile code into and out of a codebase conditionally. The trick is to develop and include autogenerated configuration code specific to your product that you integrate into your build system.
For example, there might be a product that has three different SKUs. Each SKU may have various tasks due to specific sensors being present, headless, etc. Instead of conditionally compiling or duplicating the code base for all three, the differences can be coded into a configuration file that is used to generate the code automatically. The developers can then use their build system to specify which SKU they want to generate and build. Alternatively, you can build out your SKUs in different repositories that use git modules to create the SKU-specific repository and build out the DevOps pipelines for each SKU.
A simple block diagram of how the configuration-generated code works can be found below in Figure 2.
Figure 2 – Configuration management can be done using configuration files, templates, and a script that creates the final code modules.
Element #3 – Test Driven Code
Automated testing is the last area that is often overlooked, and rarely considered. Unit testing and automated testing have found their way into nearly all areas of computer engineering, but it still struggles to gain adoption within the embedded systems space. While test code and harnesses are not part of your code per se, they can dramatically improve your software quality and help you catch bugs quickly if appropriately leveraged.
For example, I was recently working on a project where I developed a packet decoding module. The customer required a significant update to the packet’s protocol, which required updating the code. Even though the protocol was different, the interface stayed the same, and many of the tests could be used as-is or with slight modification. As I made my updates, I ran my test harness and discovered that not all the tests were passing. I had overlooked a corner case, but my tests caught it! If I didn’t have my tests, I probably would have pushed the updates and introduced a bug just waiting to wreak havoc on the system at the worst possible time.
Getting in the habit of writing unit tests and building test automation into your DevOps can make a difference. The trick is taking the time to invest upfront so that you can take advantage of it later on. It’s the classic case of the tortoise and the hare; it feels like you’re going slow, but you’ll win the race in the end.
I know how much you have on your plate, and it can be hard to stay up to date or find time to implement the latest technologies in your development cycle. However, the three overlooked elements in modern embedded software are areas that can help you manage your projects better, accelerate timelines, and improve your chances of delivering your products on time. I hope this post gives you a few ideas on where to focus your improvements in the future.
So, specifically to modeling and automatic code generation, let me mention the video lesson "#41 State Machines Part-7" Automatic Code Generation", which explains how to generate code for hierarchical state machines and also classes in C.
Can you give examples of the tools you're referring to and/or real-world examples? I use a couple tools but would like to know specifically what you've got in mind here.
There are lots of possible tools out there.
For modeling, you could use tools like Matlab, Visual State, Enterprise Architect, and so forth.
For testing, I like to use cpputest, but there are also unity, ceedling, and other test harnesses. I like to use Gitlab or Jenkins for CI/CD.
Those are a few that immediately come to mind.
Thanks for the questions
To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.
Please login (on the right) if you already have an account on this platform.
Otherwise, please use this form to register (free) an join one of the largest online community for Electrical/Embedded/DSP/FPGA/ML engineers: