crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

44 страниц V  « < 4 5 6 7 8 > »   
Ответить в данную темуНачать новую тему
> QSerialDevice - Библиотека для работы с COM-портами
kuzulis
  опции профиля:
сообщение 15.5.2010, 13:36
Сообщение #51


Активный участник
***

Группа: Участник
Сообщений: 393
Регистрация: 29.6.2009
Пользователь №: 862

Спасибо сказали: 36 раз(а)




Репутация:   7  


Цитата
А очень просто. Надо перехватывать все события udev'а, а не только те, что связаны с rs232 портами. И смотреть, являлось ли отключённое устройство портом.


Да так там и работает. Ловятся любые события от UDEV а потом просто смотрим что изменилось в директории /dev, и если там пропало у-во которое является tty* - то мы сообщаем об этом. Значит при выдергивании порта когда он открыт события не приходят от UDEV. Нужно проверить как нибудь попозже.

Цитата
я использую QxtSerialPort в виндовозе, для отлова отключения преобразователя USB-RS232 при открытом порте всегда проверяю кол-во принятых байт. Драйвер FTDI'ного преобразователя всегда отрицательное значение возвращает.


Так это не означает, что конвертер отключен. Это означает что произошла какая то ошибка ввода - вывода ИМХО.

---
Резюмирую: чтобы реализовать полностью такую фичу как "отлов втыкания/выдергивания" конвертеров в любых состояниях (открыт или закрыт или что-то там еще) необходимо найти те механизмы в ОС которые позволяли бы обнаружить втыкание/извлечение конвертера.

Вот к примеру, если конвертер (порт) закрыт, то его "втыкание/извлечение" в принципе легко отслеживается. Но, если он открыт и в этот момент его мы "выдернули" - то это проблема ОС ! Если в ней еще сохраняется состояние того что порт присутствует - то виноват "индус" который писал ОС! :)

Если вы найдете механизм, который четко и однозначно определял наличие порта в системе - то я это реализую. Присылайте патчи.. Я только ЗА всеми руками!




Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 15.5.2010, 14:26
Сообщение #52


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(kuzulis @ 15.5.2010, 17:36) *
Так это не означает, что конвертер отключен.
само собой. Просто FTDI'ный драйвер гарантирует такое поведение при отключении устр-ва при открытом порте.

Справедливо для виндовоза:
Проблема большинства имитаторов COM-порта: при открытом порте вытаскиваем USB-устройство, далее если мы не закрываем порт и снова вставляем USB-устройство. То - приплыли. Больше мы этим портом воспользоватся не сможем, пока не проделаем следующую процедуру:
1) опять выдёргиваем USB-устройство
2) в диспетчере устройств делаем обновить, соответствующий COM-порт должен исчезнуть из списка
3) Вставляем USB-устройство вновь, оно должно определиться и снова должен появится COM-порт.

Тот трюк который проделываю я:
Если приняли отрицательное кол-во байт, порт сразу закрываю. Т.к. вставка USB-устройства при закрытом порте не приводит к выше описанному криминалу.


Цитата(kuzulis @ 15.5.2010, 17:36) *
Но, если он открыт и в этот момент его мы "выдернули" - то это проблема ОС ! Если в ней еще сохраняется состояние того что порт присутствует - то виноват "индус" который писал ОС!
индус прав. Открытый порт не может исчезнуть вдруг. Т.к. этот ресурс занят программой.

программа не может ни с того ни с сего лишиться ресурса. Представь себе ситуацию:
// ты создал переменную - тоже ресурс
int myvar = 10;
...
// далее ты хочешь воспользоваться ею
int var2 = myvar;
// но вот не задача, ресурс myvar исчез
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
dekar
  опции профиля:
сообщение 15.5.2010, 16:19
Сообщение #53


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 14.4.2010
Пользователь №: 1632

Спасибо сказали: 0 раз(а)




Репутация:   0  



Цитата(kuzulis @ 15.5.2010, 14:36) *
Да так там и работает. Ловятся любые события от UDEV а потом просто смотрим что изменилось в директории /dev, и если там пропало у-во которое является tty* - то мы сообщаем об этом. Значит при выдергивании порта когда он открыт события не приходят от UDEV. Нужно проверить как нибудь попозже.

---
Резюмирую: чтобы реализовать полностью такую фичу как "отлов втыкания/выдергивания" конвертеров в любых состояниях (открыт или закрыт или что-то там еще) необходимо найти те механизмы в ОС которые позволяли бы обнаружить втыкание/извлечение конвертера.

Вот к примеру, если конвертер (порт) закрыт, то его "втыкание/извлечение" в принципе легко отслеживается. Но, если он открыт и в этот момент его мы "выдернули" - то это проблема ОС ! Если в ней еще сохраняется состояние того что порт присутствует - то виноват "индус" который писал ОС! :)

Если вы найдете механизм, который четко и однозначно определял наличие порта в системе - то я это реализую. Присылайте патчи.. Я только ЗА всеми руками!


Мы подключаем устройство.

Вот события удева:

CODE
KERNEL[1273928448.612580] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1 (usb)
KERNEL[1273928448.615458] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0 (usb)
KERNEL[1273928448.622468] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0/tty/ttyACM0 (tty)
KERNEL[1273928448.622593] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.1 (usb)
KERNEL[1273928448.622606] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/usb_device/usbdev2.112 (usb_device)
UDEV [1273928448.626864] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1 (usb)
UDEV [1273928448.627187] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0 (usb)
UDEV [1273928448.628576] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.1 (usb)
UDEV [1273928448.640491] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0/tty/ttyACM0 (tty)
UDEV [1273928448.644527] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/usb_device/usbdev2.112 (usb_device)

Мы видим, что подключено устройство, связанное с tty

Теперь мы порт открываем, после чего вытаскиваем устройство. Результат:
CODE

KERNEL[1273928469.995045] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0 (usb)
KERNEL[1273928469.995079] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.1 (usb)
KERNEL[1273928469.996906] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/usb_device/usbdev2.112 (usb_device)
UDEV [1273928469.996923] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0 (usb)
KERNEL[1273928469.996937] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1 (usb)
UDEV [1273928469.998121] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.1 (usb)
UDEV [1273928469.999564] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/usb_device/usbdev2.112 (usb_device)
UDEV [1273928469.999826] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1 (usb)

Видно, что ttyACM0 не изчез. Но, если бы мы на прошлой итерации запомнили ещё и /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0/, то тогда мы бы могли сейчас подать сигнал о том, что вынули именно ttyACM0.

Если устройство было подключено до старта watcher'а, то тогда его путь в ядре можно было бы отловить в самом начале, делая табличку интересующих нас устройств, т.е. tty* (да, знаю устройств много. Но, ИМХО, это полезая фича.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 15.5.2010, 19:43
Сообщение #54


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(dekar @ 15.5.2010, 20:19) *
Но, ИМХО, это полезая фича
безусловно.

dekar, решение действительно хорошее, может kuzulis, возьмёт его на заметку.

П.С. по поводу оформления сообщений прочитай тему: Справка по кнопкам и тэгам форума
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
dekar
  опции профиля:
сообщение 16.5.2010, 23:59
Сообщение #55


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 14.4.2010
Пользователь №: 1632

Спасибо сказали: 0 раз(а)




Репутация:   0  


А ты можешь пока проверить, есть ли сигнал от изчезновения уже открытого порта в венде? На той версии, что уже есть. Ибо у меня пока нет возможности что-то под оной собрать.

И, если не сложно, краткое описание того, как вообще в венде собирать что-то. Там gcc вообще есть? make? Или только их студия? Вот уже поставил себе семёрку в виртуалке.

А править посты тут можно? Что-то я кнопочку не нахожу.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuzulis
  опции профиля:
сообщение 17.5.2010, 7:27
Сообщение #56


Активный участник
***

Группа: Участник
Сообщений: 393
Регистрация: 29.6.2009
Пользователь №: 862

Спасибо сказали: 36 раз(а)




Репутация:   7  


Цитата
А ты можешь пока проверить, есть ли сигнал от изчезновения уже открытого порта в венде? На той версии, что уже есть. Ибо у меня пока нет возможности что-то под оной собрать.

Я проверил под виндой. Да, таже проблемка :) . Но я знаю как решить.. Просто нужно "слушать" другие ветки реестра и все должно быть нормуль.

Цитата
И, если не сложно, краткое описание того, как вообще в венде собирать что-то. Там gcc вообще есть? make? Или только их студия? Вот уже поставил себе семёрку в виртуалке.

Дык есть описние . Если используешь MinGW, то сборка ничем не отличается. Но если Студию - то там только nmake вместо make. В общем ничего сложного.

Цитата
А править посты тут можно? Что-то я кнопочку не нахожу.

А для этого нужно набрать сколько то там постов (вроде)

----

В общем проблему понял, идеи есть. Будем решать в ближайшее время :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_leech_*
сообщение 18.5.2010, 22:04
Сообщение #57





Гости








    


Добрый день! Благодарю за отличный класс для работы с компортом!

Возникла долго не решаемая проблема с приёмом данных из порта, после востановления подключения к порту.
Использую приём по сигналу readyRead()

COMport = new AbstractSerial();
connect(COMport, SIGNAL(readyRead()), this, SLOT(slot_COMPortReadyRead()));


void SCPI_Generator::slot_COMPortReadyRead()
{
    qint64 ba_count= COMport->bytesAvailable();        // Количество пришёдших байт в буффере
    QByteArray ba = COMport->read(ba_count);          // Читаем данные из буфера

    inputBuffer.append(ba);
    if (inputBuffer.contains("\n"))                                 // Если пришёл конец строки
    {
        QString ba_str(inputBuffer);
        inputBuffer.clear();
        logText->append(QString("<b>&gt;</b> %1").arg(ba_str));       // Записываем посылаемые данные в лог
    }
}


При запуске программы открывается и настраивается COMпорт
bool SCPI_Generator::ComPortOpen()
{
    COMport->setDeviceName(comPortName);
    if (COMport->open(QIODevice::ReadWrite | QIODevice::Unbuffered))
    {
        COMport->reset();
        COMport->setBaudRate(QString("%1 baud").arg(comBaudRate));
        COMport->setDataBits(QString("%1 bit").arg(comDataBits));
        COMport->setStopBits(comStopBits);
        COMport->setParity(comParity);
        COMport->setFlowControl(comFlowControl);
        return true;
    }
    else // Ошибка открытия COM порта
    {
        QMessageBox::critical(this, tr("Critical error!"),
                                    tr("Error opened serial device %1.\n"
                                       "Select another COM port.").arg(COMport->deviceName()), QMessageBox::Ok);
        return false;
    }
}



пришедшие данные отлично отображаются. ОДнако, если закрыть COM порт и потом снова открыть, при приёме отображается такая ошибка

Windows: NativeSerialEnginePrivate::nativeSelect(int timeout, bool selectForRead) 
-> function: ::WaitForSingleObject(ovl.hEvent, timeout < 0 ? 0 : timeout),
returned: WAIT_TIMEOUT:  258 . Warning!


и данные не читаются. После этого сигнал readyRead() вообще не эмитируется. Зашел пока в тупик. Заранее благодарю за разъяснения!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuzulis
  опции профиля:
сообщение 19.5.2010, 7:32
Сообщение #58


Активный участник
***

Группа: Участник
Сообщений: 393
Регистрация: 29.6.2009
Пользователь №: 862

Спасибо сказали: 36 раз(а)




Репутация:   7  


leech

А попробуйте ка использовать версию библиотеки из SVN. Там по сравнению с 0.2.0 много чего изменилось, внимательно посмотрите примеры и abstractserial.h.
Если и там будет такая-же проблема - то будем разбираться.

Из SVN качайте SVN-клиентом. Описание как это делать находится тут: http://fireforge.net/scm/?group_id=199

Ни в коем случае не жмакайте на ссылку: [Загрузить свежую SVN базу репозитория]
т.к. получите не свежий срез - а 2010/04/05. . (какая то ошибка на сервере/сайте)

Т.е. свежак - это использование клиента!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_leech_*
сообщение 19.5.2010, 17:36
Сообщение #59





Гости








    


Благодарю! Скачал SVN, пересобрал, поправил вызовы в связи с миграцией класса AbstractSerial с QIODevice на QObject, и всё заработало! Проблема решилась.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 26.5.2010, 7:16
Сообщение #60


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


kuzulis, отредактируй пожалуйста первое сообщение темы. Чтобы в нём были актуальные ссылки на проект/исходники.
Т.к. новичкам может быть обременительно читать всю тему в поисках ссылок.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

44 страниц V  « < 4 5 6 7 8 > » 
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 16:37