Due to the complexity of a firmware project, it requires the involvement of teams with diverse expertise. The success of a project is dependent on the interaction between the teams. While the “Bridging the Gap: Real-World Collaboration for Software and Firmware” blog post explores management-level best practices that can be followed to foster team coordination, this post will delve into best practices from the perspective of a firmware engineer, drawing on lessons learned from various projects.

Between Firmware and Hardware Teams
In a firmware project, the PCB boards often come with several revisions. Part changes due to shortages or cost-cutting measures are sometimes unavoidable. A working firmware could malfunction or behave differently after being loaded onto boards of different revisions. To mitigate this issue, we can customize the Board Support Package (BSP) to utilize the correct pins or peripherals based on a specific board revision. We can also develop a board-agnostic firmware by emphasizing a modular design with abstraction layers and reusable code.
To facilitate board bring-up, we can consider implementing a Command Line Interface (CLI) in the firmware. The hardware team can verify a new board revision by interacting with it using the CLI before distributing it to the firmware team. With the confidence of having working hardware, the firmware team can then focus on implementing features. For a deeper dive into embedded CLIs, refer to the blog post, “Embedded Command Line Interfaces and Why You Need Them.”
Since firmware development is closely coupled to the hardware, the firmware team should have a good knowledge of the hardware they are interacting with. Therefore, the firmware team should be involved in the board design review. The discussion between both teams ensures that the requirements are met and minimizes the need for last-minute hardware changes.
To understand and interact with the hardware, the board schematic is essential and will be useful throughout firmware development. Therefore, at the beginning of a project, we should get access to the schematic design project, such as an Altium project or, at the very least, a PDF version of the schematic. The hardware team can also create a hardware reference manual and keep it up-to-date with information about the changes in each board revision. Ideally, these items would be hosted on a shared platform that is accessible to the firmware team.
Between Firmware and Software Teams
For a microcontroller that interacts with platforms such as mobile applications or Linux systems, we need to involve developers from both firmware and software teams. Debugging a complicated system is not easy. If a portion of application logic fails during integration testing and the error is not properly propagated to the upstream software, it adds a layer of complexity to figure out the root cause of the issue. Including error statuses in the message protocol (e.g., Protobuf, etc) between the firmware/software will help pinpoint the culprit in the codebase.
Having good documentation in the codebase using tools such as Doxygen can help developers from another team better understand the code. It’s also good practice to maintain the README in the repository and update information on any shared platforms, such as Confluence or Notion. For example, firmware that interacts with the Cloud often needs mapping between different enums. Having them listed on a page will help with understanding the application flow as well as debugging.
Some best practices can be followed to streamline the code review process. In the Git workflow, commit messages serve as a history of a new feature. By having informative commit messages and keeping each commit focusing on a single task, it facilitates smoother code reviews, especially for cross-functional teams. Furthermore, we can provide step-by-step testing instructions in the pull request for other teams to test the functionality and provide valuable feedback from their perspective.
Bonus: Between Remote Firmware Teams
Setting up a complete board setup and allowing firmware team members to access it remotely can speed up development. Firmware can behave differently on different hardware setups. Having a consistent and complete board setup that can be used to verify new and existing features can eliminate the case in which it only works on my desk setup, but not on others. It also saves the time spent waiting for the only developer who has a complete setup to help with testing your implementation.
Besides a consistent board setup, a consistent development environment is also crucial. By utilizing a controlled environment such as Docker, we ensure that different teams build identical binaries. This prevents unpredictable behavior due to varied build environments and saves time spent on initial build setup. To learn more about Docker, check out the “Docker: An Ideal Development Environment” and “Dev Containers” blog posts.
Conclusion
Collaboration between cross-functional teams is unavoidable in firmware development. By following the best practices that we learned from various projects, we can make the next project smoother and more successful. If you are missing the firmware team that coordinates between your hardware and software teams, D5 is here to help! Should you be interested in elevating your project, please do not hesitate to schedule a consultation with our team. Alternatively, explore EmbedOps, our continuous integration build platform.
We look forward to hearing from you! -D5


