STM32CubeMX H7 USB CDC bug: usbd_desc.c Get_SerialNum() uninitialized variables cause HardFault on -O1/-O2
There is a critical code-generation template bug in STM32CubeMX (reproduced in 6.16.1 with STM32CubeH7) when generating USB Device middleware configurations. In the generated usbd_desc.c file, the Get_SerialNum() function is generated with uninitialized local variables that are then used in arithmetic operations.
This results in Undefined Behavior (UB). It compiles and works under -O0 because the uninitialized stack happens to evaluate to zero, but it causes an immediate, silent HardFault/BusFault during USB enumeration on Windows when compiled with -O1 or -O2 optimizations
original generated code
static void Get_SerialNum(void)
{
uint32_t deviceserial0; // Uninitialized
uint32_t deviceserial1; // Uninitialized
uint32_t deviceserial2; // Uninitialized
// ST's generator template completely misses the lines assigning the registers!
deviceserial0 += deviceserial2; // Undefined Behavior: addition on uninitialized variables
if (deviceserial0 != 0)
{
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
}
}//proposed fix or at least working code
static void Get_SerialNum(void)
{
uint32_t deviceserial0;
uint32_t deviceserial1;
uint32_t deviceserial2;
/* Explicitly read the Unique Device ID (UID) from the hardware */
deviceserial0 = HAL_GetUIDw0();
deviceserial1 = HAL_GetUIDw1();
deviceserial2 = HAL_GetUIDw2();
deviceserial0 += deviceserial2;
if (deviceserial0 != 0)
{
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
}
}
