Developing Reusable Firmware: A Practical Approach to APIs, HALs and Drivers