cancel
Showing results for 
Search instead for 
Did you mean: 

USB serial number size

EThom.3
Associate III

As others before me, I wish to make my own serial number in a USB CDC device. This isn't the problem – I know how to do that.

However, I am puzzled about how the unique serial number is generated in the code auto-generated in STM32CubeIDE. Specifically the functions Get_SerialNum() and IntToUnicode() in usbd_desc.c.

/**
  * @brief  Create the serial number string descriptor
  * @PAram  None
  * @retval None
  */
static void Get_SerialNum(void)
{
  uint32_t deviceserial0;
  uint32_t deviceserial1;
  uint32_t 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);
  }
}

/**
  * @brief  Convert Hex 32Bits value into char
  * @PAram  value: value to convert
  * @PAram  pbuf: pointer to the buffer
  * @PAram  len: buffer length
  * @retval None
  */
static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len)
{
  uint8_t idx = 0;

  for (idx = 0; idx < len; idx++)
  {
    if (((value >> 28)) < 0xA)
    {
      pbuf[2 * idx] = (value >> 28) + '0';
    }
    else
    {
      pbuf[2 * idx] = (value >> 28) + 'A' - 10;
    }

    value = value << 4;

    pbuf[2 * idx + 1] = 0;
  }
}

The three 32-bit values retrieved in lines 12 - 14 above, are together the Unique device ID of the microcontroller (UID[95:0]. For me, it would make sense to use all 96 bits or 24 hex digits to generate a unique ID. As the descriptor is supposed to be written the UTF-16, this would be a string of 48 bytes. I have read elsewhere, that the maximum number of bytes for any descriptor is 126 + 2 bytes. Yet, the constant USB_SIZ_STRING_SERIAL constant in usbd_desc.h limits the descriptor to 24 + 2 bytes, i.e. 12 UTF-16 characters.

To "fit" the 24 hex digits into half the size, the code "shrinks" the UID by adding UID[31:0] and UID[95:64] together, for the first 8 digits, and then uses half of UID[63:32] for the remaining 4.

Can anyone explain why? Am I missing something? Can the serial number really only be 12 hex digits in length?

4 REPLIES 4
TDK
Guru

It was an implementation decision to have serial numbers of that length, not a USB requirement/restriction. Serial numbers can be longer but become unwieldy at some point.

The odds of a serial number conflict with 12 hex digits are quite small (1:281 trillion).

If you feel a post has answered your question, please click "Accept as Solution".
Pavel A.
Evangelist III

It can be longer than 12 characters. Maybe some old host systems have problems with longer strings.

 

> The odds of a serial number conflict with 12 hex digits are quite small (1:281 trillion).

That would hold if they would be random. They are not.

OTOH, the examples are just that, examples. Nobody really cares.

JW

EThom.3
Associate III

Okay, thanks a lot gentlemen. I appreciate it.