Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Нe удается открыть вирт. ком-порт, работающий через usbser.sys


Страницы:   1 2 3

Kolan ©   (2010-04-09 10:18:00) 

Здравствуйте!

Есть железка, которая представляется как USB-функция и реализует ACM совместимый USB CDC профиль (это я написал под диктовку нашего «железячника»).

Для подключение к Винде мы использовали драйвер usbser.sys из Виндоус Икс-Пи (второй сервис пак).

Проблема в том, что при определенных действиях (гарантировано воспроизвести не удаётся, но это происходит при физическом отключении железки от порта) виртуальный ком-порт определяется в системе (виден в списке оборудование), а работать с ним не удается, функция открытия файла завершается с ошибкой «Не удается найти указанный файл.»

Причем дело врядли в конкретной программе, так как доступ к порту в этом случае не может получить ни одна программа вообще (пробовали ZOC и пр.).

Помогает только перетыкание USB в другой порт, при этом появляется ком-порт с другим номером и открытие файла проходит успешно. Если после этого воткнуть USB обратно (туда, где только что не работало), открытие снова работает.

Вопросы: В чем может быть дело? Как это исправить?


Kolan   (2010-04-16 12:21:00) [1]

Скорее всего не буду докапываться, потому что, вроде, работает нормально.

Благодарю участников обсуждения за ответы.


Вариант   (2010-04-16 11:59:00) [2]


> Kolan ©   (16.04.10 11:16) [45]


> Я не понял как подписываться на нотификацию и что я буду
> получать в случае с портом.
>

через RegisterDeviceNotification, сам с этим не работал, описание и пример http://msdn.microsoft.com/en-us/library/aa363431(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa363432(v=VS.85).aspx, ну или в гугле наверняка можно найти

А вот что будешь получать - это вопрос, те же WM_DEVICE_CHANGE будет приходить, но будет ли там DBT_DEVICEARRIVAL я не знаю. Если попробуешь - узнаешь - сообщи сюда, мне тоде интересно. Но у меня такого как DBT_DEVNODES_CHANGED не приходит, а потому проверить сам не могу.


Kolan   (2010-04-16 11:16:00) [3]

Я не понял как подписываться на нотификацию и что я буду получать в случае с портом.

Я тоже не сталкивался раньше с такими странностями, так как раньше DBT_DEVICEARRIVAL с DBT_DEVTYP_PORT всегда приходило.


Вариант   (2010-04-16 10:29:00) [4]

Я бы все же из интереса даже попробовал подписаться на нотификацию, просто проверить прийдет инфо или нет. Ибо про DBT_DEVNODES_CHANGED все же написано, что имеет смысл.  
И для меня это первый опыт так сказать подобной проблемы. У нас работали  с нашими программами для RS232 через USB. Но о такой проблеме мы не задумывались как-то. Не удаляют у нас устройств на ходу....


Kolan   (2010-04-16 10:27:00) [5]

Вроде получилось. Сделал так, что при отключении устройства порт закрывается. Тестирую, пока работает.


Kolan   (2010-04-16 10:09:00) [6]

Вариант 1 - Вставил устройство
Пришли сообщения -> Добавлена последовательность COM портов.
Я открыл порт. Закрыл порт. Удалил устройство из USB.
Пришли сообщения -> Удалена последовательность COM портов.


Тут еще вот какое дело. Это драйвер не шлет таких сообщение, гад. Он шлет только DBT_DEVNODES_CHANGED.

http://www.delphimaster.ru/cgi-bin/forum.pl?id=1268895548&n=0


Вариант   (2010-04-16 09:48:00) [7]

Попробовал поиграться с USB -> COM - действительно проблема существует с удалением и повторным открытием. Более того есть и такой неприятный момент, что USB устройство может посадить свой COM на уже имеющийся виртуальный порт.
Теперь о проблеме повторного открытия порта. Если USB устройство у меня удалялось в момент, когда порт не использовался, не был открыт какой-либо программой ( или был открыт и корректно закрыт), то проблемы в дальнейшем собственно не возникало. Удаление и последуещеее добавление USB девайса не влияло на повторное открытие COM порта. Если же удаление происходило при не закрытом HANDLE порта то у меня затем на команде CloseHandle происходило зависание на более чем 30 секунд или второй вариант - вставлял устройство пока программа висела, и в этом случае CloseHandle завершал работу раньше.  И после этого могла возникнуть описанная автором топика проблемная ситуация(но не всегда).
И так ->
При мониторинге добавления или удаления устройств -  обрабатывал сообщение WM_DEVICECHANGE - я видел следующее:

