Microcontrollers have reached a cost point and capability stand point that developers for many applications no longer have to write strictly bare-metal code. Instead, developers can write code at a higher level similar to the way a application developer on a PC might write their code. In order to do this, there are two different mechanisms available to embedded software developers: API’s and HAL’s.
A HAL is a hardware abstraction layer that defines a set of routines, protocols and tools for interacting with the hardware. A HAL is focused on creating abstract, high level functions that can be used to make the hardware do something without having to have a detailed knowledge of how the hardware is doing it. This can come in extremely handy for developers who work with multiple microcontroller hardware and need to port applications from one platform to the next. A HAL can also be a great way to allow engineers who aren’t experts in the lower lying hardware to still write useful application code without the nitty-gritty details.
An API is an application programming interface that defines a set of routines, protocols and tools for creating an application. An API defines the high level interface of the behavior and capabilities of the component and its inputs and outputs. An API should be created so that it is generic and implementation independent. This allows for the API to be used in multiple applications with changes only to the implementation of the API and not the general interface or behavior.
Figure 1 below shows what a typical software stack-up might look like for a developer designing embedded software.
Figure 1 – Embedded Software Stack-up
APIs’ and HALs’ are closely related but serve two different functions within software development. The HAL sits between the low level drivers and provides a common interface for common software stacks such as an RTOS and middleware components like USB, ethernet and file systems. The HAL can act as a wrapper for providing a common interface between existing drivers and higher level code or it can exist as the driver interface itself. The API’s act as a toolkit to help high level developers quickly generate application code. It provides common interface code for controlling the real-time behavior of the system and accessing common components such as serial communication and file accesses.
Separating these two concepts and using a layered software architecture can dramatically increase the re-usability of embedded software. Imagine being able to swap out every layer beneath the HAL and replace it with new hardware and drivers. That is a perfect example of what might happen when its time to upgrade existing hardware. Instead of starting from scratch, just the code beneath the HAL would need to be updated. The same idea goes for removing code above the HAL. Same hardware, new application. The result, faster development cycles, increased code reuse and increased robustness due to heritage.