Jacob Beningo is the founder of Beningo Embedded. Beningo’s website: www.beningo.com
Whether you love or hate open-source software, there are many lessons to be learned from writing modern firmware. For example, we can learn how to write portable and configurable code or create better documentation.

In today’s article, we will explore some lessons learned from modernizing embedded software workflows in Zephyr RTOS, including:
-
Treat your firmware as a modern software system rather than a one-off codebase.
-
Build systems should be reusable.
-
Modern systems are secure, portable, and continuously validated.
-
Let’s dive into what each of these lessons teaches us.
Treat your firmware as a modern software system rather than a one-off codebase.
Most embedded systems I encounter are written as one-off codebases. All components, customer code, and logic are crammed into a single repository. While this may seem convenient, the way this code is written suggests it will only be used for one thing and discarded after a year.
This is a flawed premise. In many cases, code can exist for ten years or longer, making it increasingly difficult to add new features and adapt to changing business environments. You should not dump all your code into a single codebase; you should treat your firmware like a modern software system.
What does a modern software system do? It breaks the system down into independent components and logically organizes them into multiple codebases. This may sound cumbersome. Who would want to manage a bunch of git repositories and figure out which should be included in the project and which should be excluded?
If you treat your firmware like a modern software system, you will realize that Zephyr RTOS elegantly accomplishes this with a tool called West. West introduces manifest-driven dependency management and modular code organization. This means that with a simple manifest, you can easily and effortlessly pull in the codebases required for your project.
West introduces manifest-driven dependency management and modular code organization. This means that with a simple manifest, you can easily and effortlessly pull in the codebases required for your project.
More importantly, it encourages you to think about reusable components, shared infrastructure, and long-term maintainability. You do not need to rewrite driver code or system configurations every time you start a new product. Instead, you can define your project in layers, such as application logic, board-specific configurations, shared middleware, and third-party modules.
This shift in thinking is crucial. When you treat firmware like a modern software system:
-
You can achieve scalable team collaboration.
-
You can reduce duplication and technical debt.
-
You can more easily test, simulate, and port.
Zephyr models a professional and future-oriented way to manage complex firmware across product lines and customer variants. Even if you do not use Zephyr, this model is worth emulating.
Build systems should be reusable.
Build systems are one of the biggest pain points I see in embedded teams. They are often cobbled together with Makefiles or fragile vendor tools that only work under the right conditions. Just changing a compiler flag can cause the entire system to suddenly break, or worse, the build succeeds but behaves completely differently.
The demands of modern firmware are higher. You need a build system that is portable, configurable, and reusable across multiple projects and boards. Zephyr’s CMake-based build system is just that.
CMake is not a new technology, but Zephyr applies it in a smart and scalable way. It supports layered configurations, toolchain abstraction, and board-level overrides. This means you can reuse a single application across multiple hardware platforms with minimal changes. This is a significant improvement over copying project files or making modifications in vendor IDEs.
The lesson hidden here is: your build system is part of your architecture. If it is not flexible enough, your project will not be flexible either. A reusable build system can provide you with:
-
Consistent builds across environments.
-
Easier CI/CD integration.
-
Faster new board bring-up.
Zephyr excels in this regard. Even if you do not use Zephyr, studying its build system architecture can help you modernize your own. The time you invest in improving your build system will pay off throughout the product lifecycle.
Modern systems are secure, portable, and continuously validated.
In the past, firmware was often written with a “good enough” mentality. Security was an afterthought, portability meant compiling for two slightly different boards, and testing was limited to powering on the board and hoping it wouldn’t crash. This is no longer the case.
Modern systems are more complex, interconnected, and exposed than ever before. They need to be designed with security, cross-platform portability, and automated continuous validation in mind. Zephyr understands this well and incorporates these principles into the core of the project.
Starting with security: Zephyr supports stack canary releases, address space isolation, secure boot, and trusted execution environments like Arm TrustZone. These features are not optional; they are built into the framework and encouraged for use. You do not need to add security later; you can build it into your application from the start.
Next is portability: Zephyr supports hundreds of boards and architectures. This is thanks to its strict abstraction layers and configuration system. Device drivers are decoupled from application logic. Kernel behavior is parameterized through Kconfig and device trees. This level of separation means you can reposition applications without having to rewrite everything from scratch.
Finally, continuous validation: Zephyr runs thousands of tests in continuous integration (CI) across various boards and configurations. This reminds us that testing should not just happen before a release; it should be done every time the system touches the codebase.
These are not just technical features; they represent a shift in mindset:
-
Do not assume your code is secure—prove it.
-
Do not limit yourself to a specific board—abstract it.
-
Do not wait to find bugs—find them early and often.
Zephyr shows us that embedded firmware can hold the same standards as modern software. If you want your products, teams, and skills to be future-oriented, this is a model worth learning.
In summary
You do not have to like open-source software. You do not have to use Zephyr, but you should learn from their lessons in writing modern firmware.
Complex open-source projects like Zephyr RTOS offer a wealth of techniques that can be directly applied to your development practices. From modular design to reusable build systems, there is much to learn and apply.
You can ignore these lessons and continue to maintain the status quo. After all, it is these technologies that have led to your achievements today. Unfortunately, these technologies are not a good recipe for achieving your goals. Therefore, the consequences of ignoring them are yours to bear.
The choice is yours; but you must understand the cost of stagnation in a rapidly evolving industry.