Вариант 1 - Вставил устройство
Пришли сообщения -> Добавлена последовательность COM портов.
Я открыл порт. Закрыл порт. Удалил устройство из USB.
Пришли сообщения -> Удалена последовательность COM портов.

Это нормальный режим работы, после него при включении USB устройства порты нормально открываются.

Вариант 2   - Вставил устройство

Пришли сообщения -> Добавлена последовательность COM портов(на самом деле несколько сообщений, по одному на каждый порт).
Я открыл порт.
Удалил устройство из USB.
Попытался закрыть порт.  Я не дождался завершения работы CloseHandle - прервал процесс  - в этом случае при повторном ключении USB устройства порты не открывались. Правда для устранения ошибки достаточно было удалить USB устройство и снова его вставить в то же гнездо.

Вариант 3   - Вставил устройство
Пришли сообщения -> Добавлена последовательность COM портов .
Я открыл порт.
Удалил устройство из USB.
Попытался закрыть порт. Дождался завершения работы CloseHandle (более 30 сек). в этом случае при повторном ключении USB устройства порты нормально открылись. (прим Сообщений об удалении устройств не получил)

Вариант 4   - Вставил устройство
Пришли сообщения -> Добавлена последовательность COM портов .
Я открыл порт.
Удалил устройство из USB.
Попытался закрыть порт. Не дожидаясь конца работы CLoseHandle снова вставил в USB устройство. Дождался завершения CloseHandle. ПОлучил
сообщения -> Добавлена последовательность COM портов (в дистпечере устройств порты появились).
Пришли сообщения -> Удалена последовательность COM портов.
(но в дистпечере устройств порты остались).  В этом случае повторно открыть порт не могу.

Вариант 5 (то же что и 4 но концовка другая, счастливая)   - Вставил устройство
Пришли сообщения -> Добавлена последовательность COM портов .
Я открыл порт.
Удалил устройство из USB.
Попытался закрыть порт. Не дожидаясь конца работы CLoseHandle снова вставил в USB устройство. Дождался завершения CloseHandle. ПОлучил
сообщения -> Добавлена последовательность COM портов (в дистпечере устройств порты появились). После чего повторно смог открыть порт.

Резюме - Не надо удалять устройство при работающих с ним программах. Если это случилось - надо все равно закрывать HANDLE порта (пусть долго но надо). Надо анализировать возвращаемые результаты всех функций и причины ошибок заносить хотя бы в лог - это помогает. Если возникает описанная автором ошибка порта, то в интерактивной програме - надо просто попросить пользователя переподключить устройство.


Kolan   (2010-04-15 16:29:00) [8]


> Так вот, не получится ибо он уже занят.
>

Да, и скажут, что Отказано в доступе, а тут вообще говорят, что его нет. То есть в системе он есть, а CreateFile говорит, что нет.


GanibalLector   (2010-04-15 16:22:00) [9]


> С открытием все в порядке. Ничего с ним не в порядке.CreateFile
> возвращает INVALID_HANDLE_VALUE. Смысл обсуждать что-то
> еще?


Так сам же говорил, что проблема появляется только при повторном запуске программы, когда устройство вытащили из USB.

Код, который ты привел абсолютно нормальный. И я так открываю. Я считаю, что проблема возникает при закрытии порта.

Вот для примера. У тебя есть обычные порты (СОМ1,СОМ2)? Открой один из них в гипертерминале, а потом сам попробуй открыть программно. Так вот, не получится ибо он уже занят.


Вариант   (2010-04-15 16:03:00) [10]


> Kolan ©   (15.04.10 15:49) [37]


> Тогда логичнее было бы спросить вначале.

Нет, логичней было указать версию, ибо поставить галочку надо было при создании темы. Но не суть
> Ведь в [0] это написано:

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


Kolan   (2010-04-15 15:49:00) [11]


> При том, что ты не указал версию и что прописано в твоей
> версии Windows.pas мне неизвестно.

