cancel
Showing results for 
Search instead for 
Did you mean: 

HAL Library seems to not follow classic programming guidelines

Werner Dähn
Associate II
Posted on June 09, 2018 at 15:42

I understand that programming enterprise software on a 8 core CPU with 4GHz and a simple STM32 MCU is different, nevertheless I would have added a few things to the HAL layer from the beginning:

  1. All HAL Init calls check if there is a collision with other resources. I configure PA1 as GPIO, then I use UART1 which needs PA1, hence the UART config should return an error. Granted, CubeMX is supposed to help you with that in a graphical manner but it does not in case you assign pins dynamically. And even if, what's wrong with validating that in a debug compile firmware a second time? Wouldn't that help beginners significantly?
  2. Programming a MCU is very hardware related. You need to open that gate to provide power to... by setting a register, switch the line to alternate pin by another register etc. From a HAL library I would expect to abstract exactly that. I want to enable UART1 on pin PA6, therefore the__HAL_RCC_GPIOA_CLK_ENABLE is called implicitly by the HAL_GPIO_Init function, the remap is called and the corresponding AF clock enabled and.... Things like that. Why should I remember every dependency if the HAL can do that for me?Another example: How many lines of code do you need to get an quadruple encoder (up/down counter) to work? Logically one call saying which pins to use and maybe choose the timer number. The counter specific X2 falling/X2 rising/X4 setting is needed also. Everything else can be derived from that information. Today you need 20-30 lines of code and if just one is wrong, you will not find out easily.
  3. The implementation is often too basic. Most obvious in the UART part of HAL. You can do char polling, add a interrupt callback or DMA. Fine. But useless as in most cases you would use a ring buffer. No rocket science but since when is that requested and yet still not available out of the box? Another missing receiver method is when timing plays a role like with serial packets. Every 20ms I get a packet that starts with 0x01 and ends with 0xEF and lasts for up to 5ms.

Wouldn't such things help greatly to get started? And to debug? And make the user experience better? And lower frustrations? And cause proper error messages rather than simply not working?

Or am I missing something.

Note: this post was migrated and contained many threaded conversations, some content may be missing.
60 REPLIES 60
Posted on June 09, 2018 at 16:31

>>I understand that programming enterprise software on a 8 core CPU with 4GHz and a simple STM32 MCU is different, nevertheless I would have added a few things to the HAL layer from the beginning:

I was programming system drivers on multi-core Windows boxes over a decade ago, the STM32 HAL looks like a complete train-wreck in places. Seems to evolved from engineers who coded single threaded 8051 embedded solutions rather than those using Pentium Pro's.

If your brain can conceive more than one thing occurring concurrently I suspect you're already miles ahead.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
henry.dick
Senior II
Posted on June 09, 2018 at 16:48

'

Wouldn't such things help greatly to get started?'

this is where an OEM library is often a great compromise (in a good way), as it has to deal with a vast spectrum of programming behaviors, from a 'nanny-state' approach where everything is packaged (Arduino and MBED), to 'you are on your own' approach.

It may very well be the case where MCUs of the future could run an OS that shields the user more or less from the hardware. Your approach is sure reasonable for some applications / some programmer. and will likely be the future.

However, many other people prefer the 'i want to take care of myself' approach. 

HAL is somewhere in between, but much closer to your thinking, though not enough I guess.

turboscrew
Senior III
Posted on June 09, 2018 at 17:04

Just a couple of days ago I had to add reading the raw input from an incremental encoder. Now I have those GPIO pins used for both GPIO inputs and inputs to timer in encoder mode. Good that HAL didn't check for 'conflicts'. And yes, our company wants us to use HAL. I'd do fine without any libraries and frameworks.

If handling the HW is such an issue to you, maybe your place is not in the embedded world? The embedded world tends to be mostly dealing with HW. There are also some operating systems available for the processors with some ready-made drivers.

Like

Show 0 Likes

https://community.st.com/0D50X00009XkWH3SAN

Posted on June 09, 2018 at 16:59

Let me follow up on that. Per my understanding the HAL plus MXCube is the highest abstraction level STM provides. The OEM is no generic library but more use case specific, e.g. Motor Controller for Brushless Sensored Motors.

RTOS etc sits way above that, but actually would deserve support from STM as well as part of the HAL, thinking about it. Yes,

Arduino

& MBED are probably good examples of what I am looking for, except that per my knowledge again, if an

Arduino

SerialInit() does not set the hardware right but you have to do that and it does not return an error if the hardware is not setup properly, e.g. Pin used for something else as well or register not set.

Agreed or is there a gap in my knowledge? 

Posted on June 09, 2018 at 17:04

Actually, that's a good point. It looks like a hardware engineer listed all the switches and the software programmer than implemented one function call for each switch. That's a bit harsh and wrong but still. What does the enduser want? An encoder up and running. Error messages if the preconditions are not met. 

(Didn't want to go into multithreaded programming, that's another level of complexity. Just wanted to say that a CPU as powerful as PCs a few additional if-then-else make no difference whereas in a 16MHz you might want to spare that. But there are solutions for that as well like precompiler directives adding these tests in a debug build only.)

Posted on June 09, 2018 at 17:11

Fair point. 

How often would people benefit from the test and error messages though compared to how often they would hinder them?

If they hinder you, would you be able to workaround them, e.g. by using the __HAL methods?

Let's compromise, and we add one layer above the HAL and keep the current HAL as it is. Maybe that is the better request.

PS: Your concrete example is not valid. Encoder with GPIO Input and/or external interrupts is just fine. No reason do not allow that. My example was GPIO plus UART on the same pin - that would be more exceptional.

Posted on June 09, 2018 at 17:29

Not interrupts. Just reading the pins. That could be used for board testing - even before the encoder is installed.

And I can't see why the same could not be done to serial lines.

And believe me, if a new layer was added, then the managers would require that you to use that. You can't win in these. :D

BTW, just came to mind, there are other situations of similar nature (even if not quite the same). I wrote an RS-485 interface for a F4 board.

I used the serial handshaking line for DE, because the F4 didn't support RS-485.

I also wrote a LED driver chip interface - SPI without any chip select. I used the HW NSS pin as GPIO for latching strobe.

Posted on June 09, 2018 at 17:31

While an STM32H7 running at 400-500 MHz with a Double Precision FPU doesn't have the polish of a Pentium or Pentium II, it won't burn my fingers when I press on the top of it.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on June 09, 2018 at 17:35

>>

HAL is somewhere in between, but much closer to your thinking, though not enough I guess.

The goals represented quite a reach, the problem there comes when you keep over-promising, and under-delivering.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..