QSerialDevice - Библиотека для работы с COM-портами |
Здравствуйте, гость ( Вход | Регистрация )
QSerialDevice - Библиотека для работы с COM-портами |
bukap |
2.8.2010, 12:11
Сообщение
#111
|
Новичок Группа: Новичок Сообщений: 2 Регистрация: 1.8.2010 Пользователь №: 1923 Спасибо сказали: 0 раз(а) Репутация: 0 |
Добрый день!
Регулярно работаю с устройствами, подключаемыми с помощью последовательного интерфейса к компьютеру. Интерфейсы разрабатываю на MFC, для связи с устройствами использую Windows API, ActiveX Microsoft Communication Control version 6.0. Возникла необходимость разработать новый сложный интерфейс. Перед принятием решения о переходе на Qt, был проведен анализ и испытание уже готовых библиотек работы с последовательными портами. Библиотеки: QextSerialPort v.1.2 beta QSerialSevice v 0.2.0 Среда разработки: Qt Creator 2.0 Qt SDK 4.6.3 Платформа: Microsoft Windows XP [Версия 5.1.2600] Service Pack 3 Последовательные порты: 1. Стандартный последовательный порт установленный на материнской плате 2. Prolific USB-to-Serial Comm Port 3. USB-SERIAL CH340 4. CP210x USB to UART Bridge Controller 5. PIC18F2550/4550 CDC RS-232 Emulation Microchip Technology Inc QextSerialPort Библиотека не поддерживает последовательные порты с нумерацией выше COM9. Устраняется добавлением в путь к открываемому порту указания на устройство “\\\\.\\” Для этого вносятся изменения в файл win_qextserialport.cpp. CODE bool Win_QextSerialPort::open(OpenMode mode) { unsigned long confSize = sizeof(COMMCONFIG); Win_CommConfig.dwSize = confSize; DWORD dwFlagsAndAttributes = 0; if (queryMode() == QextSerialBase::EventDriven) dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED; LOCK_MUTEX(); if (mode == QIODevice::NotOpen) return isOpen(); if (!isOpen()) { /*open the port*/ Win_Handle=CreateFileA(("\\\\.\\" + port).toAscii(), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL); … } QSerialSevice Библиотека возвращает не верный статус линии. Устраняется исправлением типа данных с bool на ulong. Для этого вносятся изменения в файл abstractserial.cpp. CODE ulong AbstractSerial::lineStatus() { Q_D(AbstractSerial); if (isOpen()) { ulong ret = d->serialEngine->lineStatus(); if (!ret) emitStatusString(ELineStatus); return ret; } emitStatusString(EDeviceIsNotOpen); return false; } Так же библиотека не смогла открыть последовательный порт PIC18F2550/4550 CDC RS-232 Emulation Microchip Technology Inc, при вызове функции открытия порта возникает ошибка из-за неудачного снятия состояния BREAK функцией ClearCommBreak. Устраняется комментированием строки ret = false;. После комментирования функциональность класса не изменяется, так как наличие вызова данной функции не обосновано. CODE bool NativeSerialEnginePrivate::nativeReset() { … // cброс регистров порта. (reset device registers) if (::ClearCommBreak(hd) == 0) { #if defined (NATIVESERIALENGINE_WIN_DEBUG) qDebug("Windows: NativeSerialEnginePrivate::nativeReset() \n" " -> function: ::ClearCommBreak(hd) returned: 0. Error! \n"); #endif // ret = false; … } |
|
|
kuzulis |
2.8.2010, 13:37
Сообщение
#112
|
Активный участник Группа: Участник Сообщений: 393 Регистрация: 29.6.2009 Пользователь №: 862 Спасибо сказали: 36 раз(а) Репутация: 7 |
2 bukap,
Цитата QSerialSevice Библиотека возвращает не верный статус линии. Устраняется исправлением типа данных с bool на ulong. Для этого вносятся изменения в файл abstractserial.cpp. Спс, мой косяк, недоглядел... Сегодня постараюсь исправить. Цитата Так же библиотека не смогла открыть последовательный порт PIC18F2550/4550 CDC RS-232 Emulation Microchip Technology Inc, при вызове функции открытия порта возникает ошибка из-за неудачного снятия состояния BREAK функцией ClearCommBreak. Устраняется комментированием строки ret = false;. После комментирования функциональность класса не изменяется, так как наличие вызова данной функции не обосновано. Берите версию из Git. Теперь там при открытии не используется метод nativeReset(), т.е. его вызов закоментирован. Цитата 1. Стандартный последовательный порт установленный на материнской плате 2. Prolific USB-to-Serial Comm Port 3. USB-SERIAL CH340 4. CP210x USB to UART Bridge Controller 5. PIC18F2550/4550 CDC RS-232 Emulation Microchip Technology Inc Со всеми ли этими устройствами корректно работает класс SerialDeviceWatcher и SerialDeviceInfo ? Сообщение отредактировал kuzulis - 2.8.2010, 13:41 |
|
|
bukap |
2.8.2010, 18:36
Сообщение
#113
|
Новичок Группа: Новичок Сообщений: 2 Регистрация: 1.8.2010 Пользователь №: 1923 Спасибо сказали: 0 раз(а) Репутация: 0 |
Со всеми перечисленными устройствами была достигнута корректная работа.
|
|
|
good835 |
5.8.2010, 14:40
Сообщение
#114
|
Студент Группа: Новичок Сообщений: 14 Регистрация: 5.8.2010 Пользователь №: 1933 Спасибо сказали: 0 раз(а) Репутация: 0 |
Добрый день!
Задача: Прошивка программного обеспечения через com порт в режиме с управлением потоком на скоростях 115200 и 230400 бит/с Опыт программирования на Qt и работы с com-портом минимальный, так что вопросы могут быть соответствующие ... Платформа: Microsoft Windows XP Service Pack 2 Среда сборки Qt Creator 2.0 Версии библиотеки 1. QSerialDevice 0.2.0 2. QSerialDevice из репозитария git http://gitorious.org/qserialdevice (от 3 августа) Последовательные порты: 1. Cтандартный последовательный порт установленный на материнской плате 2. Prolific USB-to-Serial Comm Port 3. Moxa UPort 1110 1-портовый преобразователь USB в RS-232 4. Moxa NPort 510 преобразователь Ethernet в RS-232 5. Virtual Serial Ports Driver XP фирмы Eltima Software Первый вопрос по QSerialDeviceWatcher: Версия 0.2.0 - выдавался список всех портов в системе п.1-5 (с проверкой записи данных в порт) Версия git - выдается только список "железных" портов в системе п.1-3 Первое что я заметил, это то что происходит чтение из другого места в реестре. Второй вопрос по использованию нестандартной скорости передачи 230400 бит/с, которую поддерживают порты Prolific USB2Comm и Moxa UPort 1110 Версия 0.2.0 - после добавления в список ряда скоростей соответствующей константы передача данных осуществлялась без ошибок Версия git - на скорости 115200 бит/с передача данных осуществляется без ошибок, а на скорости 230400 бит/с порт успешно открывается, задаются параметры, но далее при передаче данных происходит сбой с выдачей следующего сообщения Windows: NativeSerialEnginePrivate::nativeWrite(const char *data, qint64 len) -> function: ::::WaitForSingleObject(this->oTx.hEvent, 5000) returned: 258 . Error! Третий вопрос: Произвожу отправку данных в порт функцией qint64 AbstractSerial::write(const char *data, qint64 maxSize) Каким образом можно задать таймаут на выполнение данной функции, так как в случае ошибки передачи данных поисходит зависание программы, например, при разрыве кабеля |
|
|
kuzulis |
5.8.2010, 15:47
Сообщение
#115
|
Активный участник Группа: Участник Сообщений: 393 Регистрация: 29.6.2009 Пользователь №: 862 Спасибо сказали: 36 раз(а) Репутация: 7 |
2 good835,
Цитата Первый вопрос по QSerialDeviceWatcher: Версия 0.2.0 - выдавался список всех портов в системе п.1-5 (с проверкой записи данных в порт) Версия git - выдается только список "железных" портов в системе п.1-3 Первое что я заметил, это то что происходит чтение из другого места в реестре. Да, из другого места. Я попробую сегодня скачать драйвер виртуального порта п. 5 и потестить с ним. Также вы сами можете проверить наличие в реестре записей для этих портов по путям: HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\Serenum\\Enum HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\Ser2pl\\Enum HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\usbser\\Enum HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\lowcdc\\Enum тут приведены пути в которых прописаны девайсы п.1-3 ... Для виртуальных портов наверное есть какие то другие пути. Запустите диспетчер устройств, выберите девайс (п.4-5) и в вкладке "сведения" конкретного порта покажите мне что есть в значении : "Код экземпляра устройства" "Служба" "Верхние фильтры устройства" Цитата Второй вопрос по использованию нестандартной скорости передачи 230400 бит/с, которую поддерживают порты Prolific USB2Comm и Moxa UPort 1110 Версия 0.2.0 - после добавления в список ряда скоростей соответствующей константы передача данных осуществлялась без ошибок Версия git - на скорости 115200 бит/с передача данных осуществляется без ошибок, а на скорости 230400 бит/с порт успешно открывается, задаются параметры, но далее при передаче данных происходит сбой с выдачей следующего сообщения Windows: NativeSerialEnginePrivate::nativeWrite(const char *data, qint64 len) -> function: ::::WaitForSingleObject(this->oTx.hEvent, 5000) returned: 258 . Error! Ну тут не знаю, тут почему-то WaitForSingleObject не дожидается события от порта что данные записаны.. Короче таймаут ожидания 5 секунд срабатывает. Попробуйте выставить таймаут 10 секунд = 10000 ... Если честно, я не знаю почему эта ошибка происходит. Код я брал "стандартный" предложенный $MS, так что не знаю... Цитата Третий вопрос: Произвожу отправку данных в порт функцией qint64 AbstractSerial::write(const char *data, qint64 maxSize) Каким образом можно задать таймаут на выполнение данной функции, так как в случае ошибки передачи данных поисходит зависание программы, например, при разрыве кабеля Ух... тут это наверное возникает изза "режиме с управлением потоком" . Если это так, то я не сталкивался с этими особенностями и даж не представлю куда копать... Хотя, попробуйте в методе:
для this->cc.dcb.fAbortOnError = true; (вместо false)!!! Сообщение отредактировал kuzulis - 5.8.2010, 16:01 |
|
|
good835 |
5.8.2010, 18:02
Сообщение
#116
|
Студент Группа: Новичок Сообщений: 14 Регистрация: 5.8.2010 Пользователь №: 1933 Спасибо сказали: 0 раз(а) Репутация: 0 |
2 kuzulis,
Насколько я понял QSerialDeviceWatcher версии 0.2.0 читал данные о портах в системе по следующей ветке: [HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM] она у меня выглядит следующим образом "\\Device\\Serial0"="COM1" "\\Device\\Serial1"="COM2" "\\Device\\mxuport0"="COM14" "\\Device\\mxuport1"="COM13" "\\Device\\VSerial0"="COM20" "\\Device\\VSerial1"="COM21" "Npdrv8"="COM8" "Npdrv7"="COM7" В диспетчере устройств Виртуальные порты (COM20 COM21 из п.5) идут отдельной строкой Eltima Virtual Serial Port(COM20->COM21) Eltima Virtual Serial Port(COM21->COM20) "Код экземпляра устройства" VSBUS\DEVICES\0000 и VSBUS\DEVICES\0001 "Служба" vserial "Верхние фильтры устройства") пусто по moxa ethernet 2 com - сейчас оно не подключено и возможно поэтому его нет в диспетчере устройств а так это "Npdrv8"="COM8", "Npdrv7"="COM7" в программе NPort Administrator они конфигурируются следующим образом но это вряд ли поможет [Summary] Total_Server=1 [Server1] APID=0x80000312 HWID=0x322 IP=192.168.0.170 Port1=1,7,0,1,1,12,0,3,0,0,5000 Port2=1,8,0,1,1,12,0,3,0,0,5000 Данные из реестра для moxa nport 5210 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\npdrv] "Group"="Extended base" "Type"=dword:00000001 "Start"=dword:00000002 "ErrorControl"=dword:00000000 "ImagePath"=hex(2):5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,\ 74,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,64,00,72,\ 00,69,00,76,00,65,00,72,00,73,00,5c,00,6e,00,70,00,64,00,72,00,76,00,2e,00,\ 73,00,79,00,73,00,00,00 "DisplayName"="npdrv" [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\npdrv\Parameters] "Ports"=dword:00000002 "Servers"=dword:00000001 "SessionRecovery"=dword:00000001 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\npdrv\Parameters\Server1] "APID"=dword:80000312 "HWID"=dword:00000322 "IPAddress"=dword:c0a800aa "PortFlag"=hex:01,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00 "COMNO"=hex:07,08,01,01,01,01,01,01,01,01,01,01,01,01,01,01 "TransmissionMode"=hex:01,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00 "FIFO"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 "FastFlush"=hex:01,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00 "NetTimeOut"=hex:88,13,00,00,88,13,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\ 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\npdrv\Security] "Security"=hex:01,00,14,80,90,00,00,00,9c,00,00,00,14,00,00,00,30,00,00,00,02,\ 00,1c,00,01,00,00,00,02,80,14,00,ff,01,0f,00,01,01,00,00,00,00,00,01,00,00,\ 00,00,02,00,60,00,04,00,00,00,00,00,14,00,fd,01,02,00,01,01,00,00,00,00,00,\ 05,12,00,00,00,00,00,18,00,ff,01,0f,00,01,02,00,00,00,00,00,05,20,00,00,00,\ 20,02,00,00,00,00,14,00,8d,01,02,00,01,01,00,00,00,00,00,05,0b,00,00,00,00,\ 00,18,00,fd,01,02,00,01,02,00,00,00,00,00,05,20,00,00,00,23,02,00,00,01,01,\ 00,00,00,00,00,05,12,00,00,00,01,01,00,00,00,00,00,05,12,00,00,00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\npdrv\Enum] "0"="Root\\LEGACY_NPDRV\\0000" "Count"=dword:00000001 "NextInstance"=dword:00000001 Данные из реестра для виртуальных портов Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vserial] "Type"=dword:00000001 "Start"=dword:00000003 "ErrorControl"=dword:00000001 "ImagePath"=hex(2):53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,44,00,\ 52,00,49,00,56,00,45,00,52,00,53,00,5c,00,76,00,73,00,65,00,72,00,69,00,61,\ 00,6c,00,2e,00,73,00,79,00,73,00,00,00 "DisplayName"="ELTIMA Virtual Serial Ports Driver" "Group"="Extended Base" "ForceFifoEnable"=dword:00000001 "RxFIFO"=dword:00000008 "TxFIFO"=dword:0000000e "LogFifo"=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vserial\Security] "Security"=hex:01,00,14,80,90,00,00,00,9c,00,00,00,14,00,00,00,30,00,00,00,02,\ 00,1c,00,01,00,00,00,02,80,14,00,ff,01,0f,00,01,01,00,00,00,00,00,01,00,00,\ 00,00,02,00,60,00,04,00,00,00,00,00,14,00,fd,01,02,00,01,01,00,00,00,00,00,\ 05,12,00,00,00,00,00,18,00,ff,01,0f,00,01,02,00,00,00,00,00,05,20,00,00,00,\ 20,02,00,00,00,00,14,00,8d,01,02,00,01,01,00,00,00,00,00,05,0b,00,00,00,00,\ 00,18,00,fd,01,02,00,01,02,00,00,00,00,00,05,20,00,00,00,23,02,00,00,01,01,\ 00,00,00,00,00,05,12,00,00,00,01,01,00,00,00,00,00,05,12,00,00,00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vserial\Enum] "0"="VSBUS\\DEVICES\\0000" "Count"=dword:00000002 "NextInstance"=dword:00000002 "1"="VSBUS\\DEVICES\\0001" Sorry, файлы не дает загрузить HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\Serenum\\Enum - есть HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\Ser2pl\\Enum - есть Ser2pl, но нет enum HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\usbser\\Enum - нет HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\lowcdc\\Enum - нет HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\mxuwdrv2\\ для moxa usb2com HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\vserial\\ для вирт портов HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\npdrv\\ для ethernet 2 com остальное пока не пробовал немного странно что версия 0.2.0 работала на скорости 230400 нормально, а последняя нет ( |
|
|
kuzulis |
5.8.2010, 18:33
Сообщение
#117
|
Активный участник Группа: Участник Сообщений: 393 Регистрация: 29.6.2009 Пользователь №: 862 Спасибо сказали: 36 раз(а) Репутация: 7 |
2 good835,
на основе ваших данных я попробовал добавить поддержку тех устройств которые вы перечислили. Обновляйте Git и пробуйте. |
|
|
good835 |
6.8.2010, 11:54
Сообщение
#118
|
Студент Группа: Новичок Сообщений: 14 Регистрация: 5.8.2010 Пользователь №: 1933 Спасибо сказали: 0 раз(а) Репутация: 0 |
2 kuzulis,
Еще раз по поводу списка портов в системе... Все таки не могли бы вы пояснить почему сканируется реестр по ветке HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services Сегодня еще раз попробовал версию 0.2.0 - она отлично видит список всех последовательных портов в системе по [HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM] и нормально работает со всеми типами портов с аппратными, usb2com, и ethernet2com на скорости 230400 бит/с Я разговаривал с человеком который занимался подобным вопросом, он сказал что также работал с веткой [HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM] Версия из git Теперь видит виртуальные порты (Eltima Virtual Serial Port), а порты ethernet2com по прежнему отсутствуют 2 kuzulis, Подскажите существует ли возможность с помощью вашей библиотеки задать параметры таймаута для последовательного порта при записи данных конкретнее, WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant http://msdn.microsoft.com/en-us/library/aa...0(v=VS.85).aspx |
|
|
kuzulis |
6.8.2010, 12:53
Сообщение
#119
|
Активный участник Группа: Участник Сообщений: 393 Регистрация: 29.6.2009 Пользователь №: 862 Спасибо сказали: 36 раз(а) Репутация: 7 |
Цитата Все таки не могли бы вы пояснить почему сканируется реестр по ветке HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services Сегодня еще раз попробовал версию 0.2.0 - она отлично видит список всех последовательных портов в системе по [HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM] и нормально работает со всеми типами портов с аппратными, usb2com, и ethernet2com на скорости 230400 бит/с Я разговаривал с человеком который занимался подобным вопросом, он сказал что также работал с веткой [HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM] См. почему я изменил ветку от этого поста и ниже по постам. Цитата Теперь видит виртуальные порты (Eltima Virtual Serial Port), а порты ethernet2com по прежнему отсутствуют Напишите сюда что точно видно в диспетчере устройств по тэгу "Служба" при наличии ethernet2com порта. Я так понимаю это девайс от MOXA? Цитата Подскажите существует ли возможность с помощью вашей библиотеки задать параметры таймаута для последовательного порта при записи данных конкретнее, WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant http://msdn.microsoft.com/en-us/library/aa...0(v=VS.85).aspx В данной реализации в этом нет никакого смысла. Сейчас в библиотеки эи таймауты все нули, т.е. ф-я Write возвращает управление немедленно не дожидаясь пока данные отправятся. Поэтому ИМХО, проблема не в этом - а в том, что вы устанавливаете режим контроля потока (я попробую вечером проверить эту идею) или же это косяки драйвера или еще что-то. |
|
|
good835 |
6.8.2010, 14:37
Сообщение
#120
|
Студент Группа: Новичок Сообщений: 14 Регистрация: 5.8.2010 Пользователь №: 1933 Спасибо сказали: 0 раз(а) Репутация: 0 |
ethernet2com - это moxa nport 5210 - в диспетчере устройств его нет
в реестре, это HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM]"Npdrv8"="COM8" "Npdrv7"="COM7" плюс HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\npdrv, но вы его уже добавили в список (подробнее этот параметр я приводил выше) Если я правильно понимаю, смена ветки нужна для корректного слежения за физически подключенными портами в системе? Может это конечно и лучше, но для каждого нового типа порта вам придется править программу...что тоже не есть хорошо По поводу таймаутов пока думаю, разбираюсь что к чему. |
|
|
Текстовая версия | Сейчас: 14.11.2024, 19:11 |