Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > [Qt 3.3] Не работает чтение из последоват. порта


Автор: Tiffany 14.5.2008, 12:43
Не могу понять в чем дело. Смысл таков - надо послать одному устройству команду через послед. порт и получить ответ от устройства. Команда посылается и устройство её норм обрабатывает, потом оно должно отослать ответ и я его должна прочитать. Но при чтении (разными методами) прога либо виснет, либо вылетает, либо функция чтения возвращает ошибку.

Код

bool TRemoteControl::DeviceCOMMOpen(QString PortName)
{
     char buf[255];
     QFile f1;
     f1.setName(PortName); /* /dev/ttyM3   */

    struct termios newtio;

    if (!f1.open(IO_Raw | IO_ReadWrite)) 
    {
           ErrorCode = 0x0001;
           return false;
    }
    
    tcgetattr(f1.handle(), &newtio);

    newtio.c_cflag |= (CLOCAL | CREAD);
            newtio.c_cflag |= PARENB;
    newtio.c_cflag &= ~PARODD; 
    newtio.c_cflag &= ~CSTOPB;
    newtio.c_cflag &= ~CSIZE;
    newtio.c_cflag |= CS8;
    newtio.c_lflag |= ICANON;         
    newtio.c_iflag|=(INPCK | ISTRIP);
    newtio.c_oflag = 0;
    
    
    fcntl(f1.handle(), F_SETFL, FNDELAY);    

      cfsetispeed(&newtio, B9600);
      cfsetospeed(&newtio, B9600);
      

            tcsetattr(f1.handle(),TCSANOW,&newtio);

    ErrorCode = 0x0000;
    DeviceHandle = f1.handle();
    
            buf[0] = 0x3f;
            buf[1] = 0x03;
            f1.writeBlock(buf, 2);                      // посылаю команду на запрос статуса устройства

            f1.readBlock(buf, sizeof(buf));        /* чтение ответа от устройства - здесь прога виснет (или     readBlock возвращает -1) */

  return true;
}


В строке "f1.readBlock(buf, sizeof(buf));" пробовала и по другому: "read(f1.handle(), buf, sizeof(buf))" - тотже результат; "buf[0]=f1.getch()" - возвращает "-1".  smile 

Есть какие-нибудь мысли?  smile 


