2014-10-17 2 views
0

Я разрабатываю приложение для микроконтроллера NXP LPC1788, которое включает в себя связь с основным ПК с использованием USB.Мое устройство USB (микроконтроллер) предотвращает загрузку Windows

В целом приложение работает нормально. Однако что-то, что я заметил с несколькими компьютерами, заключается в том, что если микроконтроллер включен и подключен к отключенному компьютеру, а компьютер затем включается, компьютер не загружается. Отключение микроконтроллера и попытка загрузки компьютера снова разрешит проблему.

Почему микроконтроллер предотвращает загрузку компьютера? У меня проблема с Google, и кажется, что эта проблема возникает, когда Windows пытается рассматривать USB-устройство как загрузочное, если этого не должно быть.

Есть ли способ предотвратить это с моим приложением? Какую информацию я должен предоставить, чтобы помочь другим диагностировать проблему?

В случае, если это полезно, ниже дескриптор устройства в микросистемах:

/* USB Standard Device Descriptor */ 
const uint8_t USB_DeviceDescriptor[] = { 
    USB_DEVICE_DESC_SIZE,    /* bLength */ 
    USB_DEVICE_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    WBVAL(0x0200), /* 2.00 */   /* bcdUSB */ 
    0xFF,        /* bDeviceClass */ 
    0x00,        /* bDeviceSubClass */ 
    0x00,        /* bDeviceProtocol */ 
    USB_MAX_PACKET_SIZE,    /* bMaxPacketSize0 */ 
    WBVAL(<...>),      /* idVendor */ 
    WBVAL(<...>),      /* idProduct */ 
    WBVAL(0x0100), /* 1.00 */   /* bcdDevice */ 
    0x04,        /* iManufacturer */ 
    0x30,        /* iProduct */ 
    0x42,        /* iSerialNumber */ 
    0x01        /* bNumConfigurations */ 
}; 

Вот дескриптор конфигурации:

const uint8_t USB_ConfigDescriptor[] = { 
/* Configuration 1 */ 
    USB_CONFIGURATION_DESC_SIZE,  /* bDescriptorType */ 
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ 
    WBVAL(       /* wTotalLength */ 
    1*USB_CONFIGURATION_DESC_SIZE + 
    1*USB_INTERFACE_DESC_SIZE  + 
    2*USB_ENDPOINT_DESC_SIZE 
), 
    0x01,        /* bNumInterfaces */ 
    0x01,        /* bConfigurationValue */ 
    0x00,        /* iConfiguration */ 
    USB_CONFIG_SELF_POWERED /*|*/  /* bmAttributes */ 
/*USB_CONFIG_REMOTE_WAKEUP*/, 
    USB_CONFIG_POWER_MA(100),   /* bMaxPower */ 
/* Interface 0, Alternate Setting 0, MSC Class */ 
    USB_INTERFACE_DESC_SIZE,   /* bLength */ 
    USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    0x00,        /* bInterfaceNumber */ 
    0x00,        /* bAlternateSetting */ 
    0x02,        /* bNumEndpoints */ 
    0xFF,        /* bInterfaceClass */ 
    0x0,        /* bInterfaceSubClass */ 
    0x0,        /* bInterfaceProtocol */ 
    0x5C,        /* iInterface */ 
/* Bulk In Endpoint (data) */ 
    USB_ENDPOINT_DESC_SIZE,   /* bLength */ 
    USB_ENDPOINT_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    USB_ENDPOINT_IN(2),    /* bEndpointAddress */ 
    USB_ENDPOINT_TYPE_BULK,   /* bmAttributes */ 
    WBVAL(0x0040),      /* wMaxPacketSize */ 
    0x0,        /* bInterval */ 
/* Bulk Out Endpoint (data) */ 
    USB_ENDPOINT_DESC_SIZE,   /* bLength */ 
    USB_ENDPOINT_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    USB_ENDPOINT_OUT(2),    /* bEndpointAddress */ 
    USB_ENDPOINT_TYPE_BULK,   /* bmAttributes */ 
    WBVAL(0x0040),      /* wMaxPacketSize */ 
    0x0,        /* bInterval */ 
/* Terminator */ 
    0         /* bLength */ 
}; 

EDIT

Строка дескриптор (замененные буквы с подчеркиванием):

const uint8_t USB_StringDescriptor[] = { 
/* Index 0x00: LANGID Codes */ 
    0x04,        /* bLength */ 
    USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    WBVAL(0x0409), /* US English */ /* wLANGID */ 
/* Index 0x04: Manufacturer */ 
    0x2C,        /* bLength */ 
    USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    '_',0, 
    '_',0, 
    '_',0, 
    ' ',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    ' ',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    ' ',0, 
/* Index 0x30: Product */ 
    0x14,        /* bLength */ 
    USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    '_',0, 
    ' ',0, 
/* Index 0x42: Serial Number */ 
    0x1A,        /* bLength */ 
    USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
/* Index 0x5C: Interface 0, Alternate Setting 0 */ 
    0x0E,        /* bLength */ 
    USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
    '0',0, 
}; 

