cancel
Showing results for 
Search instead for 
Did you mean: 

HAL drivers suggestion: Add a user pointer to all peripheral handles

dhaselwood
Associate II

With the current "typedef struct" for peripheral handles, callback code that deals with multiple instances of a peripheral, such as uarts, CANs, etc., often has to do a lookup a lookup on the handle passed to it by the peripheral callback. If the handle included a pointer that the user could set, the callback lookup could be eliminated.

If the .h files for the drivers included "USER" sections, the user could insert a pointer, or add other elements to the struct, but since it appears there is no provision for user code sections in the handle definitions, a pointer would be a solution.

Obviously, one can go into the code at make the changes, but those changes are overwritten if STM32CubeMX is used to update the configuration.

13 REPLIES 13

Can't you just make an overloaded/superstructure where the "handle" points to the HAL typedef, but all your data has a direct/constant relationship?

The callbacks provide you with a user handle/token too, don't they?

typedef struct _SUPER_UART {

UART_HandleTypeDef UartHandle;

UserCrapTypeDef UserCrap;

} SUPER_UART;

SUPER_UART SuperUart = { 0 };

 if (HAL_UART_Init(&SuperUart.UartHandle) != HAL_OK)

 {

   /* Initialization Error */

   Error_Handler();

 }

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

Your suggestion works for the initialization, but the callback provides, e.g. UartHandle, so the callback code has to go through the _SUPER_UART list to find which SUPER_UART to use.

Clive's suggestion is excellent. The callback only needs cast.

It's also excellent because it avoids user-code in the Drivers directory which would impact developers organising super software repositories with many apps/projects building from the one source tree and with only one Drivers directory. STM32CubeMX isn't there yet. But with vision it will.

>>Your suggestion works for the initialization, but the callback provides, e.g. UartHandle, so the callback code has to go through the _SUPER_UART list to find which SUPER_UART to use.

No, it's cleverer than that, they point to the same memory, you don't need to do any list searching, the HAL doesn't copy the structure they pass a handle/object, and you just map it back.

SUPER_UART *local = (SUPER_UART *)huart;

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

What's more you can collect all the other parts back into it, like both DMA descriptors, as I recall they cross-link back into each other. You could arguably index backward too, the structure content have fixed relationship.

static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)

{

 UART_HandleTypeDef* huart = (UART_HandleTypeDef* )(hdma->Parent);

...

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

UART_HandleTypeDef* huart = (UART_HandleTypeDef* )(hdma->Parent);

SUPER_UART *local = (SUPER_UART *)huart;

local->UserCrap.Thing1++;

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

OK, I see what you proposing. The assumption is that the compiler optimizer doesn't rearrange the order which seems to be the practice for aligned elements in a struct.

Yes, it might rely on the compiler generating consistent and coherent code across your project, but if it doesn't you've got much more serious issues to contend with.

They can change the padding, but that is uniformally applied. Otherwise objects and libraries would sliently fail. If your tool-chains balls this up, buy some better ones.

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

Another item in the mix is that STM32CubeMX generates the peripheral handles in non-user areas, e.g. "UART_HandleTypeDef huart2; " is in the "Private variables" section. Making modifications in that area means it gets overwritten if STM32CubeMX regenerates the project.