
The days when embedded systems had to perform simple, dedicated, and manageable tasks are long gone. Features like Bluetooth connectivity, safety, security, extensive configuration options, and the merging of multiple systems into a larger one (as microcontrollers have become more powerful) cause the code base to grow rapidly. If the underlying software architecture isn't designed for this, any further changes or extensions become a gamble.
If you compare the whole thing to the construction of a house, then on top of the foundation and the floors above, a balcony is added, a dormer window is added, ... and in a very short time the architecture takes on similar excesses to our cover photo.
While dependencies can be represented in a diagram, it's no longer possible to determine with any certainty in advance what effect each change will have.
Finally, management enthusiasm is limited when time and costs get out of control.
Requirements for an architecture
Simple software
The acronym of choice is KISS (Keep it simple, stupid): The software must be simple. A complex architecture forces complex code—and this makes the software expensive in every respect (complex coding, cumbersome unit tests, time-consuming debugging). In most cases, the simpler solution is also the better one (the principle of parsimony, also known as "Occam's razor").
Focus
The basic concepts of architecture should be simple, so that limited time can be spent on the more complex topics. In a skyscraper, you don't plan each floor differently, do you?
Maintainability/Extensibility
Who can predict at the start of a project what changes or new features will come? When it comes to a successor product with a wealth of new functionality, it will come back to haunt you if software components are not extensible or interchangeable, or if responsibilities are not clearly defined or components are not distributed.
Testability
In a previous blog post, I already advocated for simulating software. You can also unit test software that is based directly on a bare metal SDK (see Blog post). But an abstraction layer (e.g., for accessing GPIOs) makes life a whole lot easier.
Distributed development
Software is probably only rarely the result of a one-man show. When simple features result in changes to many modules, developers inevitably find themselves stepping on each other's toes and constantly having to resolve merge conflicts. Aside from the fact that this is incredibly annoying, it wastes unnecessary time (and then we're back to the cost aspect again. Now I'm being annoying :).
The conclusion here again: modularity and a clear demarcation of functionality and responsibilities make work easier.
Cliffhanger
Of course, I don't want to and can't cover the topic of software architecture exhaustively in this article. Why should I? After all, there are shelves full of books, or even gigabytes, of literature on the subject. My goal is to give you food for thought, to encourage you to think in advance (this is required in medical software anyway) about what the "house" should look like, where the rooms are located, how to get from one room to another and to the different floors. And that at this point, it doesn't matter what the walls are painted or whether you want gold faucets.
In a subsequent article, I will present concrete measures on how to achieve the required goals.
In the meantime, it is worth taking a look at arch42The authors offer not only material for beginners or those looking for more in-depth study, but also a document template in various formats (Word, LaTeX, asciidoc, Markdown, EnterpriseArchitect, Confluence) and in several languages.
