Advancing Modularity in Embedded Software: Enhancing Ports and Adapters with Zephyr Bus (ZBus)
What this presentation is about and why it matters
How do you keep embedded firmware modular when direct calls, shared state, and hardware pressure all push it toward a monolith? Rodrigo Peixoto approaches that problem with a concrete architecture story from Zephyr, using ZBus as the transport layer and Zephyr as the missing contract layer above it. The talk walks through ports and adapters in embedded terms, with protobuf-based interfaces, generated glue, observers, policies, and swap-able implementations. It is most useful if you are trying to protect domain logic, improve testability, or make hardware and protocol changes less painful.
Who will benefit the most from this presentation
- Embedded software architect, if your codebase has grown into tightly coupled modules and global state.
- Firmware engineer, if you need to replace sensors, transports, or hardware targets without rewriting domain logic.
- Test engineer, if current designs still depend heavily on real hardware for integration and validation.
- Tech lead, if you want clearer module boundaries that different teams can work against in parallel.
- Zephyr user, if you are already using ZBus or considering it for a more structured application layer.
What you need to know
A basic working knowledge of embedded firmware design will help, especially if you have seen these ideas in practice:
- modules, drivers, and application logic in a typical embedded codebase
- publish-subscribe or event-driven communication
- the port and adapter idea, at least at a high level
- Zephyr RTOS and ZBus terminology, if you want the implementation details to land faster
- protobuf-style interface definitions and code generation
Glossary (terms used in this talk)
- observer: A component that reacts to events or messages without being tightly coupled to the emitter. Observers are often used to decouple producers from multiple independent consumers.
- policy: A decision-making layer that interprets events and decides what action to trigger next. Policies help keep orchestration separate from core domain logic.
- code generation: The automatic creation of source code, glue code, or boilerplate from a higher-level description. It is commonly used to keep interfaces, wiring, and repetitive scaffolding consistent.
Toolbox (mentioned in this talk)
- GitHub: A web-based platform for hosting Git repositories and collaborating on software development.
- Zephyr RTOS: A scalable real-time operating system for connected and resource-constrained devices. It often owns much of the system startup flow, including hardware initialization and thread setup.
- ZBus: A Zephyr message bus that provides compile-time defined channels and decoupled publish-subscribe communication. It is used to wire modules together without direct dependencies.
- Protocol Buffers: A language-neutral interface definition and serialization system used to describe services and messages. It is often paired with code generation to produce strongly structured interfaces and client or server glue.
Final thoughts
Practical and architecture-focused, this talk gives you a design vocabulary for thinking about modular embedded software without pretending the problem is solved by folders or layers alone. The value is less about a single trick and more about seeing how contracts, wiring, and implementation boundaries can be separated in a way that supports testing and change. It will especially help firmware engineers, tech leads, and Zephyr users working on systems that need to evolve without turning brittle. The core feeling is disciplined decoupling, with real embedded constraints still in view.
This overview is AI-generated from the session transcript. Spot an issue? Let us know.








No comments or questions yet. Be the first to start the conversation!