This article closes the series by examining the last step; Simulate, iterate and scale.
The last few articles have explored the five stages of designing an embedded software architecture, well, at least the first four stages. We have seen that the five stages of designing an embedded software architecture include the following elements:
There can certainly be more or less steps, but it’s neither here nor there. Instead, these five steps can help an embedded software architect define what they need to do and the general process they will follow. This article closes the series by examining the last step; Simulate, iterate and scale.
Step #5 – Simulate, Iterate, and Scale
The development of an embedded software architecture is usually not a single event during the software development life cycle (SDLC). If the embedded software architecture design was a one-time event that happened at some point, it would indicate that we know everything we need to know about the system at the beginning and nothing will change throughout the project. So far this has never happened in my ~20 years of experience and the ~150 projects I have worked on. Customers usually try to make changes almost up to the day the products ship, and in some cases even after!
Software architecture development is an iterative process. Typically, we start at the highest levels, the proverbial 30,000 foot view, and then progress to more and more detail. A good architecture is often delimited, ie divided into several independent or semi-independent domains. We can leverage simulation to test and prove for ourselves that the high-level architecture will not only meet our needs, but our customers’ needs as well. If we find issues, we iterate and improve our design.
As customer needs evolve, software architecture must also evolve and evolve. Software architecture and software development are never done. There’s always more to do, whether it’s fixing flaws, adding new features, or refactoring to improve code quality and comprehensibility. It’s common for a team to develop a base architecture that acts as a platform to build dozens of products. Such an architecture must evolve well to manage unknown future needs.
Embedded software simulation
The idea of simulating embedded software isn’t new, but if you ask developers and architects about simulation, you’ll probably hear that it doesn’t apply. In our discussion on the last blogs, we showed how a great architecture will separate the application from low-level hardware dependencies. The advantage here is that we can run unit tests without the hardware and run our application code in product simulators!
Simulation comes in many different forms. First, we can write application code modules, then create a framework that hooks onto those modules and provides us with visual feedback and logs on how the module behaves and operates. Second, we can deploy these modules to simulation hardware, allowing us to get general feedback on the system and explore its behavior. These first two options rely on the implementation of the architecture. A final simulation method is to use a modeling tool to create a model of our architecture. Modeling tools can often simulate the model and explore its behavior. Sometimes these templates can even generate code that can be used for production.
For example, I had a system I was working on that had several unique needs on how a heater behaved. A machine can manage the state of the heater based on several system parameters. I could have just coded a state machine and fought with it to get the right behavior. Instead, I created a model of the state machine and the system that powered it. I could use the model to test my assumptions about its behavior and provide special cases to understand the architectural changes needed. Once I figured out the behavior, I implemented the pattern and everything worked quickly.
Click for full size image
Embedded software architecture temptations
A good architect knows that the software architecture will evolve. Therefore, an exemplary architecture will keep the details high, allowing developers to implement the architecture as they see fit. However, a temptation gnaws at every architect and embedded developer. The temptation is to dive into the low-level details of the system and allow them to dictate the design.
For example, I was recently leading a workshop that covered user stories. When trying to formulate a user story for a feature, almost every developer immediately wondered what pin was used on the microcontroller, whether it was GPIO or a device connected via I2C. They were supposed to think about how the user interacts with the system and the needs of the user. Yet their minds immediately jumped to implementation details that were, to be frank, irrelevant!
An important tip is to postpone any low-level details that don’t need to be decided now. For embedded software developers, this idea is excruciating and doesn’t mesh well with our natural way of thinking. I often find that embedded developers need to be coached and their thinking adjusted to design a system well. Don’t give in to temptation! Let your architecture guide the implementation, don’t be tightly bound and dictated by it. Otherwise, you will find that your architecture will not scale or scale well.
Conclusions of step #5 of the design of the software architecture
Throughout this series, we’ve explored modern concepts for designing an embedded software architecture. Modern firmware for complex systems requires software architecture to be divided into hardware-independent architecture and hardware-dependent architecture. Traditional embedded software developers often struggle to do this. The struggle can be mitigated to some degree by focusing on the data assets of the systems and allowing them to dictate the design. The result is often a software architecture tied more easily to user needs, making the architecture more scalable and scalable. Additionally, a carefully architected system can take advantage of modern tools like unit testing and simulation and can be highly portable.
In these five articles, we’ve looked at some simple steps you can take to design your embedded software architectures. Keep in mind that we’ve only scratched the surface. As is often said, the devil is in the details. Nevertheless, these concepts should help you start, modernize and revolutionize your embedded software.
|Jacob Beningo is an embedded software consultant specializing in real-time systems based on microcontrollers. He actively promotes software best practices through numerous articles, blogs, and webinars on topics such as software architecture design, integrated DevOps, and implementation techniques. Jacob has 20 years of experience in the field and holds three degrees, including a Masters in Engineering from the University of Michigan.|
To learn more about Embedded, subscribe to Embedded’s weekly email newsletter.