Part drivers architecture

Part drivers provide the software interface for external devices integrated on boards. They are platform-agnostic and can be used with any board that integrates the specific external component. Part drivers are independent of both the HAL and the board hardware design, providing reusable unitary services (see Component-based design).

Evolution from HAL1-based BSP

The HAL2-based STM32Cube embedded software part drivers have been redesigned to improve usability and maintainability:

  • Simplified architecture allowing direct usage by application code with improved glue logic between components and communication buses (I2C, SPI, UART)

  • Reduced usage of function pointers and complex structures to enhance code readability and ease debugging

  • Separation of driver core from hardware resource configuration (pins, buses, peripherals), using descriptors that can be configured manually or through STM32CubeMX2

  • Elimination of class-based abstraction layers, allowing direct service calls from application level

  • Reworked component classification enabling straightforward usage without complex data structures

Part driver anatomy

A part driver is structured in three layers:

Diagram showing the layers of a part driver architecture, including the core layer, register layer, and IO interface.

Part driver architecture layers

  • Part core layer: High-level functions based on the unitary register functions provided by the part register layer. It is object-based [1] for multi-instance support.

  • Part register layer [OPTIONAL] [2]: Contains part register defines, low-level register write and read operations, unitary functions, and context structure. This layer is completely platform-independent and can be used with any environment. Native IO operations are provided as weak functions to handle third-party IO contexts and must be overridden by implementations in the IO interface layers.

  • Part IO interface: Set of ready-to-use low-level interfaces based on HAL drivers, linking the part to the board buses. This layer implements the IO operations required by the core and register layers. The bus itself is initialized in user code, not in the IO interface.

Part driver services

Part drivers are platform-agnostic and provide standard initialization, configuration, and operation services. For exact API signatures and detailed descriptions, refer to the documentation of the specific part driver.

IO interface architecture

The IO interface architecture provides flexible integration options:

  • Part IO interface drivers are ready-to-use glues between the core/register layer and the hardware platform through HAL drivers or other part drivers.

  • IO interfaces are split by supported bus type (I2C, SPI, UART), IO operational model (synchronous, asynchronous), and RTOS support.

  • The IO programming model is defined according to the core driver architecture. Mixed IO model services can be provided if required.

  • Core driver behavior adapts to the used IO interface pattern through configuration literals (NNXXX_USE_XXX, such as LAN8742_USE_HAL_MUTEX) without requiring additional configuration files.

  • IO interfaces include a pseudo-empty template that can be used to implement custom hardware interfaces.

Users can:

  • Use a predefined interface

  • Fork an existing pattern and customize it

  • Create a new interface implementation from scratch based on the template

IO interface services

Part IO interfaces implement initialization, register access, data transfer, reset, and bus management services to expose the part to the application. For exact API signatures and parameter details, refer to the documentation of the specific part driver.

Note

As each part has its own IO interface, the prototype of IO operations can differ across part drivers.

Part driver usage principles

In HAL2-based STM32Cube embedded software, applications can access part services directly without additional abstraction layers (legacy BSP classes).

The part driver usage follows the same two-path principle as HAL2-based middleware and utilities components:

Diagram showing the two-path usage model of middleware, part drivers, utilities components, including the resources initialization path and the services usage path.

Two-path usage model of middleware, part drivers, utilities components

  1. Part resources initialization path: Activated part resources are initialized either from system initialization code (can be generated with STM32CubeMX2) or application code.

  2. Part services usage path: Part services are invoked by the application using logical instance objects. Parts retrieve the initialized resource objects during part initialization and save them in instance objects for use in the IO interface.

This separation of concerns ensures clear responsibility boundaries: the application is fully responsible for the resources management, while the part driver is responsible for the services implementation.

For part-specific usage details, refer to the individual part driver documentation.

Commonalities with other components

Part drivers share common architectural principles with Middleware architecture and Utilities architecture:

  • Two-path usage model (initialization and service usage)

  • Interface patterns (user templates and ready-to-use interfaces)

  • Platform-agnostic core with hardware abstraction through interfaces

  • Software component delivery model