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:
- "Should I create a hardware abstraction layer?"
- "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).