Skip to main content
ST Employee
July 7, 2025
Solved

Early Access to the STM32Cube HAL Drivers Major Update

  • July 7, 2025
  • 9 replies
  • 3217 views

Get early access to the next-generation STM32Cube HAL drivers for STM32U5

A major update to STM32Cube HAL drivers, called HAL2, is now available for preview on GitHub. It supports the STM32U5 series.


Building on over 10 years of experience, HAL2 delivers the following:

  • More optimized drivers with a smaller footprint and improved performance
  • Enhanced portability across STM32 devices to reduce development time
  • A more intuitive API for easier and faster application development


To support this update, examples have been revamped for better reusability and understanding, and a new online documentation portal is introduced for enhanced content and easier navigation.

Try it now:

  • Explore the preview on GitHub: STM32CubeU5-V2-Preview.
  • Test the new features and share your feedback via GitHub Issues. Your input is essential for the final release.


Join the conversation and share your thoughts in the comments.

    This topic has been closed for replies.
    Best answer by Pavel A.

    Allow me redirect your questions to @Emil Damkjaer PETERSEN 

    However...

    Will HAL2 make this situation better or worse in real-world usage?

    IIRC the code memory usage won't be worse because some heavy functions of HAL1 (clocks setup) have been refactored, the "MSP" functions layer removed, etc.

     Will HAL2 allow us to use an RTOS (like FreeRTOS) without forcing RTOS locks (mutexes/semaphores) on all peripherals

    AFAIK, depends on the RTOS. If the RTOS supports lightweight locks similar to futex'es in Linux, then any address can act as a lock - so the lock field in the "handle" struct can legally be just a uint32_t, not any RTOS mutex or semaphore object. In C++ this kind of locks corresponds to std::atomic_t:wait() and notify_one/all().

    /* Neither FreeRTOS or ThreadX have such lock, but Zephyr has */

     

    9 replies

    Graduate II
    July 9, 2025

    Interesting, in a quick glance over the repository I definitely see a couple of shortcomings addressed in the API.

    I will try to have a closer look when time permits.

    Has ST already defined an very rough schedule for the release and which MCU Series will be supported by the new HAL? Most probably the new HAL will be released much later for older Series if at all?

    ST Employee
    July 10, 2025

    Thanks for your interest in STM32Cube evolution. This new major update of HAL will become available starting from next year. It will indeed be released first for all new STM32 series ST will introduce on the market. Some of the latest introduced STM32 series might progressively be supported as well. Looking forward reading your first feedback.

    Super User
    July 13, 2025

    These improvements are very welcome. Especially

    * Revision of initialization and configuration

    * Improvement of clock configuration and reduce code size

    "Remove Init structure from handle and convert Init structure into configuration one"

    "Remove MspInit and MspDeInit callbacks"

    * Changes in the HAL files structure - stm32_hal.h instead of stm32tnxx_hal.h , removal of Ex files

    * Factoring "environment" defs out of ...hal_conf.h to stm32_external_env.h

    * Replacing the "locks" to OSAL layer with RTOS friendly locks

    * Revision of HAL drivers state machines.

    * Revision of HAL interrupt handling, esp. "prioritize handling critical interrupts first"

     

    However, some naming looks confusing:

    "Atomic configuration methods" - the word atomic in this context is confusing because it has very specific meaning in C (as in "atomic update state"). Consider  "more granular", "split" etc.

    * Same for clocks: here

    * Factoring out the LL core.c/h files: the word "core" in this context is confusing. Consider "private", "internal" etc.

    * Change values of HAL_Status: IMHO this change is not justified. Following crypto-paranoic "convention" in  general-purpose driver libraries makes no good. 

     

    Not clear why stm32xxx_hal_conf.h should be included in hal_def.h rather than directly from stm32_hal.h to make it more visible? But this is a minor point.

     

    ST Employee
    July 14, 2025

    @Pavel A. 

    Thank you for your valuable comments and feedbacks, it will help as improving the HAL2 and fixing some issues.

    here bellow some feedbacks about your comments:

     

    - * "Atomic configuration methods" + Same for clocks: here 

    Yes what we want here is to bring more granularity for the configuration, it is not about atomic access. we will update the term , "more granular" sounds good.

    Factoring out the LL core.c/h files: the word "core" in this context is confusing: by core we mean a common set of functions to handle the peripherals that allows to have 2 or more HAL drivers on top of it (like usb core + HAL PCD/HCD or sdmmc core + HAl SD/MMC/SDIO)

    we think the term core makes sense here in term of architecture. but we will double check with ST architecture team and if required we will update it.

    -  Change values of HAL_Status: these are preliminary values to make it better than HAL1 values. we are indeed checking with our security architects to have better values. to help us improving these values could you please provide us with a proposal for these values.

    -  stm32xxx_hal_conf.h is included by the hal_def.h only.  There a indeed some issues in the doc : here

    we will fix this page: note that this is transparent for the user, all what the application needs is to have the stm32xxx_hal_conf.h at it's side, knowing that the stm32xxx_hal_conf.h is provided as a ready to use template.

     

    ST Employee
    July 14, 2025

    @Pavel A. 

    regarding the point :

    -  stm32xxx_hal_conf.h is included by the hal_def.h only.  There a indeed some issues in the doc : here

    we will fix this page: note that this is transparent for the user, all what the application needs is to have the stm32xxx_hal_conf.h at it's side, knowing that the stm32xxx_hal_conf.h is provided as a ready to use template

    "

    Finally, after double-checking, the document is correct according to the references provided  here (see also below).

    I now understand that your point is not about an issue in the document (my mistake, sorry), but rather a proposal to make the hal_conf.h  more visible.

    As you mentioned, this is a minor point: the stm32xxx_hal_conf.h file is provided as a ready-to-use template in the package (in . All our examples use this file, and there is no change compared to HAL1 regarding this specific aspect.

    From an architectural perspective, we include the stm32xxx_hal_conf.h in the lowest-level header file of the HAL inclusion model, which is stm32tnxx_hal_def.h. This approach ensures that the stm32xxx_hal_conf.h is easily accessible in the inclusion path of all peripherals HAL PPP drivers. And so make all the HAL configuration items defined in stm32xxx_hal_conf.h visible to all the peripherals HAL PPP drivers 

     

    BJABR_0-1752492689925.png

    BJABR_1-1752492833444.pngBJABR_2-1752492870591.png

     

     

    ST Employee
    August 1, 2025

    @Tom_pm and @Davide Dalfra any particular series you have in mind? And is it because you are looking at starting new projects or would like to upgrade current projects? 

    Visitor II
    September 15, 2025

    To chime in re: availability on other series:

    If one of the goals of HAL2 is Enhanced portability across STM32 devices, that's going to be defeated by any MCUs recently/currently in production that don't have a HAL2 framework.  Current STM HAL API is already fairly portable across processors, and in my company's codebase we make use of that.  This includes repos shared across projects.  There seem to be enough improvements in HAL2 to make an API break worthwhile, but porting STM HAL reliant code piecemeal with new processor dependencies will create desync issues between projects depending on which MCU they use.

    ST Employee
    September 17, 2025

    Hello @USBPD Dan,

     

     

    Thank you very much for sharing your insights on how you and your company use HAL. Is the main challenge with the two HAL versions that HAL1 allows you to use the same application code with consistent HAL calls across multiple series, despite differences in HAL versions (e.g., STM32F7xx_HAL_Driver vs. STM32U5xx_HAL_Driver)?

    If you have any suggestions on how ST could improve the experience of working with both HAL and HAL2, we would love to hear your ideas!

     

    Best Regards,

    Emil 

    Visitor II
    October 24, 2025

    Is the main challenge with the two HAL versions that HAL1 allows you to use the same application code with consistent HAL calls across multiple series, despite differences in HAL versions (e.g., STM32F7xx_HAL_Driver vs. STM32U5xx_HAL_Driver)?

     

    That's a good summary of my concern

     


    If you have any suggestions on how ST could improve the experience of working with both HAL and HAL2, we would love to hear your ideas!


     

    Ideally you'll continue releasing HAL until all MCUs still in production have a HAL2 library.  Porting application code to use HAL2 isn't an issue, but having application code support both at the same time will cause undue headaches

    Graduate
    September 16, 2025

    While I generally like the changes introduced in HAL2, and especially the C startup instead of assembly, I am too dumb to understand why the ST programmers don't use bool type for simple config options and continue to use uint32_t for boolean variables. Could anybody enlighten me?

    Super User
    October 1, 2025

    Another small suggestion: calling the user callbacks in HAL code looks too verbose with #if's:

    #if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
     hsd->ErrorCallback(hsd);
    #else
     HAL_SD_ErrorCallback(hsd);
    #endif

    Instead it could be defined as a wrapper  macro, for example:

     HAL_SD_INVOKE_CALLBACK(hsd, ErrorCallback); // unconditional
    
    // where:
    
    #if (USE_HAL_SD_REGISTER_CALLBACKS)
    #define HAL_SD_INVOKE_CALLBACK(h,f) (h)->f(h)
    #else
    #define HAL_SD_INVOKE_CALLBACK(h,f) HAL_SD_ ## f(h)
    #endif

     

    Visitor II
    October 24, 2025

    I have a few practical questions regarding HAL2. I’d really appreciate official clarification:

    1. The current HAL1 library already takes up a lot of Flash space. Will HAL2 make this situation better or worse in real-world usage? Are there any reference projects or actual size comparisons between HAL1 and HAL2?

    2. Regarding RTOS and locking: Will HAL2 allow us to use an RTOS (like FreeRTOS) without forcing RTOS locks (mutexes/semaphores) on all peripherals by default?
      Real-time performance is very important to us. For example, ESP32’s ESP-IDF adds FreeRTOS mutexes to nearly every driver, and this has seriously hurt real-time capability—some high-performance tasks become almost impossible. I hope HAL2 won’t repeat this mistake and will allow us to either fully disable or customize the locking strategy.

    3. Will HAL1 continue to be maintained? Will newly released MCUs still offer HAL1 support, or will support be exclusive to HAL2 going forward?

    Pavel A.Answer
    Super User
    October 24, 2025

    Allow me redirect your questions to @Emil Damkjaer PETERSEN 

    However...

    Will HAL2 make this situation better or worse in real-world usage?

    IIRC the code memory usage won't be worse because some heavy functions of HAL1 (clocks setup) have been refactored, the "MSP" functions layer removed, etc.

     Will HAL2 allow us to use an RTOS (like FreeRTOS) without forcing RTOS locks (mutexes/semaphores) on all peripherals

    AFAIK, depends on the RTOS. If the RTOS supports lightweight locks similar to futex'es in Linux, then any address can act as a lock - so the lock field in the "handle" struct can legally be just a uint32_t, not any RTOS mutex or semaphore object. In C++ this kind of locks corresponds to std::atomic_t:wait() and notify_one/all().

    /* Neither FreeRTOS or ThreadX have such lock, but Zephyr has */

     

    Super User
    October 30, 2025

    HAL2 feels like a lot of spinning of wheels for little to no gain. There are a lot of good changes. I wish those changes would have been made to HAL without breaking the whole structure.

     

    Random thoughts below.

     

    I looked over the breaking changes pages, lots of things like this:

    TDK_0-1761789012362.png

    Okay, so the state enum is changing names (and possibly there is a naming convention change as well?). Who cares? This isn't an increase in functionality, just a change I have to re-learn. Doesn't decrease flash space, doesn't make anything faster, doesn't make anything clearer. It does make any existing HAL code incompatible.

     

    > Split legacy HAL_PPP_Init into Init (build handle object) and config (apply configuration)

    > Remove Init structure from handle and convert Init structure into configuration one

    Good. Both easy hanging fruit in terms of reducing memory footprint.

     

    > Add HAL User Data Set/Get APIs

    > const void *HAL_TIM_GetUserData(const hal_tim_handle_t *htim)

    Okay, but why make the data const? Surely "user data" should be allowed to be modified by the user. Oversight? Maybe I'm missing something.

     

    > HAL implementation relies on LL inline functions instead of direct register access.

    I really hate this. Now you just added another step to me figuring out what the code does. The LL functions obfuscate things, the don't help clarity.

    In HAL1, I know exactly what this does after reading it:

    MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_CACHECMD, 0U);

    In HAL2, I have no clue what this does, that it modifies the CR register, or that it modifies the CACHECMD field.

    LL_DCACHE_SetCommand(p_dcachex, LL_DCACHE_COMMAND_NO_OPERATION);

     

    > HAL defines and enum(those used for HW registers) are redirected to the equivalent LL ones.

    Ow wow, I hate this one too. More obfuscation. And the reasoning is terrible:

    > This allows for an easier transition from a HAL-based application to an LL-based application.

    If I wanted to use LL, I would use LL!

     

    > All public macros related to hardware (HW) are removed, and equivalent services added to the LL layer.

    More marriage between HAL and LL, yuck. So they are no longer separate. HAL uses LL heavily.

     

    > In HAL2, all the MspInit and MspDeInit functions are removed, including the global ones and the PPP ones. The equivalent of the global MSP Init and DeInit are respectively expected after the generated call to HAL_Init and HAL_DeInit (without using any callback). The equivalent of the peripheral MSP Init and DeInit are respectively expected after the generated call to HAL_PPP_Init and HAL_PPP_DeInit (without using a callback).

    I'd like to see this. The Msp functions were confusing because it's not clear at first glance that (a) they exist and (b) get called indirectly by HAL_xxx_Init.

     

    > Merge HAL extension files with common ones and remove the EX prefix from APIs

    Reasonable. Should have been done a while ago.

     

    > In HAL2, the lock mechanism is replaced by HAL_PPP_AcquireBus and HAL_PPP_ReleaseBus APIs that use an RTOS semaphore object.

    So HAL2 forces you to use an RTOS? Huh? That's incompatible with what I do with embedded electronics, at the least.

     

    > New atomic state update macro for internal HAL PPP drivers implementations (HAL_CHECK_UPDATE_STATE)

    New implementation here: STM32CubeU5-V2-Preview/stm32u5xx_drivers/hal/stm32u5xx_hal_def.h at 0cf320046f0147a87c5db327c4d7e67e7b75eb27 · STMicroelectronics/STM32CubeU5-V2-Preview

    I guess with LDREX/STREX we are leaving some families unable to use this and left behind with HAL2. Goodbye blue pill (good riddance). Goodbye L0, G0, and others.

     

    HAL has some issues, but burning it down and trying to duplicate the library in a slightly different way is a lot of work for not much gain. This is different than standard peripheral libraries -> HAL which actually introduced fundamental differences, and overhead, into the API. Improved functionality at the cost of overhead.

     

    > Removing HAL1 lock mechanism

    > Adding a new HAL2 HAL OS

    I generally like this, as long as it's optional, but removing it from the normal HAL2 functions means a lot of users are just not going to do it and then wonder why HAL2 isn't thread-safe.

     

    > Add HAL_PPP Prefix to All HAL Peripheral APIs (Defines, Macros, Types, and Functions).

    Good change.

     

     

    Tried to follow some examples but I can't figure them out. Where is mx_example_tim_init?? It's not in example.c. Maybe just not done. Not a fan of the new main.c structure.

    STM32CubeU5-V2-Preview/examples/hal/tim/pwm_output/application/example.c at main · STMicroelectronics/STM32CubeU5-V2-Preview

     

     

    > Development toolchains and compilers

    Missing is STM32CubeIDE. Are we just abandoning it entirely?

    Graduate
    November 10, 2025

    I have not yet done any deeper dive into the whole thing.  

    For the current projects I work on, it seems a bit too much to deal with to port to the new HAL, but future projects may switch to HAL2.

    That said, under os_port you currently only list freertos and no_os

    At the same time in the cmsis section, you include CMSIS RTOS2...

    Will CMSIS RTOS2 be included in the os_port section? I don't think it makes much sense not to include something that's already in there...

    Super User
    December 21, 2025

    Hi @Emil Damkjaer PETERSEN ,

    thanks for providing the preview. I'm late as I don't use U5 in a current project.

    I have a proposal for LL: There are some macros unfortunately exposing the internal bus hierarchy.

    Like for TIM15 I found.

    # grep -RH "#define LL.*A.B.*TIM15" */Drivers/*HAL*/Inc/*ll*.h */*/ll/*.h | sed 's|.*/\([^/]*\):|\1:|' | sed 's|\s*//.*$||; s|\s*/\*.*$||'
    stm32c0xx_ll_bus.h:#define LL_APB1_GRP2_PERIPH_TIM15 RCC_APBENR2_TIM15EN
    stm32f0xx_ll_bus.h:#define LL_APB1_GRP2_PERIPH_TIM15 RCC_APB2ENR_TIM15EN
    stm32f0xx_ll_system.h:#define LL_DBGMCU_APB1_GRP2_TIM15_STOP DBGMCU_APB2_FZ_DBG_TIM15_STOP
    stm32g0xx_ll_bus.h:#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APBENR2_TIM15EN
    stm32g0xx_ll_system.h:#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBG_APB_FZ2_DBG_TIM15_STOP
    stm32g4xx_ll_bus.h:#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN
    stm32g4xx_ll_system.h:#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBGMCU_APB2FZ_DBG_TIM15_STOP
    stm32h5xx_ll_bus.h:#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN
    stm32h5xx_ll_system.h:#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBGMCU_APB2FZR_DBG_TIM15_STOP
    stm32h7xx_ll_bus.h:#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN
    stm32h7xx_ll_system.h:#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBGMCU_APB2FZ1_DBG_TIM15
    stm32l4xx_ll_bus.h:#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN
    stm32l4xx_ll_system.h:#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBGMCU_APB2FZ_DBG_TIM15_STOP
    stm32l4xx_ll_bus.h:#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN
    stm32l4xx_ll_system.h:#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBGMCU_APB2FZ_DBG_TIM15_STOP
    stm32u0xx_ll_bus.h:#define LL_APB1_GRP2_PERIPH_TIM15 RCC_APBENR2_TIM15EN
    stm32u0xx_ll_system.h:#define LL_DBGMCU_APB1_GRP2_TIM15_STOP DBGMCU_APBFZ2_DBG_TIM15_STOP
    stm32u5xx_ll_bus.h:#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN
    stm32u5xx_ll_system.h:#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBGMCU_APB2FZR_DBG_TIM15_STOP
    stm32u5xx_ll_bus.h:#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN
    stm32u5xx_ll_dbgmcu.h:#define LL_DBGMCU_TIM15_STOP DBGMCU_APB2FZR_DBG_TIM15_STOP

    These defines differ across series which hinders portability.

    LL_DBGMCU_TIM15_STOP is already a good exmaple because this hides the internal bus hierarchy and makes cross-series porting possible.

    Would like to see more of this style like simply LL_PERIPH_TIM15 or so. Maybe they come in addition to the existing ones and later the existing ones become legacy/deprecated.

    The peripheral instances have already unique names so there should be no conflicts.

    hth

    KnarfB