Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
2 / 2 / 0
Регистрация: 20.05.2021
Сообщений: 150

Работа с COM портом после ресета удаленного устройства

16.09.2022, 09:24. Показов 2393. Ответов 36

Студворк — интернет-сервис помощи студентам
Работаю из приложения с удаленным устройством через UART интерфейс АТ-командами.
Открываю порт и запускаю в приложении поток чтения COM порта.
Иногда устройству надо подавать команду программного ресета.
Но если я после таймаута пытаюсь подать АТ-команду или переоткрыть COM порт, нарываюсь на исключение:
System.IO.IOException: "Требуемый ресурс занят".

Да, я не останавливаю поток чтения: я не анализирую подаваемые команды - это функция устройства. И ни о каком ресете удаленного устройства приложение не знает.
Но если я в подобной манере работаю через терминальную программу, никаких исключений не происходит!
Она продолжает работать после истечения таймаута как будто ресета устройства и не было.
Как это организовать в моем приложении?
Я что: должен все время мониторить ресурс: открыт порт или нет и автоматически его переоткрывать когда он будет доступен?
Что-то мне не очень это нравится.
Сомневаюсь, что терминальная программа так устроена.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.09.2022, 09:24
Ответы с готовыми решениями:

После ресета не работает Wi-Fi
Всем доброго времени суток У меня случилась беда. После сброса кнопкой WPS/RESET(удерживал 10 сек.) не работает Wi-Fi. Из индикаторов...

Пропад звук в Debian8 после ресета
Каждый раз, как только вырубается свет, перезагружается или выключается\включается комп, пропадает звук. В alsamixer заглушки сняты, звука...

Странное поведение 8 меги после ресета
Здравствуйте. Вкуриваю обработчик энкодера, вроде что-то получилось, хотя и не совсем :) Но, проблема вылезла откуда не ждали: Ютуб ...

36
2 / 2 / 0
Регистрация: 20.05.2021
Сообщений: 150
20.09.2022, 12:56  [ТС]
Студворк — интернет-сервис помощи студентам
Но, если я просто открываю порт, подаю АТ, получая ОК и закрываю-открываю, все открывается.
Если я после ОК подаю еще команду ресета и жду 40 сек, а потом закрыть-открыть порт, то не открывается.
Хотя на сторонней терминальной программе уже через 35 секунд продолжает общаться.
Значит, проблемы у меня в приложении.

Добавлено через 2 минуты
Цитата Сообщение от Rius Посмотреть сообщение
Пробовали после аварийного закрытия создавать новый порт и уже его открывать?
Нет. Создавать новый порт не пробовал.
Попробовать можно, но не понимая причин нештатного поведения стремно: у меня эта процедура должна работать в многократно. Можно нарваться на всякие виндовые фокусы с ресурсами.
Самое непонятное: причина такого поведения.
0
Эксперт .NET
 Аватар для Rius
13375 / 7830 / 1695
Регистрация: 25.05.2015
Сообщений: 23,833
Записей в блоге: 14
20.09.2022, 13:02
Цитата Сообщение от АнаП Посмотреть сообщение
Попробовать можно, но не понимая причин нештатного поведения стремно: у меня эта процедура должна работать в многократно. Можно нарваться на всякие виндовые фокусы с ресурсами.
Самое непонятное: причина такого поведения.
Пробуйте.

Штатное поведение оно в WinAPI. Берите и пользуйтесь:
А SerialPort это надстройка над ним. И вовсе не безгрешная: If you *must* use .NET System.IO.Ports.SerialPort

