Skip to main content
Graduate
Mar 11, 2025 3:03 PM UTC
Question

Custom context in callback handlers

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

This topic has been closed for replies.

5 replies

Andrew Neil
Super User
Mar 11, 2025 3:12 PM UTC
A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
mƎALLEm
ST Technical Moderator
Mar 12, 2025 8:33 AM UTC
To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
Pavel A.
Mar 11, 2025 8:13 PM UTC

> 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.

 

 

Andrew Neil
Super User
Mar 11, 2025 9:41 PM UTC

@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:

https://community.st.com/t5/stm32-mcus-embedded-software/is-there-a-way-to-provide-context-pointer-to-hal-callback/m-p/182064

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
unsigned_char_array
Lead III
Mar 12, 2025 8:54 AM UTC

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.

"Kudo posts if you have the same problem and kudo replies if the solution works.Click ""Accept as Solution"" if a reply solved your problem. If no solution was posted please answer with your own."