Skip to main content
dhaselwood
Associate III
April 12, 2019
Question

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

  • April 12, 2019
  • 13 replies
  • 2633 views

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.

This topic has been closed for replies.

13 replies

Tesla DeLorean
Guru
April 12, 2019

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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
dhaselwood
Associate III
April 12, 2019

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.

alister
Senior III
April 12, 2019

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.

dhaselwood
Associate III
April 12, 2019

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.

Tesla DeLorean
Guru
April 12, 2019

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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
dhaselwood
Associate III
April 12, 2019

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.

S.Ma
Principal
April 12, 2019

C++ in C

Grouping elements related to the same functionality is also good when you want to debug them, you'll expand them with the [+] on the watch window....

dhaselwood
Associate III
April 12, 2019

After reviewing the comments and looking at some current code, adding a pointer to the handle typedef struct looks like is still the simplest overall approach. If this means modifying the CubeMX generated .h file, it is only one place that needs restoriation after regeneration with the current CubeMX/HAL drivers. If HAL drivers included a pointer, no restoration is needed after regeneration (and of course no added "USER" sections).

Some months ago when showing CubeMX code to a friend (who has a MS in computer science and 50+ year career of doing this kind of hw & sw), he said that he came around to always including a couple of user settable pointers in these types of structs as he had found that frequently it would turn out later they would be needed.

If CubeMX was used as a OTO code generation tool and no regeneration was to be done, the "SUPER struct" idea would be an alternative. Regeneration of the code involves more places needing restoration than adding the pointer to the typedef struct handle, making the (mistake free!) restoration a bit more of a task.

S.Ma
Principal
April 12, 2019

Can your friend share the most enlightening example from his experience here?

dhaselwood
Associate III
April 12, 2019

I will ask him the next time we get together. He has developed a health problem that makes it almost impossible to type at the keyboard, but his cognitive functioning is good. We are both getting rather ancient. (I wrote my first program in 1960 for an IBM 704 (vacuum tube machine.)

When this issue came up a few months ago he described a notable case where he said that including the user pointers proved to be very useful. IIRC, it had to do with medical monitoring equipment. He wrote the RTOS, roughly 30 yrs ago, and though it has been ported to new processors they are still using the same code.