问题描述
在使用 rtthread 自己的USB协议栈的时候,看到这个设备的一些信息是写死的:
ALIGN(4)
const static char* _ustring[] =
{
"Language",
"xxxxxxxx",
"yyyyyyyyy",
"32021919830108",
"Configuration",
"Interface",
};
其他还好说,但是这个SN号往往是实际使用的时候需要设备有唯一性,修改方法如下:
// 文件:usbdevice/core/core.c
/**
* This function will handle get_string_descriptor bRequest.
*
* @param device the usb device object.
* @param setup the setup bRequest.
*
* @return RT_EOK on successful, -RT_ERROR on invalid bRequest.
*/
static rt_err_t _get_string_descriptor(struct udevice* device, ureq_t setup)
{
struct ustring_descriptor str_desc;
rt_uint8_t index, i;
rt_uint32_t len;
/* parameter check */
RT_ASSERT(device != RT_NULL);
RT_ASSERT(setup != RT_NULL);
RT_DEBUG_LOG(RT_DEBUG_USB, ("_get_string_descriptor\n"));
str_desc.type = USB_DESC_TYPE_STRING;
index = setup->wValue & 0xFF;
if(index == 0xEE)
{
index = USB_STRING_OS_INDEX;
}
if(index > USB_STRING_MAX)
{
rt_kprintf("unknown string index\n");
rt_usbd_ep0_set_stall(device);
return -RT_ERROR;
}
else if(index == USB_STRING_LANGID_INDEX)
{
str_desc.bLength = 4;
str_desc.String[0] = 0x09;
str_desc.String[1] = 0x04;
}
/* 修改部分 s0:实现厂商自己的序列号机制 */
else if(index == USB_STRING_SERIAL_INDEX)
{
uint8_t jsq_uid[8];
uint8_t jsq_sn[4];
uint32_t mcu_sn[4];
char jsq_id_str[11];
mcu_sn[0] = *(volatile uint32_t *)(0x1FFFF7E8);
mcu_sn[1] = *(volatile uint32_t *)(0x1FFFF7EC);
mcu_sn[2] = *(volatile uint32_t *)(0x1FFFF7F0);
mcu_sn[3] = mcu_sn[0] + mcu_sn[1] + mcu_sn[2];
jsq_uid[7] = (uint8_t)(mcu_sn[3] >> 0) & 0x0f;
jsq_uid[6] = (uint8_t)(mcu_sn[3] >> 4) & 0x0f;
jsq_uid[5] = (uint8_t)(mcu_sn[3] >> 8) & 0x0f;
jsq_uid[4] = (uint8_t)(mcu_sn[3] >>12) & 0x0f;
jsq_uid[3] = (uint8_t)(mcu_sn[3] >>16) & 0x0f;
jsq_uid[2] = (uint8_t)(mcu_sn[3] >>20) & 0x0f;
jsq_uid[1] = (uint8_t)(mcu_sn[3] >>24) & 0x0f;
jsq_uid[0] = (uint8_t)(mcu_sn[3] >>28) & 0x0f;
jsq_sn[0] = (jsq_uid[1]&0x0F)|((jsq_uid[0]<<4)&0xF0);
jsq_sn[1] = (jsq_uid[3]&0x0F)|((jsq_uid[2]<<4)&0xF0);
jsq_sn[2] = (jsq_uid[5]&0x0F)|((jsq_uid[4]<<4)&0xF0);
jsq_sn[3] = (jsq_uid[7]&0x0F)|((jsq_uid[6]<<4)&0xF0);
sprintf(jsq_id_str, "%010u", *(uint32_t *)jsq_sn);
str_desc.bLength = 10*2 + 2;
for(i=0; i<10; i++)
{
str_desc.String[i*2] = jsq_id_str[i];
str_desc.String[i*2 + 1] = 0;
}
}
/* 修改部分 s1:实现厂商自己的序列号机制 */
else
{
len = rt_strlen(device->str[index]);
str_desc.bLength = len*2 + 2;
for(i=0; i<len; i++)
{
str_desc.String[i*2] = device->str[index][i];
str_desc.String[i*2 + 1] = 0;
}
}
if (setup->wLength > str_desc.bLength)
len = str_desc.bLength;
else
len = setup->wLength;
/* send string descriptor to endpoint 0 */
rt_usbd_ep0_write(device, (rt_uint8_t*)&str_desc, len);
return RT_EOK;
}
效果如下: