Embedded systems are ubiquitous in today's technology-driven world. Be it an internet-connected shaver or a complex automobile, embedded devices are at the heart of most electronic devices that we use today. Comprised of one or many microprocessors, embedded systems can simplify electronics by offloading complexity to be handled by software.. As embedded devices become larger and more complex so do the printed circuit boards (PCBs). Quite often these devices grow into multiple boards and become larger assemblies than originally intended.
In this article we’re going to peer into the architecture trade-offs and considerations for embedded systems consisting of multiple PCBs. We’ll cover the benefits, design considerations, and challenges associated with multi-PCB systems.
While keeping your device to a single PCB is the ideal option (both for simplicity and cost), we sometimes have to make the plunge to split our design into two or even more PCBs in order to achieve our design goals. Some reasons why we would want to break out product into multiple boards include:
For these reasons (and more) we consider designing an assembly that is comprised of multiple PCBs but the challenges with the embedded firmware side are not without their complexities.
Now that we’ve established the case for using multiple PCBs (where applicable) it’s important to understand the design considerations when architecting the embedded system. Both from a hardware and software perspective there are nuances that we don’t tend to weigh as carefully when putting everything onto a single board.
The first consideration that should pop into our minds is inter-board communication. How will each board talk to one another? What kind of processing power (if any) lives on each board? Perhaps one board consists of the brain while the others consist of the sensors? As we carefully pick our transmission protocols, be it I2C, SPI, UART, Ethernet, etc., we also must weigh the transmission lines, signal integrity, and most importantly, signal transfer through inter-board connectors. The worst thing that can happen to a designer (and trust me, I’ve been there) is to design the full system and receive back your PCBs from the manufacturer only to realize you missed a clock signal or two. We also tend to forget to keep spare pins on our inter-board connectors, attempting to squeeze every pin count to the max. This is something that can really bite us in the end. Designing with a multi-board project in mind, such as the Multi-Board Assembly feature in Altium Designer, is a must when routing so many communication lines between PCBs.
We also need to think about how we plan to distribute power, especially if we will be monitoring power buses with our microprocessor. We want accessibility to the “brain” to allow it to monitor for any catastrophic events, but we also need to consider switching supply noise, power distribution for heavy loads, and if our inter-board connector pins are rated for that kind of power.
Lastly, while it’s not directly related to the software itself of the embedded system, the mechanical design also plays an important role. Push buttons, touch screens, and other physical interfaces to the user still connect to the microprocessor and must be taken into consideration. Can the wiring be routed in such a way that the microprocessor can access its inputs? Have we considered the signal integrity of the high speed digital output as we pass it through from one board to another? These are things we have to think of when architecting our embedded device.
One of the most understated challenges that I’ve seen time and time again in scaling startups (and even large companies) has been the plague of versioning schemes between software and hardware. Managing software releases against PCB revisions has become the never ending battle that often leads to confusion, delays, and even product failures.
For instance, in one startup I worked with, a slight modification in the PCB required a re-spin and, thus, an update to the firmware (albeit minimal). Due to poor version control the engineering team deployed the new firmware on older PCB versions causing unexpected brownouts and a periodic cloud of smoke. Luckily we caught it before the product shipped but it was an absolute nightmare for days on end..
To avoid these pitfalls, it's crucial to establish a rock solid versioning scheme and ensure clear communication between hardware and software teams. Even a simple versioning scheme such as a Git hash (or semantic version) for firmware, alongside a basic supported lookup table for hardware revisions, can be good enough to get started. As time progresses more sophisticated mechanisms such as hardware revision detection in the firmware (thus checking for compatibility) greatly reduces mix ups as well.
In addition to software versioning it’s also important to think about modularity of code. With spaghetti code, swapping out a sensor board with new chips or sensors could become a refactoring nightmare. Modularizing your device drivers and creating hardware abstraction layers allows for easily swapped components for years to come. This is something that has become much more popular as embedded systems have grown in complexity over time.
When we think about embedded systems architecture we don’t always have to think small. Spacecrafts and automobiles are extremely complex embedded systems but so are smartphones. Whether we’re designing an internet connected spoon or the next satellite, understanding the tradeoffs for embedded systems architecture is extremely important when designing for multiple PCBs. We’ve explored lots of concepts in this article but there are still many more that, undoubtedly, you will find along your journey.