2025-03-11 8:03 AM - edited 2025-03-11 8:04 AM
Hello,
I would like to request a feature to be added to the STM32 HAL.
Would it be possible to be able to add a custom user context when registering peripheral callbacks.
Example:
HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID, pSPI_CallbackTypeDef pCallback, void* UserContext);
And then as callback function:
typedef void (*pSPI_CallbackTypeDef)(SPI_HandleTypeDef *hspi, void* UserContext);
I really miss this feature and have had to code around it for god knows how many times.
I have added it myself to the SPI driver, but if I regenerate its all gone ofc.
So it would be real nice if this could be added to drivers.
Thx,
Alexander
2025-03-11 8:12 AM - edited 2025-03-11 8:19 AM
This has been requested before:
Recently (Oct 2024): https://community.st.com/t5/stm32-mcus-embedded-software/feature-request-pass-arbitrary-data-pointer-in-hal-callbacks/m-p/727806
Older (May 2021): https://community.st.com/t5/stm32-mcus-products/is-there-a-way-to-provide-context-pointer-to-hal-callback/m-p/182064
PS:
Apparently being "tracked internally" by @mƎALLEm:
2025-03-11 1:13 PM - edited 2025-03-11 1:14 PM
> I have added it myself to the SPI driver, but if I regenerate its all gone
To avoid losing your changes in the HAL libraries:
- When you use Cube to (re)generate code, select the option to create links to the libraries instead of copying all the files into your project.
- Check your changes in the ST libraries into your version control (yes, make your private branch).
To minimize code differences, do not pass the UserContext as a new argument. Instead, add it to the SPI_HandleTypeDef struct. Then your callbacks will get this arg from the hspi pointer: hspi->UserContext.
2025-03-11 2:41 PM
@Pavel A. wrote:To minimize code differences, do not pass the UserContext as a new argument. Instead, add it to the SPI_HandleTypeDef struct.
@Alexander4 there was some discussion of this in the 2021 thread:
2025-03-12 1:33 AM
@Andrew Neil wrote:
This has been requested before:
Recently (Oct 2024): https://community.st.com/t5/stm32-mcus-embedded-software/feature-request-pass-arbitrary-data-pointer-in-hal-callbacks/m-p/727806
Older (May 2021): https://community.st.com/t5/stm32-mcus-products/is-there-a-way-to-provide-context-pointer-to-hal-callback/m-p/182064
PS:
Apparently being "tracked internally" by @mƎALLEm:
Escalated as well..
2025-03-12 1:54 AM - edited 2025-03-12 2:22 AM
I agree it should have been added to the function argument or to the handler struct.
Alternatively you can create a mapping table.
Some pseudocode:
typedef void (*usercallback_t)(SPI_HandleTypeDef *hspi, void* usercontext);
typedef struct
{
void *peripheral;
void *usercontext;
usercallback_t function;
} usercontext_mapping_t;
static usercontext_mapping_t mappingtable[N];
void callback(SPI_HandleTypeDef *hspi)
{
if (hspi == NULL) return
for(int i=0;i<N;++i)
{
if(mappingtable[i].peripheral == hspi->instance)
{
if (mappingtable[i].function != NULL)
{
mappingtable[i].function(hspi, mappingtable.usercontext);
}
break;
}
}
}
Create a wrapper function around HAL_SPI_RegisterCallback that automatically registers the function and adds user context to the table. You can also wrap the deregister function.
I prefer creating wrapping functions over rewriting part of the functions. While it adds some overhead in terms of stack and CPU time that usually is not a problem. Once it becomes a problem I would switch from HAL to LL and write my own library.