И почему вы думаете, что в стороннем терминале не предусмотрена обработка нештатных ситуаций?
0
2 / 2 / 0
Регистрация: 20.05.2021
Сообщений: 150
20.09.2022, 14:33  [ТС]
Цитата Сообщение от Rius Посмотреть сообщение
И почему вы думаете, что в стороннем терминале не предусмотрена обработка нештатных ситуаций
Я вовсе так не думаю. Я просто не могу эту ситуацию сформулировать и указать метод ее преодоления.
Ведь даже, если я обхожу исключение, работоспособность порта я восстановить никак не могу.
Но разве что пересоздать этот объект заново.
Но это уже само по себе - нештатная ситуация.
0
2290 / 1606 / 400
Регистрация: 26.06.2017
Сообщений: 4,772
Записей в блоге: 1
20.09.2022, 15:07
Цитата Сообщение от АнаП Посмотреть сообщение
Но это уже само по себе - нештатная ситуация.
Ну нет! На примере USB преобразователей "чего-то там to-USB" наблюдается следующая ситуация: первое "втыкание" - система ставит драйверочки и в списке СОМ и, Внимание, USB устройств появляется новое оборудование; теперь мы можем работать по некоему СОМ-порту; выдернули USB и воткнули в другой разъём, при этом система может сознать новый порт, номер другой. И как Вы планируете после полного разрыва соединения работать с СОМ-портом по старым данным?
0
Эксперт .NET
 Аватар для Rius
13375 / 7830 / 1695
Регистрация: 25.05.2015
Сообщений: 23,833
Записей в блоге: 14
20.09.2022, 15:09
Цитата Сообщение от АнаП Посмотреть сообщение
Но это уже само по себе - нештатная ситуация.
Почему это? Соответствующие ситуации меры.
Эта обёртка не рассчитана на то, что порт физически удалят из системы.
Что при этом происходит, можно посмотреть в исходниках .Net.

По самой ситуации спрашивали на форумах Microsoft: Virtual Serial Port from USB device disconnect reconnect then can't open port.

Цитата Сообщение от Uswer Посмотреть сообщение
при этом система может сознать новый порт, номер другой. И как Вы планируете после полного разрыва соединения работать с СОМ-портом по старым данным?
Автопоиск устройства по всем доступным портам.
0
2290 / 1606 / 400
Регистрация: 26.06.2017
Сообщений: 4,772
Записей в блоге: 1
20.09.2022, 15:33
Цитата Сообщение от Rius Посмотреть сообщение
Автопоиск устройства по всем доступным портам.
Но это же потребует как минимум переконфигурирование СОМ-порта, куда легче создать новый и работать через него.
0
Эксперт .NET
 Аватар для Rius
13375 / 7830 / 1695
Регистрация: 25.05.2015
Сообщений: 23,833
Записей в блоге: 14
20.09.2022, 15:56
Вот демокод моего метода. Наспех, но работает.
Вложения
Тип файла: zip SerialPortReconnectDemo.zip (18.1 Кб, 12 просмотров)
0
2 / 2 / 0
Регистрация: 20.05.2021
Сообщений: 150
21.09.2022, 08:02  [ТС]
Коллеги, к сожалению, пересоздание порта после ресета не решает проблемы: та же ругалка при его открытии "Требуемый ресурс занят".
Очень печально. И непонятно, что ему не хватает.
Пробовал передергивать питание устройства после ресета и тогда пересоздать порт.
Хрен тебе! Все равно требуемый ресурс занят, и порт не открывается, блин!
Но порт появляется в диспетчере устройств с тем же именем.
0
Эксперт .NET
 Аватар для Rius
