This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to change the usb serial number

Hi

I have a unique serial number saved in EEPROM for each PCB, I want to assign that serial number string to the USB descriptor, so on windows, I can see that serial number. How can I do this? I see the USB descriptor serial number is defined as macro, can't be changed in run-time.

Thanks
Wang

Parents Reply Children
  • String descriptor structure on RAM

    On RL-USB library, USBD_StringDescriptor structure, defined on usb_lib.c, gives the all string descriptors on the device, including the serial number string. As the default, this structure is assigned to ROM by "const" modifier. Deleting "const" modifier, this structure is placed on RAM, so that it can be modified at run time.

    1) Copy C:\Keil\ARM\RV31\INC\usb_lib.c to your project folder, and rename it.
    2) Change usb_lib.c reference in usb_config.c at the bottom of this file.

    usb_config.c
    
    #ifndef  __NO_USB_LIB_C
    #include <usb_lib.c>    // <--- change to "renamed_usb_lib.c"
    #endif
    


    Now that you may customize renamed usb_lib.c as you like.

    3) Near the bottom of usb_lib.c, USBD_StringDescriptor is defined.
    Delete "const" from this definition.

    usb_lib.c
    
    __weak \ 
    const struct {      // <--- delete "const" of this line
      struct {
        U8  len;
        U8  type;
        U16 langid;
      } desc_langid;
      USBD_STR_DEF(STRDESC_MAN);
      USBD_STR_DEF(STRDESC_PROD);
    #if  (USBD_STRDESC_SER_ENABLE)
      USBD_STR_DEF(STRDESC_SER);
    #endif
    ...
    ...
    } USBD_StringDescriptor
    

    4) At the start-up initialization in main(), before "usbd_connect(__TRUE);" is called,
    the string descriptor for serial number is replaced to those read out from EEPROM.

    USBD_StringDescriptor.descSTRDESC_SER.len (U8 variable) - length of custom string + 2
    USBD_StringDescriptor.descSTRDESC_SER.str[] (U16 array) - body of custom string in UNICODE

    Ah, you have to assign dummy string of enough length to USBD_STRDESC_SER

    usb_config.c
    
    #define USBD_STRDESC_SER            L"0001A0000000"  // <---  assign dummy string of enough length
    




    USB_ReqGetDescriptor() routine may be overridden, but it isn't safe without original source code of this routine.

    Tsuneo

  • Great! Thanks Tsuneo! Will try it now.

  • An interesting thing here is this part:

    __weak \   <==== weak linkage, so another file can contain a symbol of same name to replace this.
    const struct {
      struct {
        U8  len;
        U8  type;
        U16 langid;
      } desc_langid;
    

    So in case this file contains lots of other things that a user do not want to change, then another source file should be able to redeclare USBD_StringDescriptor.

  • Aha, I know how how "__week" works.
    But in this case, USBD_StringDescriptor definition uses bunch of #define macros and conditional compilation, which are defined in usb_lib.c and usb_config.c. To extract USBD_StringDescriptor definition, we have to make these macros referable. It's so troublesome. In this reason, above method is easier and safer, just to delete "const" modifier.

    Tsuneo