複数の同じUSBデバイスを識別する方法として、シリアルナンバーで区別する方法がありますが、MicrochipのCDCサンプルプログラムでは以下の通り、シリアルナンバーはサポートされていません。
$ sudo lsusb -d 04d8:000a -v Bus 001 Device 004: ID 04d8:000a Microchip Technology, Inc. CDC RS-232 Emulation Demo Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 2 Communications bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x04d8 Microchip Technology, Inc. idProduct 0x000a CDC RS-232 Emulation Demo bcdDevice 1.00 iManufacturer 1 Microchip Technology Inc. iProduct 2 CDC RS-232 Emulation Demo iSerial 0 ←ここ bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 67 bNumInterfaces 2 (以下略)
そこで、シリアルナンバー対応してみました。
usb_descripters.c の 166行目付近の device_dsc を以下のように修正します。
/* Device Descriptor */ ROM USB_DEVICE_DESCRIPTOR device_dsc= { 0x12, // Size of this descriptor in bytes USB_DESCRIPTOR_DEVICE, // DEVICE descriptor type 0x0200, // USB Spec Release Number in BCD format CDC_DEVICE, // Class Code 0x00, // Subclass code 0x00, // Protocol code USB_EP0_BUFF_SIZE, // Max packet size for EP0, see usb_config.h 0x04D8, // Vendor ID 0x000A, // Product ID: CDC RS-232 Emulation Demo 0x0100, // Device release number in BCD format 0x01, // Manufacturer string index 0x02, // Product string index 0x03, // Device serial number string index 0x01 // Number of possible configurations };
修正したのは下から2つめの「// Device serial number string index」で、0x00だったのを0x03にして、string indexの3がシリアルナンバーであることを指定します。
さらに同じファイルのもっと後の方にstring descriptorの定義があるので、ここも修正します。
//Language code string descriptor ROM struct{BYTE bLength;BYTE bDscType;WORD string[1];}sd000={ sizeof(sd000),USB_DESCRIPTOR_STRING,{0x0409}}; //Manufacturer string descriptor ROM struct{BYTE bLength;BYTE bDscType;WORD string[25];}sd001={ sizeof(sd001),USB_DESCRIPTOR_STRING, {'M','i','c','r','o','c','h','i','p',' ', 'T','e','c','h','n','o','l','o','g','y',' ','I','n','c','.' }}; //Product string descriptor ROM struct{BYTE bLength;BYTE bDscType;WORD string[25];}sd002={ sizeof(sd002),USB_DESCRIPTOR_STRING, {'C','D','C',' ','R','S','-','2','3','2',' ', 'E','m','u','l','a','t','i','o','n',' ','D','e','m','o'} }; //Serial string descriptor これを追加 ROM struct{BYTE bLength;BYTE bDscType;WORD string[8];}sd003={ sizeof(sd003),USB_DESCRIPTOR_STRING, {'S','N','0','0','0','0','0','1'} }; //Array of configuration descriptors ROM BYTE *ROM USB_CD_Ptr[]= { (ROM BYTE *ROM)&configDescriptor1 }; //Array of string descriptors ROM BYTE *ROM USB_SD_Ptr[USB_NUM_STRING_DESCRIPTORS]= { (ROM BYTE *ROM)&sd000, (ROM BYTE *ROM)&sd001, (ROM BYTE *ROM)&sd002, (ROM BYTE *ROM)&sd003 // これを追加 };
追加箇所は2箇所、sd003に関するところです。
この修正だけだとUSB_NUM_STRING_DESCRIPTORSの定義が変わらないため、コンパイルでエラーが出ますので、usb_config.h も修正します。144行目に
#define USB_NUM_STRING_DESCRIPTORS 3
というのがあるので、これを
#define USB_NUM_STRING_DESCRIPTORS 4
に修正します。
これでコンパイルしてFlashに書き込んで、USBコネクタに挿入すると、
$ sudo lsusb -d 04d8:000a -v Bus 001 Device 005: ID 04d8:000a Microchip Technology, Inc. CDC RS-232 Emulation Demo Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 2 Communications bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x04d8 Microchip Technology, Inc. idProduct 0x000a CDC RS-232 Emulation Demo bcdDevice 1.00 iManufacturer 1 Microchip Technology Inc. iProduct 2 CDC RS-232 Emulation Demo iSerial 3 SN000001 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 67 bNumInterfaces 2 bConfigurationValue 1 : : 以下略
となって、無事にシリアルナンバーがつきました。