Russian Qt Forum
Ноябрь 23, 2019, 05:58 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 ... 87   Вниз
  Печать  
Автор Тема: Создаю библиотеку для работы с последовательными портами. [В ПРОЦЕССЕ].  (Прочитано 382212 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2709


Просмотр профиля
« : Май 17, 2009, 18:27 »

Доброго дня!

Важная новость!
26.02.2013 – Проект перемещен из песочницы в основную ветвь Qt5!

Важное замечание!:

С недавнего времени ветка QSerialDevice 2.0
портирована в репозиторий на Gerrit и планируется,
что она станет аддоном для Qt5 под названием QtSerialPort.

Подробнее тут http://qt-project.org/wiki/QtSerialPort_Russian

Далее, все что написано ниже в этом первом посте относится
только к "устаревшей" библиотеке QSerialDevice, разработка
которой остановлена, т.к. все силы срочно брошены на QtSerialPort.

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



Вступление:

Я тут решил создать библиотеку для работы с последовательными портами.
Упор делался на возможность будущей интеграции в Qt4, поэтому желательно
собирать библиотеку имея Qt4 скомпилированную из исходников (а не готовую).
Причина такой рекомендации в том, что в готовых SDK может не быть некоторых приватных заголовков, которые используются в библиотеке QSerialDevice.

На текущий момент имеются две ветки разработки:
1. Это текущая ветка 1.0 "master" с нумерацией версий от 0 до 1 (0.3, 0.4)
2. Новая ветка 2.0, разработка которой начата 18.06.2011



Содержимое QSerialDevice ветки 1.0

Класс AbstractSerial
Собственно, является основным классом который управляет работой последовательного порта
и предоставляет следующие функциональные возможности:
- читать/писать данные
- конфигурировать порт:
  + любой скоростью обмена (в рамках разумного)
  + любым кол-вом бит данных (5-8)
  + любым типом паритета (None, Even, Add, Mark, Space),
  + любым кол-вом стоп-бит (1, 1.5, 2)
  + любым режимом контроля потоком (Off, Hardware, Software)
- получать состояние линий порта
- работать в буферизированном и небуферизированном режиме

Т.к. класс AbstractSerial унаследован от QIODevice, то он предоставляет все методы и сигналы от QIODevice,
а также дополнительные специфические методы и сигналы.

Поддерживается в ОС: GNU/Linux, MS Windows, MacOSX и др. POSIX совместимых.

Класс SerialDeviceEnumerator
Является вспомогательным классом, который предоставляет
следующие функциональные возможности:
- получать список имен всех имеющихся последовательных портов в системе
- получать определенную информацию о выбраном порте по его имени
- автоматически уведомлять о новых появившихся портах или об их исчезновении

Поддерживается в ОС: GNU/Linux, MS Windows, MacOSX (кроме уведомления).

----
PS: Разработка этой ветки приостановлена и будет оказываться только её поддержка.



Содержимое QSerialDevice ветки 2.0

Эта версия является (планировалась) "как-бы" более продвинутой,
оптимизированной на быстродействие (золотая середина).
Но, главной особенностью - является структура классов, более "заточенная" к возможности
принятия в Qt.

Класс SerialPort
Выполняет функции аналогичные AbstractSerial из более ранней ветки,
но более облегчен и "вылизан".

Планируется поддержка в ОС: GNU/Linux, MS Windows, MacOSX и др.

Уже реализована базовая поддержка: GNU/Linux, MS Windows, MacOSX, WinCE, Symbian.
Но необходима помощь "симбианщиков" для доделки.


Класс SerialPortInfo
Выполняет функции аналогичные SerialDeviceEnumerator из более ранней ветки,
но также более облегчен и "вылизан" и имеет переработанную структуру (наподобие QPrinterInfo).

Планируется поддержка в ОС: GNU/Linux, MS Windows, MacOSX и др.

Уже реализована базовая поддержка: GNU/Linux, MS Windows, MacOSX, WinCE, Symbian.

----
PS: Разработка и поддержка этой ветки идет полным ходом.

Где скачать?

Текуций репозиторий с исходными кодами находится тут: https://gitorious.org/qserialdevice
Как скачать, думаю, разберетесь.

==========
Для всех заинтересованных лиц, готовых принять участие в разработке, тестировании, генерации новых идей - милости просим на обсуждение в эту тему форума.
« Последнее редактирование: Февраль 26, 2013, 20:40 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3872


Просмотр профиля WWW
« Ответ #1 : Май 17, 2009, 18:38 »

Цитировать
1. Асинхронный
2. Поддержка waitForReadyRead и т.п. и т.д.
можно по подробнее насчёт асинхронности? Как она реализована?
Записан

Юра.
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2709


Просмотр профиля
« Ответ #2 : Май 17, 2009, 18:46 »

2 lit-uriy,

ну, это, исходники гляньте Улыбающийся , я сам не знаю как

т.е с помощью объектов ядра мы ловим события по приходу или уходу символов в буфер и потом читаем их и т.п и т.д. .. эмм..  примерно так Улыбающийся
т.е по факту наличия в буфере байт!


//
Me:

http://enos.itcollege.ee/~aandreim/Diplom/loputoo-arendus.pdf

http://library.developer.nokia.com/index.jsp?topic=/S60_3rd_Edition_Cpp_Developers_Library/GUID-35228542-8C95-4849-A73F-2B4F082F0C44/html/SDL_93/doc_source/reference/reference-cpp/C32/RCommServClass.html

http://www.koders.com/cpp/fid6E732C74FA1BA3E40D2A20EC9006D75DB6B3AA10.aspx?s=sort
« Последнее редактирование: Сентябрь 30, 2011, 15:14 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3872


Просмотр профиля WWW
« Ответ #3 : Май 18, 2009, 00:06 »

>>объектов ядра мы ловим события по приходу или уходу символов в буфер
ну вот в виндовозе у последовательного порта есть события и на них можно подписаться.
А в *nix-системах, я никгда не слышал про подобное.
И склонен считать, что в QextSerialPort соответствующей функциональности нет именно по этой причине.
В исходниках "qextserialport-1.1" есть кусок кода для виндовоза для работы в асинхронном режиме и он полностью закоментирован, видимо из-за отсутствия аналогичного для *nix'ов
Записан

Юра.
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2709


Просмотр профиля
« Ответ #4 : Май 18, 2009, 07:21 »

Цитировать
ну вот в виндовозе у последовательного порта есть события и на них можно подписаться.
А в *nix-системах, я никгда не слышал про подобное.

все там есть Улыбающийся .. там все на вызов Select завязано.. да гляньте ж исходники в конце то концов (мои) !!! Улыбающийся  
« Последнее редактирование: Июнь 28, 2011, 14:36 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2709


Просмотр профиля
« Ответ #5 : Май 18, 2009, 07:31 »

ЗЫ:

я уже в "промышленных масштабах АСУТП" применял асинхронный режим под Windows и Linux, правда не используя QT. А теперь вот с QT вышел УПС! Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2709


Просмотр профиля
« Ответ #6 : Май 18, 2009, 07:42 »

т.е алгоритм такой (что в виндах что в никсах):

1) Если хотим прочитать из порта 100 байт то:
1. Делаем waitForReadyRead и в качестве таймаута ставим время в течении которого будем ожидать прихода данных в Rx буфер порта!
2. Если время истекло - то п.1 вернет false
3. Если все нормуль (т.е пришел хотябы 1 байт) - то true
4. Теперь проверяем сколько пришло в буфер байт bytesAvaiable (эта в-я вызывается внутри readData)
5. Читаем эти байты и делаем инкремент счетчика: retVal+=bytesRead.
6. Делаем  waitForReadyRead и в качестве таймаута ставим время ожидания следующего СИМВОЛА!.
7. Если время истекло - то значит что посылка закончилась и можем возвратить прочитанные байты
8. Если опять пришли данные то см. п. 4 и так до того времени пока не прочитаем все 100 Байт из буфера

