crossplatform.ru

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

44 страниц V  « < 24 25 26 27 28 > »   
Ответить в данную темуНачать новую тему
> QSerialDevice - Библиотека для работы с COM-портами
niklep
  опции профиля:
сообщение 22.5.2011, 18:59
Сообщение #251


Новичок


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

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




Репутация:   0  


Прошу прощения, косяк был мой (стоило ожидать=)). просто я не в том месте делал привязку:
connect(temp_com->port, SIGNAL(readyRead()), this, SLOT(slotReadCom()));
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuzulis
  опции профиля:
сообщение 22.5.2011, 20:24
Сообщение #252


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

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

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




Репутация:   7  


Цитата(niklep @ 22.5.2011, 19:59) *
Прошу прощения, косяк был мой (стоило ожидать=)). просто я не в том месте делал привязку:
connect(temp_com->port, SIGNAL(readyRead()), this, SLOT(slotReadCom()));

Понятно. :)

Значит можешь не отвечать на мои сообщения на gitorious.org .
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
devnir
  опции профиля:
сообщение 24.5.2011, 15:28
Сообщение #253


Новичок


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

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




Репутация:   0  


Здравствуйте, перечитал практически всю тему. Собственно читать то начал из-за своей проблемы:
работаю с AbstractSerial, собственно из под Linux - все хорошо и прекрасно. а вот в маст дае (Win) начинают "теряться" байты данных.
Ну собственно сам код:
Port = new AbstractSerial(this);
#if defined (Q_OS_UNIX)
    portNameStr = "/dev/ttyUSB0";
#elif defined (Q_OS_WIN)
    portNameStr = "COM1";
#endif


инициализация и открытие:
    Port->setDeviceName(Pname);
    if (Port->open(AbstractSerial::ReadWrite | AbstractSerial::Unbuffered)){

        if (!Port->setBaudRate(AbstractSerial::BaudRate115200)) {
        };
        if (!Port->setDataBits(AbstractSerial::DataBits8)) {
        };
        if (!Port->setParity(AbstractSerial::ParityNone)) {
        };
        if (!Port->setStopBits(AbstractSerial::StopBits1)) {
        };
        if (!Port->setFlowControl(AbstractSerial::FlowControlOff)) {
        };

#if defined (Q_OS_UNIX)
        if (Port->openMode() & AbstractSerial::Unbuffered)
            Port->setCharIntervalTimeout(10000);//5 msec
#elif defined (Q_OS_WIN)
        if (Port->openMode() & AbstractSerial::Unbuffered)
            Port->setTotalReadConstantTimeout(100);
#endif

#ifdef __Debug__
        dbg("Port Opened, timeout: %d\n", Port->charIntervalTimeout());
#endif
        connect(Port, SIGNAL(readyRead()), this, SLOT(slotReadPort()));
        return true;
    }
    else
    {
#ifdef __Debug__
        dbg("Port not OPENED!!! \n");
#endif
        return false;
    }



slotReadPort()
{
    QByteArray tmpBuff;
    quint64 len = Port->bytesAvailable();
    tmpBuff = Port->read(len);
    for(int i =0; i< tmpBuff.length(); i++)
    {
        dbg("0x%02X ", tmpBuff.at(i)&0xff);
        pRead(tmpBuff.at(i)&0xff);
    }
}


использую для пересылки файла через порт. Алгоритм простой как двери. отправил сообщение - получил подтверждение что со стороны приемника часть файла получена (0xAA)- отправил следующую часть(F_LEN = 4096 + 4 байта) с небольшой задержкой:
pRead(char c)
{
                if (c==0xAA) {
                    serial_timer.start(TR_WAIT);
                }
}


slotTimeout()
{
            if (offset >= file_data.size())
                return;

            this->Port->write(file_data.constData()+offset, F_LEN);
                offset+=F_LEN;
}


