I'm exploring the world of STM32 microcontrollers. I must say, so far it's a huge puzzle. I find that there are many documents provided by ST, but none of them really teach me anything. And it's really confusing that there is so much information that points me to tools that seem to be superceeded by STM32 Cube IDE (Which I only found out after I spend days to get eclipse/GNU plugin working....)

I bought the book 'mastering STM32' which is a huge source of information.

This book has a strong focus on the HAL drivers, while I also read a lot on the low level drivers. The two are supposed to be complementary.

Now when I read about the UART peripheral on this page which gives me the impression that I should not use the HAL driver.

I have timing requirements to take into account (1 milisecond response time).

  • Are there serious drawbacks in using the HAL?
  • Is there some rule of thumb how to choose between HAL/LL drivers?
  • Can I find some more in depth documentation on either solution? I am not finding much more useful than the blinky app...
  • \$\begingroup\$ From a ST's document: The HAL offers high-level and feature-oriented APIs, with a high-portability level. They hide the MCU and peripheral complexity to end-user. The LL offers low-level APIs at registers level, with better optimization but less portability. They require deep knowledge of the MCU and peripherals specifications. \$\endgroup\$
    – Long Pham
    Sep 3 '19 at 20:36
  • \$\begingroup\$ You can go with APIs or talk to the hardware register directly yourself. There are pros and cons to each (the hardware in these devices is relatively easy dont be lead to believe there is hidden complexity). Professionally you should be able to do both. If you look at the source code for the apis, they are not necessarily written by the A-team, in some cases downright disturbing. Your product relies on your solution, you are responsible ultimately for your choices in this matter. \$\endgroup\$
    – old_timer
    Sep 4 '19 at 2:17
  • \$\begingroup\$ you can go straight api, be it whatever api they provide (it is in their business interest to replace the apis every so many years, so not uncommon there are at least two solutions for a product you might be using), you can go api with your own bug/design fixes, you can go without an api and/or make your own. Your choice, again, professionally you should be able to do any one of the three, and should practice that from time to time to determine what choice to use for the next product you are working on. \$\endgroup\$
    – old_timer
    Sep 4 '19 at 2:19

Are there serious drawbacks in using the HAL?

Is there some rule of thumb how to choose between HAL/LL drivers?

I've not yet found a one-size-fits-all guide to this particular issue... that is "Should I use a HAL"? But I would offer my experience with this issue.

Let's boil down this question a bit more: "Should I use a HAL?" broken down is:

  1. "Should I create a hardware abstraction layer?"
  2. "Should I use a 3rd Party HAL?"

In my opinion, it is generally good practice to create "layers of software". These layers create obvious and logical organization in any software design, embedded firmware included.

With that being said, the answer to part of your decomposed question "Should I create a hardware abstraction layer" is "yes". It is good practice to separate all hardware calls and direct register accesses into a HAL. Not only is this a good organizational scheme, but it also makes the software more easily portable and reduces the amount of "stuff" you need to keep in your head at once. If you really need that bare metal, ultra-optimized, direct register accessing performance, then try to keep it limited to as few functions as possible.

What's more readable and reusable?

PORT0->IOCR8 |= 1<<13; //enable push-pull output on pin 13



This is a trivial example, but it serves to illustrate my point that HAL's make firmware more readable and less prone to bugs since it makes the software more "human readable". There are techniques to minimize or even eliminate the function call penalty through static inline functions.

The second decomposed question "Should I use a 3rd party HAL?" is a bit more complicated and subject to years of biases and opinions. So I will offer my own.

In my experience, 3rd party HAL's are not true HAL's in that they still lock you into a specific vendor. They aren't abstract in the purest sense. They likely will only be portable between a particular MCU vendor's portfolio.

3rd party HAL's work great for configuring peripherals and other initialization schemes. Then there's a middle ground where moderately complicated functions like UART tx/rx, I2C tx/rx, and even DMA, where the HAL's try to get tricky and write ISR's for you to provide a convenient API. I've had mixed experience here. You open yourself up to vendor bugs and possible performance issues at the expense of quicker time-to-market. Finally, once you move onto things like wifi or bluetooth stacks, there's not really a choice and you must use 3rd party libs.

So, unfortunately, the answer is: "it depends". Perhaps we can address your question with more information about your specific needs.

If you're interested, Jacob Beningo's book "Reusable Firmware Development" offers some valuable insight into this subject. (I apologize if recommendations are frowned upon).

  • \$\begingroup\$ Thanks for the educating answer! That's really helpful for somebody new like me, overwhelmed by documentation which doesn't really seem to give the answers I am looking for. So if I may, let's stick to just one example; the UART peripheral in 9 bit mode. Can I safely rely on the STM HAL? Or would I be better of writing my own HAL based on the LL drivers? That's the choice to make, right? Or is 'writing your own HAL' also not using anything from the LL drivers? Is the LL driver also some kind of 3rd party HAL? \$\endgroup\$
    – bas
    Sep 3 '19 at 21:19
  • \$\begingroup\$ You could certainly use the LL's and add your own HAL layer on top of them. I've done this in the past to good effect. I am particularly fond of this when configuring clocks. I will say though, if this is primarily an educational exercise, try and write everything including the LL's. This is a fundamental area you need to understand and build from. Try not to use the LL's to bridge an area you lack understanding in yet. \$\endgroup\$
    – gregb212
    Sep 4 '19 at 14:25
  • \$\begingroup\$ Great tip. I will try to do that then. My background is software, and I'm clearly lacking a foundation in electronics. My gut feeling said that it's impossible to write the interface with the microcontroller myself. I guess I've got a mission now :). Thx again for the advice! \$\endgroup\$
    – bas
    Sep 4 '19 at 18:02
  • 1
    \$\begingroup\$ It's a lot of disparate knowledge in the beginning, but once you grasp the fundamentals, it will become much easier. The first key is understanding how to think in 'bare metal', and how the hardware-software bridge is handled through memory mapped registers. In other words, how to use software to control something in hardware. At the end of the day, it's all handled in the registers. Understand that, and the rest will fall into place. \$\endgroup\$
    – gregb212
    Sep 5 '19 at 19:28
  • 1
    \$\begingroup\$ I found this page: vivonomicon.com/2018/04/02/…. That really helps a lot! I'm actually getting somewhere now :) :). \$\endgroup\$
    – bas
    Sep 6 '19 at 8:45

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .