Some context: I'm working on embedded system with Micro-Controler targets. My purpose here is to clarify the terms I can use for my code repository names. I focus on the low-level naming in that post which represents for me the target-oriented code (versus application-oriented code for the high level).
I enter in a loop over the web and forums where nobody seems to clearly defined the difference between these terms: HAL vs BSP vs Drivers.
According to me, all my three terms are theoretically equivalent, but people seems to make difference where the HAL is reserved for the MCU drivers (e.g. UART, GPIO, ...) and the BSP is reserved for the external peripheral drivers (e.g. accelerometer, EEPROM, ...).
Can somebody help me to clarify this? Additionally, can you mention if your answer is based on your personal opinion or if it is based on the reasoning/rationale of a community/company/standard/whatever?
Thank you for your time,
I will provide an answer based on my experience working with MCUs, but I also think it is something that could be better standardized and referred to within the embedded software community or within an organization. These terms do seem to have a more standard and practical definition when talking about lower-level interactions on more complex computing systems (CPUs and higher-level operating systems).
Thinking about a low-level embedded systems architecture, writing embedded software at a low level is a balance between building a reusable base that can be used across many projects, while also considering memory, power consumption and critical timing at this hardware level, that may need to be adjusted for different use cases.
In embedded and electronic systems, I would define each as follows:
Hardware Abstraction Layer - This layer provides abstraction to write to hardware registers (e.g. ADC, Timers, UART etc) within an MCU - which I will refer to here as "device". Functions here provide access to hardware features and is built on device-specific header/linker files.
HAL firmware should be device specific (although, the actual C code may support multiple devices within an MCU family, and pre-compiler definitions can be used to enable, disable or switch between features of different devices).
Many common MCU suppliers (e.g. TI with DriverLib, ST with STM32Cube) provide HAL libraries for many of their MCUs, which generally work very well for most applications, however, being generic, it may not be as efficient in regard to power, memory and timing when compared to having direct control of every register within the device, specific for your application.
If you have a project and you change your MCU, ideally all you want to change is the HAL firmware.
Board Support Package - This can be used as a layer above the HAL, and refers to how the device is connected on the board (e.g. an LED on pin 2). The application/component layers would call the BSP layer to turn on the LED, and the BSP layer would then call the HAL to switch the GPIO in the device hardware.
If I was to add a new LED to my project, I should not need to change the HAL firmware, only the BSP and application component using this new LED.
This should refer to any firmware component used to control external hardware (for example, an accelerometer, external EEPROM etc). This is an isolated component with APIs that can be used by your BSP (or possibly your application layer).
For example, any project where you use a specific accelerometer should be able to make use of this driver firmware for that accelerometer, regardless of device or board layout.
For example, consider a project that tracks acceleration data and stores the previous 100 values for each axis in an external EEPROM IC (I say EEPROM as the question uses it as an example, EEPROM may not be the best choice in reality). This data is then analysed and an LED blinks at a different rate based on a rolling average of the magnitude of acceleration. An example architecture for this, using HAL, BSP and Driver could be as follows (note this was designed quite roughly and quickly for demonstration purposes, so may not be a perfect design):
https://github.com/ARMmbed/mbed-os
https://www.ti.com/lit/wp/swsy004e/swsy004e.pdf
I hope this helps.
I would like to hear thoughts from other embedded developers on these definitions as well.