Собственно где я что упустил ? Есть идеи? Писал и отлаживал в Linux, вот понадобилось собрать под винду. собрал - а работает не корректно. примерно на пересылке 2-3 го блока все зависает :( из за того что не получена квитанция о пересылке предыдущего куска.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuzulis
  опции профиля:
сообщение 24.5.2011, 16:10
Сообщение #254


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

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

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




Репутация:   7  


Попробуй пройтись сниффером типа free-serial-port-monitor на предмет того, а шлет ли клиент вообще 0хAA ?!
А также выложи минимальные компилябельные проекты "клиента<->сервера" в которых воспроизводится данная проблема.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
devnir
  опции профиля:
сообщение 24.5.2011, 17:07
Сообщение #255


Новичок


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

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




Репутация:   0  


Да мне кажется там просто переполнение идет буферов порта у винды. - рвется пакет который отправляется - ну а приемник собственно проверяет ЦРЦ свертку - которая не сходится - нет АА.

Проверил примерно так:
файл для передачи: нарезал на 4096 байт + 4байта ЦРЦ32. получил 4100 байт массива который передал кусками (с задержкой в 1 сек.) по 205 байт.
Покурил - сделал кофе - вернулся, пол файла передало. но ошибок нет.
Теперь вот думаю примерно какой кусок и с какой задержкой посылать - что бы не переполнить какуют там ФиФошку. Еще угнетает то что QT в виртуалке да еще и статической сборки. Проэкт линкуется минут 15 :(

Насчет снифера - то я уже мониторил. Собственно и дошел до того что ошибка именно в переполнении буферов винды(сервер) - так как порт начинал работать криво - терял байты. хотя с другой стороны(клиент) мониторя - я точно уверен в отправке сообщения, так как там такой же снифер стоял.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuzulis
  опции профиля:
сообщение 24.5.2011, 18:36
Сообщение #256


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

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

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




Репутация:   7  


Цитата
файл для передачи: нарезал на 4096 байт + 4байта ЦРЦ32. получил 4100 байт массива который передал кусками (с задержкой в 1 сек.) по 205 байт.
Покурил - сделал кофе - вернулся, пол файла передало. но ошибок нет.

Попробуй тогда открывать порт в буферизованном режиме, т.е не использовать флаг Unbuffered (тут можно передавать неограниченное кол-во байт) и убрать вообще код где используются таймауты и т.п.
т.е смотри примеры в /test/guiapp(guiapp2)

ЗЫ:
А так - да, если читаешь из порта (открытого с флагом Unbuffered , как у тебя сейчас) то нужно использовать метод waitForReadyRead() , и т.п извращаться,
т.к. лимит по умолчанию в драйвере винды на 4096 байт (если не ошибаюсь) и нужно постоянно читать данные для того чтобы буфер драйера не переполнился.

В общем, используй буферизованный режим и будет всё ок.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 25.5.2011, 8:18
Сообщение #257


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

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




Репутация:   34  


Извиняюсь, что вклиниваюсь, но, по-моему, я совсем только что по таким граблям прошёл ) Дело было с драйвером фирмы FTDI, преобразователь USB<->COM

на небольших скоростях всё было хорошо, но когда прибор стал валить в USB порт очень толстый поток данных, драйвер стал подглючитваь и зависать. В конце концов всё решилось так: в отдельном потоке раз в 1 мс (при помощи мультимедийного таймера) вытаскиваю все данные в буфер (размер я могу, конечно же, задать произвольный. Это - рассчитать, сколько нужно). Если буфер переполняется, то новые данные откидываю - иначе у драйвера крышу сносит. В основном потоке по обычному виндовому таймеру выделяю осмысленные куски данных и вычищаю их из буфера. Естественно, операции работы с буфером - через критическую секцию.

Уже 4 дня после этих исправлений полёт нормальный, тьфу, тьфу, тьфу
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
good835
  опции профиля:
сообщение 3.6.2011, 13:45
Сообщение #258


Студент
*

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

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




Репутация:   0  


Добрый день!
После изменений в классе SerialDeviceEnumerator (SerialDeviceEnumerator reimplemented as a singleton.) программа стала подвисать при создании объекта класса (пример quiapp)
    if (!this->enumerator)
        this->enumerator = SerialDeviceEnumerator::instance();

грузит процессор сервис Service Control Manager (SCM) (\Windows\System32\Services.exe) - под 100% - идет поиск устройств?
после того как сервис отработает появляется окно программы. До изменений такой проблемы не было, с чем это может быть связано?
ОС: WindowsXP, QT 4.7.1. mingw
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuzulis
  опции профиля:
сообщение 3.6.2011, 15:01
Сообщение #259


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

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

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




Репутация:   7  


2 good835

Да не должно грузить, т.к. в принципе ничего не изменилось (кроме того что теперь SerialDeviceEnumerator является одиночкой).

Я только что проверил : у меня приложение /gui/test, собранное в релизе,
не подвисает (ну, загружает, процентов на 30% - но не на 100 как у вас.).

В принципе, это нормально, любые иные приложения тоже при старте грузят процессор.

ЗЫ: Хотя, может быть, это связано с тем, что вы в конструкторе выполняете метод: isBusy() ?
И если ДА - то может из-за него проблемы, т.к. если порт открыт и метод пытается его опять открыть - то этот процесс тормозит N-ное кол-во времени.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
good835
  опции профиля:
сообщение 7.6.2011, 16:26
Сообщение #260


Студент
*

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

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




Репутация:   0  


2 kuzulis

Разобрался я, почему грузит процессор. Как и предполагалось проблема была в методе SerialInfoMap SerialDeviceEnumeratorPrivate::updateInfo() const
   
static const ::GUID guidArray[] =
{
    /* Windows Ports Class GUID */
    { 0x4D36E978, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } },
    /* Virtual Ports Class GUIG (i.e. com0com, nmea and etc) */
    { 0xDF799E12, 0x3C56, 0x421B, { 0xB2, 0x98, 0xB6, 0xD3, 0x64, 0x2B, 0xC8, 0x78 } },
    /* Windows Modems Class GUID */
    { 0x4D36E96D, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }
};
   int guidCount = sizeof(guidArray);
   for (int i = 0; i < guidCount; ++i) {

       ::HDEVINFO DeviceInfoSet = ::SetupDiGetClassDevs(&guidArray[i],
                                                        0,
                                                        0,
                                                        DIGCF_PRESENT);
  ....

Собственно говоря ошибка была в определении длины цикла guidCount, что и приводило к некорректной работе при поиске инфо об устройстве. Должно быть так:
   int guidCount = sizeof(guidArray)/sizeof(::GUID);
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

44 страниц V  « < 24 25 26 27 28 > » 
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


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




RSS Текстовая версия Сейчас: 28.11.2024, 22:35