2025-10-31 8:08 AM
When connecting via USB to a STM32 board in DFU mode, it is possible to read a serial number from the instance path.
However, in runtime, the serial number exposed via USB must be programed by the user... It would be nice then if ST provided the algorithm they used to create this string.
We do have some hints though. When generating a STCube project, by default a `Get_SerialNum` function is generated in usbd_desc.c.
However, it does not produce the same string as the bootloader does.
Can anyone please tell us what is the algorithm stored in ROM of each type STM32 to generate the USB serial number string based on the 96-bit UID?
On STM32F76/STM32F77, I have found that this function outputs a string that matches the one produced in ROM:
`static void Get_SerialNum(void)
2025-11-03 3:33 AM
To reproduce the serial number of teh DFU-Bootloader, blackmagic uses:
#elif DFU_SERIAL_LENGTH == 13
/* Use the same serial number as the ST DFU Bootloader.*/
const volatile uint16_t *const uid = (uint16_t *)DESIG_UNIQUE_ID_BASE;
#if defined(STM32F4) || defined(STM32F7)
int offset = 3;
#elif defined(STM32L0) || defined(STM32F0) || defined(STM32F3)
int offset = 5;
#endif
utoa_upper(uid[1] + uid[5], serial_no, 16);
utoa_upper(uid[0] + uid[4], serial_no + 4, 16);
utoa_upper(uid[offset], serial_no + 8, 16);
2025-11-04 2:15 AM
Hi @Areslane
Would you attach the example project to reproduce the issue?
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-11-04 2:29 AM
Thank you, but I am worried for how long and for which boards this code will work, since ST will not document the changes they make in the ROM
2025-11-04 4:45 AM
I cannot share the whole project, as it comes from my company, but the GetSerialNum() function is the one generated by STM32CubeMX:
static void Get_SerialNum(void)
{
uint32_t deviceserial0, deviceserial1, deviceserial2;
deviceserial0 = *(uint32_t *) DEVICE_ID1;
deviceserial1 = *(uint32_t *) DEVICE_ID2;
deviceserial2 = *(uint32_t *) DEVICE_ID3;
deviceserial0 += deviceserial2;
if (deviceserial0 != 0)
{
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
}
}
2025-11-04 5:01 AM
Hi @Areslane again
Would you share minimum project to reproduce or the IOC file?
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-11-06 2:02 AM
Thank you @FBL for trying to debug my code, but my issue is not project dependent.
What we would like to have is official and maintained documentation from ST about the algorithm stored in ROM of each type of STM32 to generate the USB serial number string based on the 96-bit UID in the USB descriptors.
This is important for us, so that we can make sure our boards expose the same serial number string to the USB hosts whether they are in DFU mode or not, without having to rewrite the whole bootloader ourselves with a custom serial number string.
Such documentation is important, as otherwise if we use custom reverse-engineered code like @Uwe Bonnes kindly shared with us, but you change the built-in bootloader algorithm in the new MCUs you produce, it will break our products.
2025-11-06 5:55 AM
For release devices, the code will not change. And what in future happens with new devices, nobody knows and existing code, even reversed must be rechecked,