P. S. Правда в другой программе у мну норм читались ответы, тока они шли от другого ПК. Это было что-то типа миничата через послед. порты =) Настройки порта там конечно были другие, но и в этой программе (с устройством) я пыталась сделать следующий финт ушами - пишим команды с теми настройками что указаны вверху, а когда надо получать ответ, запускаем другой поток для чтения который устанавливает те настройки, с которыми работало чтение в чате, читает (должен был бы) ответ и возвращает обратно настройки для записи  smile 
Но и в таком варианте тот же эффект =(
Мож дело и не в настройках порта... хз ...  smile 

Автор: JackYF 14.5.2008, 14:51
Tiffany, а Qt здесь при чём? Тебе не в юникс-программирование случайно?

Автор: chaos 15.5.2008, 08:51
Tiffany
а почему ты юзаешь QFile ?
разве QFile использует низкоуровневые функции open, close, read, write ? Даже если это так, то все равно опастно этим пользоваться - трроли однажды изменят внутреннию реализацию QFile на какие-нибудь стримы и все.
мой тебе совет исполльзовать функции приведенные выше.

ЗЫ  
чуть-чтуь бы еще изменил код твой, те настройку порта
Код

newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
newtio.c_oflag &= ~OPOST;


Автор: Tiffany 15.5.2008, 13:11
chaos, угу, терь вроде все норм с такими настройками (правда проверить на устройстве смогу наверно только завтра, а сейчас проверяла между 2я компами - работает, и судя по com-монитору - настройки те что надо). Завтра узнаю наверняка. А QFile использовала потому, что обычный open тупо вылетает с ошибкой  smile  Вот када пишешь в каком-нить vim-e просто пару строк с open-ом - все норм, файл открывается. А када компилишь и запускаешь из ПС "Конструктор" под МСВС - вылетает с ошибкой, а QFile работает. Вобщем просто неохота было разбираться с этой тупостью и сделала через QFile. Вот када буду убеждена, что работает чтение от устройсва - мб переделаю на open и т.д.  smile 

А кстати... я же QFile использовала, только чтобы открыть порт, а читать\писать то всеравно можно обычными read\write:

Код

read(f1.handle, buf, sizeof(buf));
write(f1.handle, buf, sizeof(buf));


Это должно быть равносильно использованию этих функций с дескриптором полученным от open.

Автор: chaos 16.5.2008, 08:04
Цитата(Tiffany @ 15.5.2008,  10:11)
А QFile использовала потому, что обычный open тупо вылетает с ошибкой

я же QFile использовала, только чтобы открыть порт, а читать\писать то всеравно можно обычными read\write:

Код

read(f1.handle, buf, sizeof(buf));
write(f1.handle, buf, sizeof(buf));


Это должно быть равносильно использованию этих функций с дескриптором полученным от open.

1. c какой ошибкой
2. Если QFile обертка для функция опен, клосе, рид, врайт то да, "можно" использовать, но я бы не стал smile

Автор: Tiffany 16.5.2008, 08:33
chaos
Цитата

1. c какой ошибкой


Та вот уже и непомню с какой. Помню что просто закрывается окно на "open" молча и все. Ну уже не суть. Пока все работает. Проблема с чтением решилась тоже довольно неадекватными действиями  smile  Было как: в отдельном файлике (.h) класс потока (от QThread), в нем инклудился класс для работы с устройством из другого файлика. Из этого класса что-то нечиталось никак. Потом просто скопипастили чтение в основной файлик (ну типа form0.ui.h) и все норм читается. Вобщем похихикали над этой парапсихологией и пока закрыли глаза на это дело. Ща вот допишем функциональную часть и потом будем приводить все в порядок. А так - вопрос можно считать решенным  smile 

Автор: Ken 17.5.2008, 18:25
Там у вас стоит опция:

Код

newtio.c_lflag |= ICANON;


В документации написано:

       In canonical mode:

       * Input  is made available line by line.  An input line is available when one of the
         line delimiters is typed (NL, EOL, EOL2; or EOF at the start of line).  Except  in
         the case of EOF, the line delimiter is included in the buffer returned by read(2).

Т.е. пока полная строка с символами конца строки не придет, вы не получете ничего. Вы, как раз, установили этот режим. Что посылает устройство?

Автор: Tiffany 22.5.2008, 15:00
Ken, та работает уже все. Написано же - вопрос решенный.

Автор: Oligarch 11.4.2009, 09:30
Помогите пожалуста.
Почему то при чтении из порта при помощи команды read(), читается не больше 14 символов, сколько бы я не указывал читать в последнем параметре read(). Вот код конфигурации порта и чтения из него:

Код

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>

int main(void)
{
    int oldflags,fdDK ;
    unsigned char temp;
    char out[10],in[50];
    struct termios termios_struct;

//Конфигурирование порта
    fdDK = open("/dev/ttyM0",O_RDWR|O_NOCTTY);         /*ttyM0 - имя файла порта RS-485 (MOXA CP-132IS)*/
    oldflags = fcntl (fdDK, F_GETFL, 0);
    oldflags&=~O_NONBLOCK;
    fcntl (fdDK, F_SETFL, oldflags);

    tcgetattr(fdDK,&termios_struct);
    termios_struct.c_cflag|=(CLOCAL|CREAD);
    cfsetispeed(&termios_struct,B38400);
    cfsetospeed(&termios_struct,B38400);
    termios_struct.c_cflag&=~PARENB;
    termios_struct.c_cflag&=~CSTOPB;
    termios_struct.c_cflag&=~CSIZE;
    termios_struct.c_cflag|=CS8;
    termios_struct.c_lflag&=~(ICANON | ECHO | ECHOE | ISIG );
    termios_struct.c_iflag|=(INPCK | ISTRIP);
    termios_struct.c_iflag&=~IXON&~IXOFF&~IXANY&~ICRNL;
    termios_struct.c_oflag&=~OPOST;
    termios_struct.c_cc[VMIN]=0;
    termios_struct.c_cc[VTIME]=10;
    tcsetattr(fdDK,TCSANOW,&termios_struct);
    //Очистка входного буфера порта
    while(read(fdDK,&temp,1));

//Обмен                
    sprintf(out,"$02K\r");
    if(write(fdDK,out,5)<0)return 0;
    read(fdDK,in,40);
    printf("%s\n",in);
    close(fdDK);
    return 1;
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)