Тогда логичнее было бы спросить вначале.


> ПРоверь так и прочти что будет написано в сообщении


Ведь в [0] это написано:
„
Проблема в том, что при определенных действиях (гарантировано воспроизвести не удаётся, но это происходит при физическом отключении железки от порта) виртуальный ком-порт определяется в системе (виден в списке оборудование), а работать с ним не удается, функция открытия файла завершается с ошибкой «Не удается найти указанный файл.»
“


Вариант   (2010-04-15 15:37:00) [12]


> Kolan ©   (15.04.10 15:00) [34]
> Причем тут Д6? Я использую Д2009.

При том, что ты не указал версию и что прописано в твоей версии Windows.pas мне неизвестно.


> Kolan ©   (15.04.10 15:02) [35]



> Разницы нет.


ПРоверь так и прочти что будет написано в сообщении

if FPortHandle = INVALID_HANDLE_VALUE then
begin
raise Exception.Create(SysErrorMessage(GetLastError)));
end;


Kolan   (2010-04-15 15:02:00) [13]

Вот из nrComma код

function OpenPort(const n:integer):THandle;
begin
 Result:=CreateFile(PChar('\\?\'+ComPortToStr(n)),(GENERIC_READ + GENERIC_WRITE),0,nil,
   OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
end;


Разницы нет.


Kolan   (2010-04-15 15:00:00) [14]

Причем тут Д6? Я использую Д2009.

С открытием все в порядке. Ничего с ним не в порядке.

CreateFile возвращает INVALID_HANDLE_VALUE. Смысл обсуждать что-то еще?


Вариант   (2010-04-15 13:33:00) [15]


> GanibalLector ©   (15.04.10 13:05) [32]
> Kolan ©   (15.04.10 09:42) [29]
>
> С открытием все в порядке.

Возможно - правда в дельфи 6 это просто не компилируется. Но даже если и прошло , то я бы сделал  тут хотя бы -
if FPortHandle = INVALID_HANDLE_VALUE then
begin
 raise Exception.Create(SysErrorMessage(GetLastError)));
end;
что бы точно знать причину ошибки.... И так же и в других проблемных местах.


GanibalLector   (2010-04-15 13:05:00) [16]

Kolan ©   (15.04.10 09:42) [29]

С открытием все в порядке.
Что в  SetUserComTimeOuts ?

При запуске программы после перегрузки как ведет себя CloseHandle ? Результат проверяешь ?


Anatoly Podgoretsky   (2010-04-15 12:25:00) [17]

CreateFileW


Вариант   (2010-04-15 12:03:00) [18]


> Kolan ©   (15.04.10 09:42) [29]


CreateFile( PWideChar

В Delphi 6 в Windows.pas


> function CreateFile; external kernel32 name 'CreateFileA';


В этом случе  PWideChar не уместен.


Kolan   (2010-04-15 09:42:00) [19]

Вот код из писанного мной компонента:

function TAnisochronousComm.Open: Boolean;
begin
 Result := False;
 if FPortHandle <> INVALID_HANDLE_VALUE then
   Close;
 {'\\.\' prefix is nescessary for ports above 9.}
 FPortHandle := CreateFile(PWideChar('\\.\'+FPortName), GENERIC_READ or GENERIC_WRITE,
   0, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
 if FPortHandle = INVALID_HANDLE_VALUE then
   Exit;

 ZeroMemory(@FOverlappedRead, SizeOf(@FOverlappedRead));
 ZeroMemory(@FOverlappedWrite, SizeOf(@FOverlappedWrite));
 FOverlappedRead.hEvent := CreateEvent(nil, False, False, nil);
 FOverlappedWrite.hEvent := CreateEvent(nil, False, False, nil);

 SetUserComState;
 SetUserComTimeOuts;
 Purge;
 Result := True;
 SetEvent(FComOpenEvent);
end;


Германн   (2010-04-11 03:18:00) [20]

Ну и ещё.

> Kolan ©   (10.04.10 12:09) [19]
>
>
> > Ты же вроде что-то пробовал с tpapro?
>
> На него забили, он странно подвисал при работе с зед-модемом.
>  Купили nrComm.
>
>

Если купили, то ...
Сам догадаешься, что нужно сделать?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо