A software architecture as defined in IEEE 1471 is "the fundamental organization of a system embodied in its components, their relationship to each other, and to the environment, and the principles guiding its design and evolution." The software architecture identifies the major system pieces and identifies the inputs and outputs for those pieces. Within an architectural understanding, developers are destined to continuously rework their code and inject nasty bugs simply from not looking at the big picture. Despite the increasing complexity that many embedded products are experiencing, my interactions with a few dozen clients has shown me that software architecture is heavily neglected and in many cases misunderstood. For today, let's examine a few fundamental tips on how a software architecture can be used to improve our software.
Tip #1 - The Architecture Is the Blue Print
I have never heard a contractor that ordered steel, concrete, and windows without first having an architectural blueprint specifying how tall, wide, and the number of floors that the building will have. Just imagine building a skyscraper and saying, "We'll figure out how tall it should be once we start building it." No one in their right mind would ever undertake such a complex endeavor as creating a building without first designing what they are building. Yet, embedded software developers do just that every day.
A software architecture is the blueprint for the software. The architecture provides a developer with the boundaries and characteristics for the system just like the blueprint for a building provides the foundation, height, and important characteristics to the building contractor. A single line of production code should not be written until an architecture has been laid out for the software.
Tip #2 - Use UML
The Unified Modeling Language (UML) is a great tool developers' can use to develop their software architecture. The latest 2.0 specification contains 13 different modeling diagrams that can be used to specify every aspect for a system ranging from sequential and state modeling through deployment. For a typical embedded system developers don't need to use every diagram but can instead pick the models that provide the best insights for the product. For example, for a typical system a developer is likely to use activity diagrams, sequence diagrams, state charts, and object diagrams. Visit www.uml.org to get a deeper view into the capabilities and resources available to developers.
Firmware for Embedded Systems. Jacob Beningo will be leading sessions on HAL design for MCUs, real-time software using Micro Python, and how to create an IoT device in 45 minutes — all happening at the Embedded Systems Conference. Sept. 21-22, 2016 in Minneapolis. Register here for the event, hosted by Design News’ parent company UBM.
Tip #3 - Don't Underestimate Sequence Diagrams
Sequence diagrams are typically used to show an events sequence that occurs for the system to successful perform an operation such as transferring data or moving a motor. A developer will use these diagrams to think through a complex event series that involves multiple components or even devices. However, a sequence diagram can be a very powerful tool. Rather than simply using the diagrams as needed, they can be used to fully specify behavior and serve as a requirements document for the system.
Tip #4 - Stay Above the 15,000-Ft View
A software architecture should provide the high-level design elements and pieces not the low-level nitty-gritty details. A developer can be very tempted to use an architecture to define every little nuance for the design. An architecture should be language independent and identify the major high-level system components and their interactions. Defining variable names, language constructs, or even exact algorithms is too much detail for the architecture. The implementer still needs to have the flexibility to adapt their software for the problem at hand, and dropping down into the details can be too constraining. For this reason, keep an architectural diagram above 15,000 feet. After all, the building architect doesn't care where the white boards, tables, and chairs are going and neither should the software architect!
Tip #5 - Run Simulations
Using UML to develop a software architecture can have a unique benefit -- the ability to run simulations on the architectural model. For example, a developer can model a state machine and then run an active model on the state machine. User data can be input such as pressing buttons or even receiving messages, which cause the state machine to move through its different states. A developer can then observe the behavior and check out how the system will behave under varying conditions without ever having to write a single line of code! The potential benefits are early detection for bugs, verifying system requirements, and perhaps cost and time savings.
Development cycles always seem to be behind schedule with delivery dates scheduled for weeks in the past. Taking the time to develop a software architecture seems like a time waster. Surely just architecting as you code is far more efficient. The fact is, if time is not taken to think through the major components and their interactions, the software is doomed to late delivery, unexpected bugs, and cost overruns. The software architecture is the guiding blueprint for the software and without it, the software is destined in fall in on itself like a house of cards.
Jacob Beningo is an embedded software consultant who currently works with clients in more than a dozen countries to dramatically transform their businesses by improving product quality, cost, and time to market. He has published more than 200 articles on embedded software development techniques, is a sought-after speaker and technical trainer, and holds three degrees which include a Masters of Engineering from the University of Michigan. Feel free to contact him at [email protected], at his website www.beningo.com, and sign up for his monthly Embedded Bytes Newsletter here.