cancel
Showing results for 
Search instead for 
Did you mean: 

Algorithm to derive USB-DFU DeviceDescriptor.iSerialNumber from UnigueDeviceID?

StanislavHavranek
Associate II

I have a device with STMF412 processor.

This device has UniqueDeviceID [1F 00 23 00 09 51 37 35 31 37 37 36 ]
- Contents of the register "Unique device ID register: (96 bits) at address UID_BASE 0x1FFF7A10UL

---------------------------------

When I boot into the application (USB-CDC communication was generated in CubeIde)
and I connect the device to the PC, so I read the following DeviceDescriptor for the USB-CDC device

Device Descriptor:
  bcdUSB:                     0x0201
  bDeviceClass:            0x02
  bDeviceSubClass:      0x02
  bDeviceProtocol:        0x00
  bMaxPacketSize0:     0x40 (64)
  idVendor:                    0x0483 (STMicroelectronics)
  idProduct:                   0x5740
  bcdDevice:                 0x0200
  iManufacturer:            0x01 0x0409: "STMicroelectronics"
  iProduct:                     0x02 0x0409: "STM32 Virtual ComPort"
  iSerialNumber:           0x03 0x0409: "365A37503537"
  bNumConfigurations: 0x01

The serial number is calculated in the file usdd_desc.c by the function Get_SerialNum()
static void Get_SerialNum(void)
{
    uint32_t deviceserial0, deviceserial1, deviceserial2;

    deviceserial0 = *(uint32_t *) DEVICE_ID1;       // [1F 00 23 00] 0x0023001F
    deviceserial1 = *(uint32_t *) DEVICE_ID2;       // [09 51 37 35] 0x35375109
    deviceserial2 = *(uint32_t *) DEVICE_ID3;       // [31 37 37 36] 0x36373731

    deviceserial0 += deviceserial2; // 0x0023001F+0x36373731 = 0x365A3750

    if (deviceserial0 != 0)
    {
      IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);   "36 5A 37 50"
      IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4); "35 37"
    }
}

---------------------------------

When I boot into DFU
and connect the device to the PC, I read the following DeviceDescriptor for the USB-DFU device

Device Descriptor:
  bcdUSB:                    0x0100
  bDeviceClass:           0x00
  bDeviceSubClass:     0x00
  bDeviceProtocol:        0x00
  bMaxPacketSize0:     0x40 (64)
  idVendor:                    0x0483 (STMicroelectronics)
  idProduct:                   0xDF11
  bcdDevice:                  0x2200
  iManufacturer:             0x01 0x0409: "STMicroelectronics"
  iProduct:                      0x02 0x0409: "STM32 BOOTLOADER"
  iSerialNumber:            0x03 0x0409: "365A375A3537"
  bNumConfigurations:  0x01

---------------

Does anyone know how to derive the DFU-bootloader from the UniqueDeviceID [1F 00 23 00 09 51 37 35 31 37 37 36 ]
that serial number "365A375A3537" ? Which, unlike the CubeIde serial number, has the value "5A" instead of "50"?

( "365A37503537" vs "365A375A3537")

1 ACCEPTED SOLUTION

Accepted Solutions

The F411 looks to have an algorithm like you describe. Are you sure you read the UID correctly?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

6 REPLIES 6
jiangfan
ST Employee

I guess the DFU-bootloader uses a bit different Get_SerialNum() implementation than the usdd_desc.c implementation for STM32F412.

It is clear to me that DFU-bootloader uses a slightly different implementation of Get_SerialNum() than usdd_desc.c for STM32F412.

But which one? The source code for the bootloader is not public, so I don't have a chance to see what the function looks like, how the serial number is created.

But ST should have the source code. It would help me a lot if you could publish the way the serial number is created.

The F411 looks to have an algorithm like you describe. Are you sure you read the UID correctly?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Yes, I read the UID correctly.
I tried comparing the serial number in DFU mode and CDC mode for multiple processors and it was different each time

                                          STM32F412VETX STM32F412VETX STM32F412VGT6
"STM32 BOOTLOADER"  "3547363D3536"   "333FB6473132"   "B837B94C3231"
"STM32 Virtual ComPort"  "354736333536"   "333FB63D3132"   "B837B9423231"

Looks like the bootloader simply adds 10 to the 2nd byte before converting it to the UCS-2 string. I have no idea what made ST to do that.

While the bootloader sources are not available, you still can run the bootloader with debugger attached, place a data breakpoint ("watchpoint") to the UniqueID, and single-step in asm to see what happens with it (should be quite straighforward).

Of course, there's no guarantee for this to remain the same when the bootloader changes - rarely, but they do, if an error is discovered, see versions in AN2606.

JW

I looked at the F411 to hand, and that didn't add the 10, it was the usual computation.

Can you dump the ROM from 0x1FFF0000..0x1FFF7FFF, and I'll take a look at the binary.

Thanks, -Clive

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..