13375 / 7830 / 1695
Регистрация: 25.05.2015
Сообщений: 23,833
Записей в блоге: 14
21.09.2022, 08:04
Выше код работает у вас или нет? Или вы что-то по своему написали?
0
2 / 2 / 0
Регистрация: 20.05.2021
Сообщений: 150
21.09.2022, 08:20  [ТС]
Rius, пока не пробовал.
Есть еще решение со stackoverflow помещением процедур COM порта в отдельный процесс, чтобы хандлеры порта принадлежали ему, и каждый раз пересоздавать этот процесс.
Будем посмотреть...
0
2 / 2 / 0
Регистрация: 20.05.2021
Сообщений: 150
21.09.2022, 15:17  [ТС]
Попробовал Ваш пример с кодом создания и работы порта в отдельной задаче.
С тем же неуспехом :-(
Картина никак не меняется: в задаче после ресета порт сначала исчезает потом вроде как проявляется по фидбэкам от USB.
Но несмотря на переподключение, порт реально не открыт и вызывает на каждом следующем проходе по записи в порт исключение.
В обработчике исключения он видит, что соединение установлено по фидбэкам, и шурует дальше в цикле.
Но поскольку исключения перехватываются, то падения не происходит, просто обмена нет: порт реально закрыт.
Вот этот чуток модифицированный цикл обмена из Вашего примера.
Я просто вставил секундную задержку внутри цикла и по счетчику секунд отправляю нужные команды в порт.
Вначале подаются команды АТ чтобы убедиться в наличии ответа.
Потом команда ресета с паузой в 40 секунд перед следующей командой АТ, которая подается дважды на всякий случай. Но все они остаются без ответа.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
        private void Reader(CancellationToken token, string portname)
        {
            int passNum = 0;
            byte[] request = { 0 };
            string response = "";
 
            var port = new PortUsbUart(portname, 115200, Parity.Odd, 8, StopBits.One);
            try
            {
                port.Open();
                var buffer = new byte[20];
 
                while (!token.IsCancellationRequested)
                {
                    switch(passNum++)
                    {
                        // exchange by seconds
                        case 5:
                            request = Encoding.ASCII.GetBytes("AT\r");
                            this.progress.Report("send AT");
                            break;
                        case 10: // reset
                            request = Encoding.ASCII.GetBytes("AT+M2M=1\r");
                            this.progress.Report("send AT+M2M=1");
                            break;
                        case 40:
                            request = Encoding.ASCII.GetBytes("AT\r");
                            this.progress.Report("send AT");
                            break;
                        case 45:
                            request = Encoding.ASCII.GetBytes("AT\r");
                            this.progress.Report("send AT");
                            break;
                        default:
                            request = Encoding.ASCII.GetBytes("\r");
                            break;
                    }
 
                    try
                    {
                        port.Write(request, 0, request.Length);
                        if (port.BytesToRead > 0)
                            response = port.ReadLine();
                    }
                    catch (Exception e)
                    {
                        if (this.eventDisconnected.IsSet)
                        {
                            this.eventConnected.Wait(token);
 
                            port.Dispose();
                            port = new PortUsbUart(portname, 115200, Parity.Odd, 8, StopBits.One);
                            port.Open();
                        }
                    }
 
                    if (response.Length > 0)
                    {
                        this.progress.Report(response);
                        response = "";
                    }
 
                    Thread.Sleep(1000);
                }
            }
            catch
            {
            }
            finally
            {
                if (port.IsOpen)
                {
                    port.Close();
                }
            }
        }
Перезапуск задачи на выходя из приложения тоже ничего не меняет: поведение сохраняется.
Какая хрень у него захвачена - хз.
0
Эксперт .NET
 Аватар для Rius
13375 / 7830 / 1695
Регистрация: 25.05.2015
Сообщений: 23,833
Записей в блоге: 14
21.09.2022, 15:51
Вот так лучше.
C#
1
2
3
4
if (this.eventDisconnected.IsSet)
{
    port.Dispose();
    this.eventConnected.Wait(token);
А чип usb-uart чей? Какой VID&PID показывается в диспетчере устройств или в usbdeview для вашего порта, пока он подключён?
0
2 / 2 / 0
Регистрация: 20.05.2021
Сообщений: 150
21.09.2022, 16:17  [ТС]
Цитата Сообщение от Rius Посмотреть сообщение
А чип usb-uart чей? Какой VID&PID показывается в диспетчере устройств или в usbdeview для вашего порта, пока он подключён?
На плате устройства сразу после USB разъема стоит драйвер TPD2E2U06-Q1.
В диспетчере устройства порт подключения значится как модем. Ему присвоен COM порт.
USB\VID_1BC7&PID_1201&REV_0318&MI_05
USB\VID_1BC7&PID_1201&MI_05
1
Эксперт .NET
 Аватар для Rius
13375 / 7830 / 1695
Регистрация: 25.05.2015
Сообщений: 23,833
Записей в блоге: 14
21.09.2022, 16:32
TPD2E2U06-Q1 - защита от ESD (искр статического электричества).
Модем Telit.
Попробуйте мой код не с командой перезагрузки, а с физическим отключением кабеля.
0
2 / 2 / 0
Регистрация: 20.05.2021
Сообщений: 150
22.09.2022, 13:18  [ТС]
Попробовал: ничего не меняется.
После восстановления соединения связи нет.
Тоже самое когда я просто передергиваю питание модема.
Только полный рестарт приложения возобновляет связь.
Где-то не так глубоко "спрятался" некий ресурс, который нужен порту и остается недоступен.
Все манипуляции со сборщиком мусора не освобождают его.
Узнать бы как зовут...

Добавлено через 5 часов 30 минут
Rius
Сделал из Вашего примерчика диалоговую программку (не автомат, а передача из поля ввода).
Запустил в двух экземплярах и нормально пообщался через виртуальный мостик COM-COM.
Выключение обмена на одном из окон не ведет к падению соединения и при восстановлении я получаю все что недополучил за время паузы. Перезапуск одного из окошек тоже нормально восстанавливает обмен!
Т.е. аппаратура UARTа работает корректно в таких ситуациях.
А аппаратура USB-СOM дурит!
Кривая программная поддержка.
И видимо пока не лечится.
0
Эксперт .NET
 Аватар для Rius
13375 / 7830 / 1695
Регистрация: 25.05.2015
Сообщений: 23,833
Записей в блоге: 14
22.09.2022, 13:20
Попробуйте с каким-нибудь другим адаптером usb-uart.
Есть подозрение, что драйвер этого модема не умеет корректно отключаться при физическом удалении открытого порта.

Ещё можно посмотреть логи usb и uart через сниффер. Как происходит переподключение в терминале.
0
2 / 2 / 0
Регистрация: 20.05.2021
Сообщений: 150
23.09.2022, 07:38  [ТС]
Не могу согласиться: работаю через стороннюю терминальную программу и все ОК. Ничего не падает, после ресета продолжает работать. Есть еще одна терминальная программа, похоже написанная на Java. Там тоже нет таких проблем.
Подозреваю: проблема в дотнетовских библиотеках.
На компе есть старенький Borland C++Builder. У него в примерах есть терминальный чат.
Попробую его приспособить и посмотреть поведение.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.09.2022, 07:38

Gigabyte ga-965p после ресета пропадает изображение
Конфиг: БП 350w, проц е7200, карта gts450, 1 терр хард, ОЗУ Ноу нэйм 2гб. Всё работало хорошо, без перегревов (следил) и нареканий. Стало...

При перезагрузке комп виснет на этапе завершения работы. После ресета сбрасываются настройки БИОС
Попала в руки старенькая система, решил тестю домашний компьютер оформить.. Все снес, установка XP прошла нормально, но при перезагрузке...

Bluetooth получение удаленного устройства
Вдруг перестали запускаться приложения,по логам ссылается на final BluetoothDevice device = Blut.getRemoteDevice(MyAdress) , все что...

Проблема получения звука с удалённого устройства
3-G модем, установленный на роутере с OpenWrt, пишет звук в виртуальный com порт. Удалённое приложение получает звуковые данные по TCP/IP...

Работа с Com-портом
Приветствую, ребята! Подскажите пожалуйста с такой задачкой. Требуется отправлять команды из стека на устройство, подключенное по...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
сукцессия 30. Фосфорный и азотный замки по "честному" закону лимитирования Либиха
anaschu 16.07.2026
Основные достижения за последние дни 1. Механизм отложенного высвобождения фосфора Добавлен специальный пул для медленного разложения меланизированных гиф ЕСМ Реализована разная скорость. . .
Запрет пометки на удаление и отмены проведения
Maks 16.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "ПутевойЛист" разработанного в КА2. Задача: запретить помечать на удаление и отменять проведения путевого листа при условии, если он сдан. . .
Как надо было делать правильно - вообще не слушать ИИ, его дело - текст.
Hrethgir 15.07.2026
А вообще надо было делать не так, чтобы не исправлять ошибку https:/ / www. cyberforum. ru/ blogs/ 223907/ 10996. html , правильно было : удалил кнопку, а потом добавил её. Всё это стресс конечно. Почему?. . .
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот. Ларри Уингет
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru