複数の同じUSBデバイスを識別する方法として、シリアルナンバーで区別する方法がありますが、MicrochipのCDCサンプルプログラムでは以下の通り、シリアルナンバーはサポートされていません。
1 | $ sudo lsusb -d 04d8:000a -v |
2 |
3 | Bus 001 Device 004: ID 04d8:000a Microchip Technology, Inc. CDC RS-232 Emulation Demo |
4 | Device Descriptor: |
5 | bLength 18 |
6 | bDescriptorType 1 |
7 | bcdUSB 2.00 |
8 | bDeviceClass 2 Communications |
9 | bDeviceSubClass 0 |
10 | bDeviceProtocol 0 |
11 | bMaxPacketSize0 8 |
12 | idVendor 0x04d8 Microchip Technology, Inc. |
13 | idProduct 0x000a CDC RS-232 Emulation Demo |
14 | bcdDevice 1.00 |
15 | iManufacturer 1 Microchip Technology Inc. |
16 | iProduct 2 CDC RS-232 Emulation Demo |
17 | iSerial 0 ←ここ |
18 | bNumConfigurations 1 |
19 | Configuration Descriptor: |
20 | bLength 9 |
21 | bDescriptorType 2 |
22 | wTotalLength 67 |
23 | bNumInterfaces 2 |
24 | (以下略) |
そこで、シリアルナンバー対応してみました。
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コネクタに挿入すると、
1 | $ sudo lsusb -d 04d8:000a -v |
2 |
3 | Bus 001 Device 005: ID 04d8:000a Microchip Technology, Inc. CDC RS-232 Emulation Demo |
4 | Device Descriptor: |
5 | bLength 18 |
6 | bDescriptorType 1 |
7 | bcdUSB 2.00 |
8 | bDeviceClass 2 Communications |
9 | bDeviceSubClass 0 |
10 | bDeviceProtocol 0 |
11 | bMaxPacketSize0 8 |
12 | idVendor 0x04d8 Microchip Technology, Inc. |
13 | idProduct 0x000a CDC RS-232 Emulation Demo |
14 | bcdDevice 1.00 |
15 | iManufacturer 1 Microchip Technology Inc. |
16 | iProduct 2 CDC RS-232 Emulation Demo |
17 | iSerial 3 SN000001 |
18 | bNumConfigurations 1 |
19 | Configuration Descriptor: |
20 | bLength 9 |
21 | bDescriptorType 2 |
22 | wTotalLength 67 |
23 | bNumInterfaces 2 |
24 | bConfigurationValue 1 |
25 | : |
26 | : |
27 | 以下略 |
となって、無事にシリアルナンバーがつきました。