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 17:35

:D :D

Posted on June 09, 2018 at 22:02

'

is there a gap in my knowledge? '

user applications are diverse, and such use diversity calls for diversity in approach. As such, there is no one way to program a device.

that's a perspective that you will learn to respect as your experience in programming broadens.

Posted on June 10, 2018 at 00:34

I am not a lawyer but I believe you are allowed to clone the library, fix all the problems you outlined, and publish the result in turn.

JW

Posted on June 10, 2018 at 12:35

Werner Dähn - burn in hell with such suggestions.

HAL is an unfortunate abstraction over cmsis, which in turn is a very unfortunate representation of official documentation - distorted and shortened names of small details.

At the time of creating cmsis, there was one requirement - to implement the primary level of abstraction as quickly as possible. The developers had a positive experience with chips containing very few peripherals, then almost everything was very small and poor. But the forecasts did not materialize, and the periphery increased tens to hundreds of times. There was a problem of shortage of short names - therefore as cmsis it is displayed in space of global names. The output is a long compound name.

HAL, as well as LL - is located above cmsis, they had to add their own prefixes to the already familiar ads.

In the world of big machines and very 'right' programming languages, this approach leads to a sad result. The operations in the code look like one mathematical function for the entire width of the screen - there is no more room for it. The reason is very long variable names, literally half the screen. And they can not make them shorter - all short names are already taken.

This is all the result of using ' ♯ define'. It is quite simple to declare a constant, it is used by everyone to whom not laziness.

What do we learn from the use of the ' ♯ define' of a particular project with HAL, LL, or even cmsis:

For example (TIMx_CCMR1 - TIMx_CCMR2) description of the timer registers - which can not be used simultaneously, because they refer to the same place, but have different values depending on the timer mode. DMA - the value of the registers has a limited meaningful state, but there are no rules at the cmsis level.

Almost every peripheral unit has magical states - when it can perform useful work, and a huge number of states - when it will cause a malfunction. To solve this problem, you have to read the documentation on the chip.

So, HAL, LL and also cmsis - are not able to limit the options for setting the registers. Any new level of abstraction built on their basis - will get old sores, and also add their own (in large numbers). CubeMX can delay the moment a little - when you need to look in the documentation. And this moment appears when you need to write your own.

So the developers have chosen the wrong road at the very beginning of the journey. Now this road is already with a huge track, only the most courageous will be able to get out of it.

But I can suggest the solution: use static structures instead of constants. For example, the GPIOx configuration looks like this:

gpio_install (GPIOE, s_gpio_line.pin_02.out_af_05.speed_100Mgz.pull_up.push_pull.lock_on); /// spi4_sck

Dma register:

 DMA1_Stream2-> CR = sdma_line.dma1.stream_2.ch7_I2C2_RX /// channe - tmigger

                            | sDMA_SxCR_DIR.peripheral_to_memory /// data transfer direction

                            | swDMA_SxCR_PL (3) /// priority level 0-Low, 1-Medium, 2-High, 3-Very high

                            | sDMA_SxCR_MSIZE.t8_bit /// memory data size

                            | DMA_SxCR_MINC /// memory increment mode

                            | sDMA_SxCR_PSIZE.t8_bit /// peripheral data size

                            | DMA_SxCR_EN;

Where is the example

https://community.st.com/external-link.jspa?url=https%3A%2F%2Fbitbucket.org%2FAVI-crak%2Fsystem_f746%2Fsrc%2Fdefault%2Fstm32f7_emus.h

This may seem cumbersome and strange - but this is only the first opinion.

The main advantage of static structures is the once written rules in the form of a branch of the structure. The error of incorrect application is excluded purely physically. When you write the name of a structure in your editor - your choice is limited to existing structure branches. Yes, it is big and very fat - because it describes all magical working states, but it also ignores erroneous and excessive states. You can be horrified at viewing stm32f7_s_gpio_line.h - it's all constants for GPIO !!!

However, such a huge array of data is completely destroyed at the compilation level. GCC takes only that data - that is used in the project. In this case, the structures do not have an address in the project, the structure values do not have an address in the project !!! Data from the static structure is used as a constant at assembler level !!! - this is the maximum annihilation of unnecessary information !!! At the same time, the use of static structures practically does not require reading the documentation on the chip - this is exactly what is required. Bonus - less garbage in the namespace.

In order to use static structures - it is necessary to abandon HAL, LL, and even cmsis. Even I can not afford this in full. It will be possible - when the description of all registers will be created in one style. This is a huge work.

I made an attempt, I liked it. But to carry out such a project in one person - I can not purely physically.

Amen.
Posted on June 10, 2018 at 13:17

It sounds like you have some strong feeling on how we must program our chips according to your wishes. Fortunately the world doesn't work that way.

As to your compliant about cmsis, you may have a unique understanding of what it is.

Posted on June 10, 2018 at 13:28

I use even better solution (where ever I can): I dump all libraries and frameworks and do it myself. That way I have access to every feature the hardware offers and I only define what I need. I'm not a guy that runs up and down the stairs with a loaded shotgun - I don't need that much protection from myself.

Posted on June 10, 2018 at 13:35

The way I see it, is that CubeMX, HAL and CMSIS are steps towards standardized platform onto which it's easier to create code generators and maybe later even IoT blocks. That way companies can spare a lot of money when they can get rid of most of the programmers.

Posted on June 10, 2018 at 13:51

'

I don't need that much protection from myself.'

that's the very point: there is a diverse group of programmers and programming approaches out there. the fact that you don't need protection from yourself has 100% bearing on your applications but zero bearing on their applications.

thus the need for a diverse set of support mechanisms for all of them.

Posted on June 10, 2018 at 13:53

you missed the point of why chip makers invest heavily into their libraries: to tie you down. naive programmers incorporate those libraries heavily into their projects so that it is next to impossible to port their code to another vendor's chips.

once you understand that, you know exactly how those libraries should be used to alleviate your reliance on those libraries.

Posted on June 10, 2018 at 14:31

It looks like you are a brave man who could get out of the rut.

Yes, chip manufacturers make their own unique libraries - incompatible with the rest of the world. This is their right.

However, I am surprised by people who take these libraries and make a standard on them. This is not convenient, about the same - as a man to walk in women's clothes. I apologize for associations - but I'm uncomfortable with this dress in many places.