Теперь:
1. Если нужно прочитать 100 байт, а пришло в конце концов 200 - то прочитается 100 байт
2. Если нужно прочитать 100 байт а пришло в конце концов 50 - то прочитается 50

Вот примерно такая идея
Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2709


Просмотр профиля
« Ответ #7 : Май 18, 2009, 11:23 »

Попробуйте кто нить для эксперимента создайте класс наследник от QIODevice, переопределите bytesAvaiable примерно так:
Код:
...
...
qint64 TMyDevice::bytesAvailable () const
{
   qint64 mybav =0;
   qint64  bav = QIODevice::bytesAvailable () ;
   cout << "mybav = " << mybav << "| bav =  " << bav << endl;
   return mybav + bav ;

}
...
...
потом выполните в ф-ции main:
Код:
...
qint64 MyDevice.open();
qint64 rbav= MyDevice.bytesAvailable ();
cout<<" rbav = " << rbav << endl;
MyDevice.close();
...

и скажите, какое значение в выводе у гого переменых : mybav, bav, rbav !

Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2709


Просмотр профиля
« Ответ #8 : Май 19, 2009, 11:46 »

Ничего не понимаю! Грустный

Сам сделал как тут постом выше написал - вывод mybav , bav , rbav нули везде (пробовал под QT4.3.4 под x86_64 ArchLinux) ,
но когда собираю библиотеку QSerialDevice и примеры к ней - то QIODevice::bytesAvailable () возвращает значение = 16384  !!!

Я уже не знаю в чем дело! Грустный
Записан

ArchLinux x86_64 / Win10 64 bit
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2510

чтоб работа волком не казалась :)


Просмотр профиля WWW
« Ответ #9 : Май 19, 2009, 17:01 »

делали тоже подобную штуку, если интересно, сырцы тут:
http://ii-system.com/soft/devzone/serialport.2007.09.16.zip
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

http://sintegrial.com - всякий хороший Qt софт (был Грустный )
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2709


Просмотр профиля
« Ответ #10 : Май 19, 2009, 17:30 »

посмотрел, но там не то немного.. там все-равно на базе QextSerialPort сделано .. 
но спасибо ! Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2709


