There are two big problems facing technology companies in the United States today; microprocessor supply chains and finding engineers to get the job done. In my last post, 5 Tips to Successfully Manage Engineering Shortages, we discussed the later issue. In today’s post, we are going to discuss how to design embedded systems so that they are flexible enough to handle supply chain issues.
When it comes to the supply chain, the biggest problem that is facing teams today is that they can’t find stock of their microprocessor. Teams designed their products with common stock products, and then suddenly there aren’t any available. The lead times for these parts might be long, sometimes a year or more.
Obviously, no one wants to wait that long. The result is that hardware and software need to be changed. Below are some tips for designing and/or redesigning your product so that it’s flexible enough to handle supply chain issues like swapping out a microcontroller.
Tip #1 – Separate Hardware Dependent Software from the Business Logic
My first suggestion is that you design your embedded software into two separate architectures; the business logic and the hardware-dependent architecture. The business logic will contain all the special sauce for the product.
The features, user interactions, algorithms, and so forth. The business logic has no dependency on hardware. Instead, the business logic depends on an interface that interacts with the underlying hardware.
The advantage to architecting embedded software in this way is that it allows the product features to be easily ported to any microprocessor or microcontroller. Developers don’t need to fight their way through microcontroller-specific calls or register in the application code. Instead, they only update the hardware-dependent code behind the interface, leaving the business logic intact.
The interface used to interact with software is a hardware abstraction layer, often referred to as a HAL. Many microcontroller vendors provide drivers and interfaces to simplify and speed up development, but developers often don’t go far enough by adding in the hardware abstraction layer. They look at the drivers as the abstraction layer, which is not correct.
The result is that the application code gets coupled to the hardware driver code which in turn adds more time and effort when a product needs to change to a new microcontroller. Example hardware abstraction layers can be found in Arms’ CMSIS.
Tip #2 – Use Code Generator Tools
Another technique that you can use to build more flexible software is to leverage code generation tools. A generator will often take either a high-level software construct like an architectural component or even a configuration file and then generate useable code. The high-level component or the configuration file can be modified and then the code regenerated very quickly.
In general, two types of code generation tools come to mind; driver generators and “full stack” generators. Driver generators are typically provided by silicon vendors. The generator takes configuration for different peripherals and then generates the code necessary to control the peripheral and interact with it. Full-stack generators are design tools like Matlab that can be used to develop the software architecture and then generate target-specific code.
Code generators often times don’t generate the cleanest or most efficient code, but they provide a level of portability and scalability well beyond hand-coding. If you design and auto-generate and then discover that you can’t find the microcontroller, there may be an option to select a different target library and then generate code for the new microcontroller. The code generation removes the need to rewrite low-level drivers, remove and integrate software packages, and deal with all the low-level challenges that come with porting software.
Tip #3 – Design with Compatible Parts
Another technique that I often use when designing embedded systems is to design with more than one part in mind. Early in my career, I worked in the automotive industry which engrained in my mind that you always design with a second part in the mind. Supply chains are unpredictable and you don’t want to be caught without critical components.
When designing a hardware system, it’s useful to identify several parts from different vendors and from the same vendor that are pin-compatible or near pin compatible. Now, you might be thinking that it’s nearly impossible to find compatible parts, which can be true.
However, if you understand the differences, the PCB artwork can be designed so that it can handle either part. Many microcontrollers have very flexible pin multiplexing schemes. The greatest challenges can be lining up power pins and programming pins.
In some systems, it may even make sense to remove the concern for compatibility and instead create processor modules. There are lots of existing solutions for application processors that are built as a system on a module (SOM).
These modules usually contain all the power and provide their I/O in a pin-compatible way. Replicating this type of design can add hardware flexibility and even allow a product line to provide varying degrees of processing power. The disadvantage is that it does add some bill of material (BOM) costs for the connectors.
Tip #4 – Leave Space on Your PCB
Engineers are sometimes optimizing machines. We want to build the most efficient, smallest, streamlined system possible. However, when we build a system in this way, we sometimes also remove the ability to scale and pivot the design.
One technique that I have often employed when I design hardware is to leave extra space on the PCB around components. For example, I might have a microcontroller in the middle of a board. I won’t put other integrated circuits or components as close as I can to it. Instead, I carve out a small space around the microcontroller to give it room.
If I ever have to swap out microcontrollers and redesign the PCB, by leaving the extra room, I increase the chance that I have the space needed to not have to completely redesign the entire board. If I didn’t leave that space and have to move to a larger part, I now have to move nearly every component which is more time-consuming and risky.
The microcontroller isn’t the only part that this can be done with. It doesn’t hurt to do the same around radio modules, memory, sensors, and other components. Now you don’t want to get crazy and increase the size of the board too much. Some systems just have really tight mechanical constraints and leaving space just won’t be an option. However, if you have the space, put it to good use and protect the portability of your product.
When designing the hardware and software for an embedded system, designers can assume that everything will go right. In fact, designers need to do the opposite and assume everything will go wrong. The software will be used in more than one application and will be ported and scaled. The microcontroller we selected could go end-of-life unexpectedly or suddenly drop to zero available with long lead times.
A little bit of forethought up front in the design can help ensure that drastic measures aren’t required when the unexpected happens to the supply chain. Being proactive, not reactive, will ensure that you are able to provide products to your customers uninterrupted even though others in the industry may be scrambling.
Jacob Beningo is an embedded software consultant who 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, including a Master 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.