HAL2 architecture ¶
HAL2 is the peripheral drivers layer of the STM32Cube embedded software. It is the evolution of the HAL1-based drivers, providing improved usability and maintainability while preserving the same programming model and API style.
Refer to each STM32 series HAL documentation for more details on a specific HAL2 software component (see HAL Drivers).
Purpose ¶
The HAL provides function-oriented, portable APIs that simplify peripheral usage across STM32 series. The LL drivers provide low-level, register-focused APIs for optimized, fine-grained control.
HAL targets ease-of-use and process-oriented operations. LL targets minimal-footprint, direct register access and performance.
Layering and roles ¶
HAL layer:
consists of high-level, handle-based drivers [1]
implements polling, interrupt and DMA programming models
provides reentrant, RTOS-compliant APIs, user callbacks and peripheral multi-instance support
LL layer:
is series-closer, register-based drivers [2]
uses static inline APIs grouped by peripheral
offers low, middle and high level functions for atomic register access and one-shot operations
Design principles and rules ¶
Resource ownership
Each software layer defines its own types and macros (
HAL_
/
hal_
prefixes).
Cohabitation
Do not mix HAL configuration or process APIs with LL calls for the same peripheral instance. Either use HAL for that instance, or use LL exclusively: mixing might leave HAL handles inconsistent.
API compatibility
HAL preserves inter-series API/structure naming when features match: fields or APIs may be removed or extended when series hardware differs.
LL APIs are series-specific and may differ in naming, parameters, or availability based on the underlying hardware features.
Safety and concurrency
HAL provides bus services (
AcquireBus
/
ReleaseBus) and timeout-based blocking calls.
LL offers no such services and requires the user to handle timeouts, errors and concurrency.
HAL implementation notes ¶
HAL drivers group full peripheral feature sets in C modules and expose a standardized API across families. HAL implements higher-level checks and state management, updates handle fields, and calls LL primitives to perform register operations when applicable.
LL implementation notes ¶
LL functions are typically defined as
static
inline
for direct register operations and are organized per peripheral in header files.
They avoid global state, use local variables only, and limit argument counts to favor compiler optimizations.
LL drivers enable predictable, minimal implementations suitable for performance and footprint optimization.