Паф 0 23 июня, 2009 Опубликовано 23 июня, 2009 · Жалоба Разработано CDC USB устройство с питанием от шины. Пишется PC программа для настройки и апгрейда устройства. Из PC программы необходимо сделать ресет устройства для перехода в наш бутлодер. Пробуем DeviceIoControl(), но что-то не выходит. Кто-нибудь делал такую вещь??? Помогите плиз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex11 6 23 июня, 2009 Опубликовано 23 июня, 2009 · Жалоба Мы делали в системе команд, передаваемых по CDC (виртуальному COM-порту), команду перейти в Boot. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Паф 0 23 июня, 2009 Опубликовано 23 июня, 2009 · Жалоба To Alex11: Девайс работает под 1С по CAS протоколу. А наша РС программа нужна лишь для апгрейда прошивки, в ней другой протокол и в бутлодере соответственно тоже. Не хотелось бы парсить лишнюю команду в основной программе процом, но видимо придется ввести уникальную на ресет. Вариант с ресетом девайса от хоста выглядит наиболее удачным. Смысл в разделении протоколов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 45 23 июня, 2009 Опубликовано 23 июня, 2009 · Жалоба Из PC программы необходимо сделать ресет устройства для перехода в наш бутлодер. Пробуем DeviceIoControl(), но что-то не выходит. Кто-нибудь делал такую вещь??? В протоколе USB нет и не может быть такой команды, получатель которой делал бы себе харакири :). Поэтому копать надо не в сторону поиска такой экзотической USB-команды, а в сторону интерпретации уже имеющихся в протоколе команд. Например, интерфейсная команда SEND_BREAK используется крайне редко, вот на ее обработчик (в вашем USB-устройстве) вы могли бы повесить ресет (блокировать прерывания + поставить самый быстрый WatchDog + войти в вечный цикл). Тогда для ресета микропроцессора было бы достаточно послать на виртуальный COM-порт команду с помощью API-шной Windows-функции SetCommBreak. При этом нет необходимости делать интерпретатор идущего по линии потока данных, поскольку интерфейсные команды поступают иным путем. P.S. Только не забудьте, сразу же закрыть COM-порт (CloseHandle) со стороны компьютера, а после ресета снова его открыть, иначе после ресета USB-порт откажется разговаривать с устройством, позабывшим свой адрес. Т.е. рискуете тем, что устройство перезапустится на bootloader, но USB-канал зависнет в патовой комбинации, из которой выйти можно только вручную - выдернуть и снова воткнуть USB-кабель. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Паф 0 23 июня, 2009 Опубликовано 23 июня, 2009 · Жалоба Вот есть интересная ссылочка USB Developers FAQ: http://www.lvr.com/usbfaq.htm "How can my application reset, disable, or restart a USB device? The DevCon example in the Windows DDK is a command-line utility that shows how to enable, disable, restart, update, remove and query devices using the SetupAPI and CfgMgr32 API functions." Вот этот пример и не получается разжечь!!! А если SetCommBreak пошлет не моя программа, а какая-нибудь тулза юзера?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Паф 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Получилось! :) Кому интересно: код функции, которая реализует посылку хостом команды Reset устройству. В качестве параметра в нее передается USB product string descriptor устройства. ///////////////////////////////////////////////////////////////////////////// #include "SetupApi.h" #pragma comment(lib, "SetupApi") bool ResetPortDevice(const char *Name); // Name - USB product string descriptor ///////////////////////////////////////////////////////////////////////////// bool ResetPortDevice(const char *Name) { BOOL bRes; LPGUID pClassGuidList, piClassGuidList; DWORD i, j, need_size; HDEVINFO DeviceInfoSet; SP_DEVINFO_DATA DeviceInfoData; SP_PROPCHANGE_PARAMS PropChange; BYTE *pData; pData = new BYTE[1+strlen(Name)]; if (!pData) return false; // Request number of 'Ports' items need_size = 0; pClassGuidList = NULL; SetupDiClassGuidsFromName("Ports", pClassGuidList, need_size, &need_size); if (!need_size) { delete [] pData; return false; } // Request all 'Ports' items piClassGuidList = pClassGuidList = new GUID[need_size]; if (!pClassGuidList) { delete [] pData; return false; } bRes = SetupDiClassGuidsFromName("Ports", pClassGuidList, need_size, &need_size); if (!bRes) { delete [] pData; delete [] pClassGuidList; return false; } // Loop by all GUIDs for (i = 0; i < need_size; i++, pClassGuidList++) { // Get list of devices DeviceInfoSet = SetupDiGetClassDevs(pClassGuidList, NULL, NULL, DIGCF_PRESENT); if (DeviceInfoSet == INVALID_HANDLE_VALUE) continue; DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); PropChange.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); PropChange.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; PropChange.StateChange = DICS_PROPCHANGE; // For reset !!! PropChange.Scope = DICS_FLAG_CONFIGSPECIFIC; PropChange.HwProfile = 0; // Loop by all devices by given GUID for (j = 0; SetupDiEnumDeviceInfo(DeviceInfoSet, j, &DeviceInfoData); j++) { if (GetLastError() == ERROR_NO_MORE_ITEMS) break; // Try get extended information bRes = SetupDiGetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_LOCATION_INFORMATION, NULL, pData, 1+strlen(Name), NULL); if (!bRes) continue; if (strstr((const char *)pData, Name) == NULL) continue; // Apply function for the found device (i.e. Reset) bRes = SetupDiSetClassInstallParams(DeviceInfoSet, &DeviceInfoData, &PropChange.ClassInstallHeader, sizeof(PropChange)); if (!bRes) break; bRes = SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DeviceInfoSet, &DeviceInfoData); if (!bRes) break; } // Clear list of devices bRes = SetupDiDestroyDeviceInfoList(DeviceInfoSet); if (!bRes) break; } // Clear arrays delete [] piClassGuidList; delete [] pData; if (!bRes) return false; return true; } ///////////////////////////////////////////////////////////////////////////// Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 45 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Получилось! :) Кому интересно: код функции, которая реализует посылку хостом команды Reset устройству. Ресет USB-устройства и ресет удаленного микропроцессора - вещи совершенно разные! Reset USB-устройства это разрыв логического соединения, а затем его новое соединение с повторным чтением всех дескрипторов и присвоением нового адреса (SET_ADDRESS). Эта процедура происходит на уровне протоколов. Напротив, ресет микроконтроллера означает его физический перезапуск, вследствие чего он имеет возможность запуститься с загрузчика. Никаким ресетом порта вам не заставить перезапусться микроконтроллер! А если SetCommBreak пошлет не моя программа, а какая-нибудь тулза юзера?? Отвечу вам в тон: а что если тулза юзера сделает то же самое, что делает код вашей функции? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Паф 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Может я не совсем точно сформулировал сабж. То что мы хотели, мы получили: микроконтроллер получает стандартную команду от хоста и переходит в бут. Никаких лишних интерпретаций основного протокола. Какова вероятность того что от хоста случайно придет SetCommBreak или несколько байт с правильной CRC(команда)? По-моему второе значительно надежнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Седой 0 26 июня, 2009 Опубликовано 26 июня, 2009 · Жалоба Может я не совсем точно сформулировал сабж. То что мы хотели, мы получили: микроконтроллер получает стандартную команду от хоста и переходит в бут. Никаких лишних интерпретаций основного протокола. Вы сделали программный вызов функции стандартного Class Installer, что соответствует последовательности пунктов меню устройства в Диспетчере устройств Отключить и Задействовать - это не способ перевода устройства в режим загрузчика. Пользователь имеет полное право выбирать эти пункты меню и ... ваше устройство перешло в режим upgrade. Вы предусмотрели выход из такой ситуации? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HARMHARM 0 28 июня, 2009 Опубликовано 28 июня, 2009 · Жалоба Только не забудьте, сразу же закрыть COM-порт (CloseHandle) со стороны компьютера, а после ресета снова его открыть, иначе после ресета USB-порт откажется разговаривать с устройством, позабывшим свой адрес. Т.е. рискуете тем, что устройство перезапустится на bootloader, но USB-канал зависнет в патовой комбинации, из которой выйти можно только вручную - выдернуть и снова воткнуть USB-кабель. Это все правда. Но для загрузчика можно иметь другой VID/PID, и тогда это будет другой порт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Паф 0 29 июня, 2009 Опубликовано 29 июня, 2009 (изменено) · Жалоба Вы сделали программный вызов функции стандартного Class Installer, что соответствует последовательности пунктов меню устройства в Диспетчере устройств Отключить и Задействовать - это не способ перевода устройства в режим загрузчика. Пользователь имеет полное право выбирать эти пункты меню и ... ваше устройство перешло в режим upgrade. Вы предусмотрели выход из такой ситуации? Юзер может Отключить и Задействовать видеокарту например, это его право. Да устройство перейдет в режим upgrade и выйдет из него через несколько секунд в application не получив команд от PC программы. Подскажите пожалуйста другое более правильное решение, если знаете. За этим и создан топик. Изменено 29 июня, 2009 пользователем Паф Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Седой 0 29 июня, 2009 Опубликовано 29 июня, 2009 · Жалоба Юзер может Отключить и Задействовать видеокарту например, это его право. Да устройство перейдет в режим upgrade и выйдет из него через несколько секунд в application не получив команд от PC программы. Подскажите пожалуйста другое более правильное решение, если знаете. За этим и создан топик. Зачем изобретать велосипед, см. Device Class Specification for Device Firmware Upgrade http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Паф 0 30 июня, 2009 Опубликовано 30 июня, 2009 · Жалоба Спасибо. Это то что нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Седой 0 30 июня, 2009 Опубликовано 30 июня, 2009 · Жалоба Спасибо. Это то что нужно. Да, если серьезно заинтересованы, то могу выложить продолжение проекта http://projects.caxapa.ru/?ID=45 Он сильно видоизменился. 1. Появился CoInstaller драйвера. 2. Программа загрузки интегрирована в CoInstaller и теперь можно обновлять firmware из Диспетчера устройств. Вам всего лишь нужно будет реализовать собственно загрузчик в устройстве в соответствии со спецификацией USB класса DFU1.1 3. Появилось API c низко и высокоуровневыми функциями DFU, а также также для работы с DFU файлами. И если не устраивает встроенная программа загрузки, то можете написать свою, а встроенную отключить. API интегрировано в CoInstaller dll драйвера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Паф 0 30 июня, 2009 Опубликовано 30 июня, 2009 · Жалоба Мы уже реализовали наш подход. Тестируем на пилотных образцах. Но в дальнейшем планируем сделать поддержку DFU. Ваш проект несомненно нам интересен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться