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.