cancel
Showing results for 
Search instead for 
Did you mean: 

C-Library const-correctness for STM32F1xx

Brian H
Senior

I think const-correctness is an important-enough concept to call this a bug report.

In the HAL Driver for STM32F1xx, much of the codebase is not const-correct.  For G4xx, I see that I2C is not.

What is const-correctness in C?

If a function that accepts a pointer to some data doesn't change that data, the function can tell the calling context that fact by declaring the buffer pointer to be const, like so:

void i_do_not_change_the_data(const void * data_ptr);

Then the calling context can be sure that the function will not attempt to write to the buffer, and can take advantage of compiler and language optimizations surrounding const arguments.  One such (poor) example is a string literal, which can serve as a const char * argument, but not a char * argument.

Most (all?) of the HAL functions that take pointers to buffers take non-const pointers, even if those functions don't write to the buffer.  That means that I cannot write my own code to be const-correct without casting away the constness, exposing my code to undefined behaviors.

Unfortunately, this problem runs extremely deeply in the library code, all the way down to HAL struct members.  TX buffers in particular should be declared as const *, but they're not, so const pointers can't be assigned to them and the APIs can't be corrected.

This needs an intense application of effort to correct.  If ST intends its HAL libraries to be suitable for production code, this really ought to be fixed.

All pointer arguments to functions should be const unless they can't be.  Const-ness should be a forethought, not an afterthought.

1 ACCEPTED SOLUTION

Accepted Solutions

> Not for me.  From "stm32f1xx_hal_spi.h" as found in the project I'm working on now:

Might want to update your library then. It's const in the latest version. Looks like it may have been updated 7 months ago.

stm32f1xx-hal-driver/Inc/stm32f1xx_hal_spi.h at 9577d269eed0a141a7e339adcaf434c325738b99 · STMicroelectronics/stm32f1xx-hal-driver

TDK_0-1739375163820.png

 

 

The USB code is part of Middlewares, not HAL, and is generally lower quality/robustness. Should be corrected there, but doing a const-cast doesn't cause problems.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

9 REPLIES 9
Pavel A.
Evangelist III

 If ST intends its HAL libraries to be suitable for production code

That's a big if.

 

TDK
Guru

> TX buffers in particular should be declared as const *, but they're not, so const pointers can't be assigned to them and the APIs can't be corrected.

Most buffers are declared this way. For example (F4 SPI as a randomly chosen example):

const uint8_t *pTxBuffPtr; /*!< Pointer to SPI Tx transfer Buffer */

and the calling function takes a pointer to const:

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size, uint32_t Timeout);

 

Since most functions are changing the peripheral state in some way, it makes sense for most of them to take non-const handles. Things that are read-only take a const handle. For example:

HAL_SPI_StateTypeDef HAL_SPI_GetState(const SPI_HandleTypeDef *hspi);

 

 

Are there specific other examples where you think this should be looked at? Certainly the intention is already there to make things const-correct.

If you feel a post has answered your question, please click "Accept as Solution".
gbm
Principal

That's an old and well-known problem. Also, init structures' pointers are not const-qualified, so any config structure must be variable although it never gets modified.

Besides const there are few other C keywords and constructs unknown to HAL people, like bool type, enum, structure initializers and compound literals. This might be for the sake of C90 or maybe FORTRAN compatibility. ;)

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Saket_Om
ST Employee

Hello @Brian H 

Our HAL driver is compliant with the rule 8.13 of MISRA C 2012. 

"Rule 8.13:  A pointer should point to a const-qualified type whenever possible"

A const qualifier has been added to pointer argument of HAL API whenever is possible. 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

Not for me.  From "stm32f1xx_hal_spi.h" as found in the project I'm working on now:

 

 

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);

HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);

 

 

The one I encountered that "triggered" me, so to speak, is from the USB CDC implementation:

 

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);

 

So maybe it varies across platforms.

Edit: I just checked the H5xx project I have, and it's much better.  So clearly it is inconsistent across the processor families.


@Saket_Om wrote:

Hello @Brian H 

Our HAL driver is compliant with the rule 8.13 of MISRA C 2012.  


No it isn't.  Not in the project I created some time last year against STM32F1xx.  See my reply to TDK with quotes from the stm32f1xx_hal_spi.h file for example.  In fact, I'll attach the entire SPI driver header to this message and you can observe for yourself how the keyword const does not appear anywhere in the file.

In fact, let's see how many times the const keyword appears in the entire include path.  In project_path/Drivers/STM32F1xx_HAL_Driver, I did this:

$ grep -r "\<const\>" > constness.txt

and

$ grep -rc "\<const\>" > constness_count.txt

Too much output for the body of this post, but take note of how many files have zero uses of the const keyword (in constness_count.txt).

So, no.  HAL Driver for STM32F1xx is not compliant with Rule 8.13.

In case it's a version issue (maybe you guys JUST fixed it), tell me how to check what version of the library is installed and I will (I can't find it).

Brian H
Senior

Note: Since the const-correctness of HAL Driver clearly varies across supported processor families, I've edited my original post to be more specific to the families where I've directly observed the problem.

I think it would be good for STM to audit the entire set of HAL Driver packages across all supported processor families to ensure none are missed.

To summarize, for the processors I've worked with lately:

STM32H5xx - good const-correctness (as far as I looked, which was not exhaustive)

STM32G4xx - bad const-correctness

STM32F1xx - bad const-correctnes

Clearly the concept is understood, but the implementation is incomplete.

> Not for me.  From "stm32f1xx_hal_spi.h" as found in the project I'm working on now:

Might want to update your library then. It's const in the latest version. Looks like it may have been updated 7 months ago.

stm32f1xx-hal-driver/Inc/stm32f1xx_hal_spi.h at 9577d269eed0a141a7e339adcaf434c325738b99 · STMicroelectronics/stm32f1xx-hal-driver

TDK_0-1739375163820.png

 

 

The USB code is part of Middlewares, not HAL, and is generally lower quality/robustness. Should be corrected there, but doing a const-cast doesn't cause problems.

If you feel a post has answered your question, please click "Accept as Solution".

@TDK wrote:

> Not for me.  From "stm32f1xx_hal_spi.h" as found in the project I'm working on now:

Might want to update your library then. It's const in the latest version. Looks like it may have been updated 7 months ago.

stm32f1xx-hal-driver/Inc/stm32f1xx_hal_spi.h at 9577d269eed0a141a7e339adcaf434c325738b99 · STMicroelectronics/stm32f1xx-hal-driver


Seven months ago qualifies as "JUST fixed it", I'd say; my project is easily that old.  For a rule that was ratified in 2012, I feel moderately justified in still being irritated that the codebase wasn't compliant until sometime in 2024.  That said, I also do understand that it's a lot of code...that they could've written "correctly" to begin with.  </rant>

 


The USB code is part of Middlewares, not HAL, and is generally lower quality/robustness. Should be corrected there, but doing a const-cast doesn't cause problems.


Not sure what you mean by "doing a const-cast doesn't cause problems" from the standpoint of an API consumer.  If the API doesn't declare the argument to be a const pointer, then I have no reason to trust it not to try to write to the pointed-to location.  I'm not going to de-const a pointer I declared const to provide it to a non-const API, even if I can read all the code.  It's just a bad practice.

Anyway, it looks like I'm operating on out-of-date libraries, in any case.

Thanks, everyone.