Skip to main content
Visitor II
October 31, 2025
Question

DFU USB serial number and runtime STCubeMX generated USB serial number differ.

  • October 31, 2025
  • 3 replies
  • 292 views

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)

{
    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)
    {
        // --- Apply offset to mimic DFU vs APP difference ---
        // Example: add 0xA to the lowest byte of deviceserial0
        uint8_t *p = (uint8_t *)&deviceserial0;
        p[0] = (uint8_t)(p[0] + 0x0A);

        // Now convert to Unicode string as before
        IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
        IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
    }
}`
    This topic has been closed for replies.

    3 replies

    Graduate II
    November 3, 2025

    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);

    AreslaneAuthor
    Visitor II
    November 4, 2025

    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

    Technical Moderator
    November 4, 2025

    Hi @Areslane 

    Would you attach the example project to reproduce the issue?

    AreslaneAuthor
    Visitor II
    November 4, 2025

    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);
     }
    }
    Technical Moderator
    November 4, 2025

    Hi @Areslane again

    Would you share minimum project to reproduce or the IOC file?

    AreslaneAuthor
    Visitor II
    November 6, 2025

    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.

    Graduate II
    November 6, 2025

    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,