EDIT 2

Изменение iManufacturer, iProduct и iSerialNumber к 0x1, 0x2 и 0x3 соответственно делает это так, чтобы USBLyzer не принести строковых дескрипторов, которая не является обнадеживающим признаком. Если я использую исходные значения индекса, он делает это. Я не проверял, как это влияет на способность компьютера загружаться.

EDIT 3

Я заметил, что мои iSerialNumber и iInterface параметры были 2 прочь. 0x30+0x14 = 0x44.

Я посмотрю, исправлено ли что-либо.

EDIT 4

После исправления двух параметров выше, мой вопрос, как представляется, фиксированы. TurboJ привлек мое внимание к тому, что значения индекса должны быть небольшими, например. 0x1, 0x2, 0x3 ...

У NXP, похоже, есть другое представление о том, как это сделать, и я скопировал их путь, но я думаю, что я могу немного изменить код позже, чтобы заставить его работать так, как это делается для других USB-устройств.

+0

Я думаю, что вы можете использовать настройки BIOS и отключить USB от загрузки .. или выбрать HardDisk для начальной загрузки ... – mlwn

+0

Но не будет ли это результатом того, что каждый клиент/конечный пользователь этого приложения должен будет играть со своей BIOS чтобы остановить эту проблему? Я бы предпочел избежать этого, если это возможно. – Tagc

ответ

0

Я исправил свою проблему и улучшил метод NXP.

Примеры проектов USB NXP содержали все дескрипторы строк в одном массиве. Затем они реализованы функции «USB Получить Descriptor» следующим образом:

case USB_STRING_DESCRIPTOR_TYPE: 
    EP0Data.pData = (uint8_t *)USB_StringDescriptor + SetupPacket.wValue.WB.L; 
    len = ((USB_STRING_DESCRIPTOR *)EP0Data.pData)->bLength; 
    break; 

Это означало, что они должны были указать iManufacturer, iProduct и т.д., используя нелепые значения индекса, такие как (в их случае) 0x04, 0x20 и 0x48.

В моем собственном коде я изменил их подход. Я утверждаю, строковые дескрипторы как массив массивов:

const uint8_t USB_StringDescriptor[][100] = { 
    { 
    /* Index 0x00: LANGID Codes */ 
    0x04,        /* bLength */ 
    USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    WBVAL(0x0409), /* US English */ /* wLANGID */ 
    }, 

    { 
    /* Index 0x01: Manufacturer */ 
    0x2A,        /* bLength */ 
    USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    // ... 
    }, 

    { 
    /* Index 0x02: Product */ 
    0x12,        /* bLength */ 
    USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    // ... 
    }, 

    { 
    /* Index 0x03: Serial Number */ 
    0x1A,        /* bLength */ 
    USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    // ... 
    }, 

    { 
    /* Index 0x04: Interface 0, Alternate Setting 0 */ 
    0x0E,        /* bLength */ 
    USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */ 
    // ... 
    } 
}; 

Затем я изменить способ, что запросы строки дескрипторов обрабатываются:

case USB_STRING_DESCRIPTOR_TYPE: 
    EP0Data.pData = (uint8_t *)USB_StringDescriptor[SetupPacket.wValue.WB.L]; 
    len = ((USB_STRING_DESCRIPTOR *)EP0Data.pData)->bLength; 
    break; 

Таким образом, в моем дескрипторе устройства я могу указать iManufacturer, iProduct и т. д. как просто 0x01, 0x02 ...

Я протестировал это на двух компьютерах, и оба могут успешно загрузиться, когда мое приложение подключено и работает.

2
0x04,        /* iManufacturer */ 
0x30,        /* iProduct */ 
0x42,        /* iSerialNumber */ 

Ваши iProduct и iSerialNumber байт, кажется, быть выключен - это порядковые номера, Ususally маленькие. Ваш дескриптор потребует 66 строк в дескрипторе строки. Эти необычные высокие номера могут привести к переполнению в BIOS USB-реализации.

+0

Глядя на дескрипторы других USB-устройств, подключенных к моему компьютеру, вы, кажется, правы, но не могли бы вы объяснить, почему пример устройства USB-устройства предусматривает, что NXP предоставляет набор iManufacturer, iProduct и iSerialNumber так же, как я? http://pastebin.com/0Dg6BrwG Я также добавил свои собственные дескрипторы строк к исходному сообщению. – Tagc

+0

Упрощение для привлечения моего внимания к значениям индекса дескриптора строки, где проблема, но проблема не в том, что я использовал высокие значения индекса (у NXP есть странный способ определения дескрипторов, видимо), а просто, что я был на пару на некоторых из них. – Tagc

Смежные вопросы