Просмотр профиля
« Ответ #11 : Май 19, 2009, 18:47 »

Вроде нашел где "баг" наблюдается.... В общем если вызвать MyDevice->bytesAvaiable() - то функция возвращает правильное количество байт в входном буфере, НО если вызвать ее изнутри класса QSerialDevce , вот так - то возвращает те-же 16384 бйит!!! :
Код:
qint64 TPosixSerialDevice::readData(char * data, qint64 maxSize)
{
    int bytesRead=0;//кол-во реально прочитанных байт за один проход
    int retVal=0;//кол-во реально прочитанных байт за все проходы
    int bav=0;//количество байт готовых бля чтения, которые находятся в текущий момент в приемном буфере последовательного устройства
    do {
        if (maxSize>retVal) {
            bav=bytesAvailable(); // ВОТ ТУТ ОНА НЕПРАВИЛЬНО ВОЗВРАЩАЕТ ЗНАЧЕНИЕ = 16384 !!! о_О
            if (bav>0) {
                if ((maxSize-retVal)<=bav) {
                    bav=maxSize-retVal;
                }
bytesRead = ::read(fd, (void*)(data+retVal), bav);
                if  (bytesRead==-1) {
                TTY_PORTABILITY_DEBUG("TPosixSerialDevice::readData->bytesRead==-1! Error!");
                    return -1;
                }//if read == -1
                else {
                    if (bytesRead==bav) {
                        retVal+=bytesRead;//with OK
                    }//if bytesRead==bav
                    else {
                        TTY_PORTABILITY_DEBUG("TPosixSerialDevice::readData->(bytesRead!=bav) with OK! Error!");
                        return -1;
                    }//else bytesRead!=bav
                }//else read
            }//if bav>0
            else {
                TTY_PORTABILITY_DEBUG("TPosixSerialDevice::readData-> (bav<=0)! Error!");
                return -1;
            }//else bav<=0
        }//if maxSize>retVal
        else {
            return retVal;
        }
    } while (waitForReadyRead(parameters->charIntervalTimeout));//ожидаем прихода в приемный буфер устройства следующего символа
    return retVal;
}


Я не знаю в чем причина такого поведения! Подскажите кто нибудь!! МОжет нужно как-то по особенному переопределять виртуальные функции ??
« Последнее редактирование: Май 20, 2009, 13:12 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2709


Просмотр профиля
« Ответ #12 : Май 25, 2009, 22:09 »

Все, разобрался где касяк! В общем в Qt 4.3.4 в файле qiodevice.cpp есть такое:
Код:
...
static const qint64 QIODEVICE_BUFFERSIZE = 16384;
...
...
qint64 QIODevice::read(char *data, qint64 maxSize)
{
...
...
     qint64 readSoFar = 0;
    bool moreToRead = true;
    do {
        int lastReadChunkSize = 0;

        // Try reading from the buffer.
        if (!d->buffer.isEmpty()) {
            lastReadChunkSize = d->buffer.read(data + readSoFar, maxSize - readSoFar);
            readSoFar += lastReadChunkSize;
            if (!sequential)
                d->pos += lastReadChunkSize;
#if defined QIODEVICE_DEBUG
            printf("%p \treading %d bytes from buffer into position %d\n", this, lastReadChunkSize,
                   int(readSoFar) - lastReadChunkSize);
#endif
        } else if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) { // <<<<<<<< ========= ВОТ ИЗЗА ЭТОГО ЕСТЬ НЕПОНЯТКА!!!
            // In buffered mode, we try to fill up the QIODevice buffer before
            // we do anything else.
            int bytesToBuffer = qMax(maxSize - readSoFar, QIODEVICE_BUFFERSIZE);
            char *writePointer = d->buffer.reserve(bytesToBuffer);
...
...
}

при том в Qt 4.1. вообще другое содержимое у qiodevice.cpp

мне только вот непонятно зачем вообще нужно это:
Код:
...
else if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE)
...

Братцы! Выручайте! Скиньте кто-нить файл qiodevice.cpp от Qt 4.5 и выше! Оч нужно! Улыбающийся

 
« Последнее редактирование: Апрель 09, 2012, 18:21 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #13 : Май 25, 2009, 22:25 »

Братцы! Выручайте! Скиньте кто-нить файл qiodevice.cpp от Qt 4.5 и выше! Оч нужно! Улыбающийся

Лови. Qt 4.5.1
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3872


Просмотр профиля WWW
« Ответ #14 : Май 26, 2009, 02:58 »

kuzulis, Вот тебе все файлы ветки 4.5, самый свежак: http://qt.gitorious.org/qt/qt/trees/4.5
Вот сам файл: http://qt.gitorious.org/qt/qt/blobs/4.5/src/corelib/io/qiodevice.cpp
(в низу страницы есть ссылка Raw blob data, чтобы скачать сам файл)
« Последнее редактирование: Май 26, 2009, 03:01 от lit-uriy » Записан

Юра.
Страниц: [1] 2 3 ... 87   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.058 секунд. Запросов: 22.