AnsweredAssumed Answered

Feature request -- please add to HAL the xxx_StructInit() functions from the StdPeriphLib

Question asked by gazzoni.decio on Jul 13, 2015
Latest reply on Jul 13, 2015 by germanovix.gabriel
tl;dr version: ST, please add back the xxx_StructInit() functions as they existed in the Standard Peripheral Library. Systematic use of these functions avoided many subtle bugs due to unitialized struct fields.

Back with the Standard Peripheral Library, about every xxx_Init() function (where xxx = a peripheral like GPIO, DMA, USART, etc.) had a corresponding xxx_StructInit() function as well. The purpose of these functions was to initialize the structs passed to xxx_Init() with default values.

The importance of this function goes well beyond merely selecting the same values that the peripheral takes on when the MCU is booted. The problem is that users may not initialize every field in the struct; and sometimes this seems like the sensible thing to do, because the user supposedly doesn't care about the contents of these values -- maybe a certain feature is not going to be used and the user doesn't care what value the xxx_Init() function will put there. One example is the alternate function configuration for GPIOs on, say, the STM32F4 -- if the GPIO is going to be used in input or software-controlled output mode, it doesn't matter what's on the Alternate field as it's going to be ignored.

However, when a field is not initialized, there may be garbage in them which goes beyond merely a non-sensical value for a given field, and may even spill over to other bits of a given peripheral register, those that configure things that actually matter to the user. This garbage originates from the fact that when a xxx_InitTypeDef struct is created on the stack, unlike when created as a global, it is not initialized by the compiler, and assumes whatever value was in the memory region pointed to by the stack pointer at the time. By the very nature of a stack, memory positions are reused as functions are called, local variables are created, modified and destroyed, and functions are returned from.

Back before the HAL library, I made a habit of calling xxx_StructInit() for every struct that would later be used in a xxx_Init() call, even if I called filled in every single field in the struct. Think of this as a "personal MISRA-C-like rule" of sorts -- MISRA-C forbids quite a few things that are valid, legal and unambiguous C, but may still be confusing or mistake-prone. I created this rule after quite a few long drawn out debugging sessions that came down to uninitialized values in xxx_InitTypeDef structs.

Now with HAL, the xxx_StructInit() calls are gone, so far as I can tell (maybe they got renamed and I didn't notice?) Just today, I spent most of a Sunday afternoon tracing a bug that basically boils down to the HSICalibrationValue being uninitialized -- I wouldn't have noticed it if it was initialized to any fixed value, but the problem was that it was changing as the composition of the stack changed (by adding more local variables to the function). In fact I wasn't even aware that this field existed, but because it wasn't initialized, this cost me the whole of Sunday afternoon. The existence of a xxx_StructInit() function would have prevented this bug from ever existing. This is just the most recent one in a long string of bugs I've had because of the lack of this function. So much so that in our company's homegrown libraries, we started creating our own versions of xxx_StructInit(). Unfortunately it takes time to research the default values for every possible struct, write the code, etc.

Keeping in mind this is something that might benefit lots of HAL users, I kindly request that ST consider the possibility of adding the xxx_StructInit() functions to HAL in a future version.

If anyone else shares my view on the importance of these functions, please add to this thread so we can make it clear to ST how important this issue is.

Thanks in advance to ST and everyone else, and please, no snarky "I'm sorry Dave, I'm afraid I can't do that" responses.