Цитата(Sh@dow @ Sep 20 2010, 20:50)

>>А CyAPI штука очень удобная и весьма надежная
Что меня смутило так это то что коннект к девайсу происходит в конструкторе.
USBDevice* dev = new USBDEvice()
делать в конструкторе такие вещи нельзя.Конструктор возвращать значения не может поэтому если коннект обломится то как программа это узнает?
Это не совсем так. (Прошу прощения, я проиллюстрирую свои слова кодом, может немножко обширным.)
Вот фрагмент моей функции инициализации. Параметр "hWnd" можно не использовать (я использую только для того, чтобы смотреть присоединение/отсоединение девайсов, по большому счету мне это нафик не нужно :-) Сделал просто так, для общего развития).
Код
pUSBDevice = new CCyUSBDevice(hWnd); // Create an instance of CCyUSBDevice
if(pUSBDevice == NULL) {
ERR_MSG(" Can't create USBDevice ");
return SLE901ERR_USB_DEVICE_NOT_EXIST;
}
else {
Scusb_VID = scusb_VID;
Scusb_PID = scusb_PID;
scan_devices();
{
if(pEp1OutEndpt && pEp1InEndpt) {
sprintf_s(s,"%s: EP1 present, EP1 OUT = 0x%02X EP1 IN = 0x%02X\r\n",module,
SCUSB_ENDPOINT_EP1_OUT, SCUSB_ENDPOINT_EP1_IN);
}
else {
sprintf_s(s,"%s: EP1 not present\r\n",module);
}
UtilsR1_force_protocol_str(s);
}
if(!pUSBDevice->IsOpen()) { return SLE901ERR_USB_DEVICE_NOT_OPENED; }
if(!pControlOutEndpt) { return SLE901ERR_CONTROL_OUT_ENDPOINT_NOT_EXIST; }
if(!pControlInEndpt) { return SLE901ERR_CONTROL_IN_ENDPOINT_NOT_EXIST; }
... и т.д. по всем моим ендпойнтам
Здесь после создания объекта устройства USB вызывается функция "scan_devices();", которая как раз и опрашивает все девайсы, пока не найдет мой. Вот ее код:
Код
void scan_devices()
{
if(pUSBDevice == NULL) {
ERR_MSG("scan_devices: USBDevice not exist");
return; // We don't have USB device object!
}
int devices = pUSBDevice->DeviceCount();
int vID = 0, pID = 0;
int d = 0;
while (d < devices ) {
pUSBDevice->Open(d); // Open automatically calls Close( ) if necessary
vID = pUSBDevice->VendorID;
pID = pUSBDevice->ProductID;
if ((vID == Scusb_VID) && (pID == Scusb_PID)) break;
d++;
}
if ((vID == Scusb_VID) && (pID == Scusb_PID)) {
int epts = pUSBDevice->EndPointCount();
CCyUSBEndPoint *endpt;
for (int i = 1; i < epts; i++) { // Skip endpoint 0, which we know is the Control Endpoint
endpt = pUSBDevice->EndPoints[i];
if (endpt->Attributes == 2) { // Bulk
switch(endpt->Address) {
case SCUSB_ENDPOINT_CONTROL_OUT:
pControlOutEndpt = endpt;
break;
case SCUSB_ENDPOINT_CONTROL_IN:
pControlInEndpt = endpt;
break;
case SCUSB_ENDPOINT_US_DATA_IN:
pUsDataInEndpt = endpt;
break;
case SCUSB_ENDPOINT_CFM_DATA_IN:
pCfmDataInEndpt = endpt;
break;
case SCUSB_ENDPOINT_EP1_OUT:
pEp1OutEndpt = endpt;
break;
case SCUSB_ENDPOINT_EP1_IN:
pEp1InEndpt = endpt;
break;
}
}
}
}
else {
pUSBDevice->Close();
}
}
Здесь Scusb_VID/Scusb_PID - коды моего устройства, а SCUSB_ENDPOINT_xxx - адреса моих эндпойнтов. Таким образом я точно знаю, что мое устройство присоединено (или нет в случае ошибки).
Цитата(Sh@dow @ Sep 20 2010, 20:50)

>>Что касается закрытия драйвера
Собственно закрыть драйвер не проблема. В случае CyAPI это delete USBDevice,деструктор класса сам вызывает функцию Close.
В случае управления через DeviceIoControl это CloseHandle();
Там все гораздо хуже. К примеру, сначала я попробовал закрывать устройство в DllMain по приходу DLL_PROCESS_DETACH. Не закрывается ни фига. Тогда я вынужден был в основной программе по WM_DESTROY вызывать экспортированную функцию "Close". В общем-то не смертельно, но неудобно, если отлаживаешь программу. Ты ее остановил - а она, соответственно, не вызвала "Close" и привет, программа и не жива, и не мертва :-)
Цитата(Sh@dow @ Sep 20 2010, 20:50)

jur, Вы загружали прошивку в контроллер? Дело в том что после загрузки и сброса контроллер в системе идентифицируется по новым PID/VID и поэтому должен быть переинициализирован. Мне надо программно определить проинициализировался ли драйвер или нет если нет то программа ждет когда проинициализируется и дальше работает с новым устройством.
Тут у меня опыта нет. Хотелось бы, конечно, разобраться с этим вопросом, но все как-то руки не доходят... Я пробовал в "CyConsole.exe" рестартовать устройство, или его ресетить, но у меня не получилось, чтобы оно снова ренумерировалось и нормально работало. Плюнул и записал фирмваре в EEPROM-ку :-) Коллега, если получится - пожалуйста дайте знать! (Давай на "ты"?) Думаю, что многим участникам этот вопрос будет интересным.
Или, может быть, кто-то из участников обсуждения освоил этот прием? Поделитесь опытом, пожалуйста!