URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 10449
[ Назад ]

Исходное сообщение
"Проблема обмена данными через виртуальный USB-com порт"

Отправлено EdiRu , 02-Авг-23 17:31 
Добрый день! Жизнь заставила переходить с виндов на Linux, столкнулся с проблемой: работаю с железкой по USB через виртуальный ком-порт в Qt Creator. В консольном приложении всё идет на "ура", так же если делаю библиотеку и вызываю через консольное приложение - железка получает команды и отвечает как надо. Попытка использования оконного приложения или "даблклика" по файлу консольного приложения без запуска терминала приводит к тому, что функция read, возвращая нужное количество прочитанной информации, возвращает массив заполненный нулевыми значениями (0х00). Пробовал менять тип массива с char на wchar_t, все равно и старшие и младшие байты нули. Может кто чего подскажет? Примерная последовательность действий:

    int fd = open("/dev/ttyACM0", O_RDWR);
    if (fd < 0) { // обработка ошибок сокращена    }
    fcntl(fd, F_SETFL, 0);
    struct termios oldsettings, newsettings;
    tcgetattr(fileno(stdin), &oldsettings);
    newsettings = oldsettings;
    cfsetospeed(&newsettings, B4000000);
    cfsetispeed(&newsettings, B4000000);
    newsettings.c_lflag &= ~(PARENB|CSTOP|CSIZE);
    newsettings.c_lflag |= CS8;
    newsettings.c_cc[VMIN] = 0;
    newsettings.c_cc[VTIME] = 10;
    newsettings.c_ispeed = 12000000;
    newsettings.c_ospeed = 12000000;
    if (tcsetattr(fd, TCSANOW, &newsettings) < 0) {// обработка ошибок сокращена }

    char buf[50];
    char bufin[2048];
    tcflush(fd, TCIOFLUSH);
    int rP, crd;
// заполнение буфера сокращено, rP=длина буфера
    int cnt = write(fd, &buf, rP);
// обработка ошибок сокращена
    timeval timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = 100000;
    fd_set fs;
    FD_ZERO(&fs);
    FD_SET(fd, &fs);
    int res = select(fd+1, &fs, NULL, NULL, &timeout);
    if(res==0) {// обработка ошибок сокращена }
    else if(res<0) {// обработка ошибок сокращена }
    else if(FD_ISSET(fd, &fs))
    {
       memset(bufin, 0x00, sizeof(bufin));
       crd = 20; // устанавливаем с запасом, т.к. заранее не знаем, сколько придет
       cnt = read(fd,&bufin,crd);
// cnt = 19 - пришло сколько нужно, bufin[0] = 0x00, bufin[1] = 0x00 и т.д.


Содержание

Сообщения в этом обсуждении
"Проблема обмена данными через виртуальный USB-com порт"
Отправлено ACCA , 02-Авг-23 20:46 
[...]
>     tcgetattr(fileno(stdin), &oldsettings);

Ты взял атрибуты из STDIN. Терминальный эмулятор делал какие-то stty, которые ты сам не делаешь.
Посмотри, чего не хватает, заполни сам свой newsettings, без подглядывания в stdin на лету.


Вообще, код получился очень хрупкий, так с COM-портом не работают.

read может вернуть вообще 1 байт. Ну, очень шустрый у тебя процессор и успел уловить с помощью select что что-то пришло, потом read это "что-то" поймал, потом ещё что-то будет, но об этом никто не узнает.


Посмотри лучше пример с ~ICANON и без select: https://stackoverflow.com/questions/2917881/how-to-implement...


"Проблема обмена данными через виртуальный USB-com порт"
Отправлено EdiRu , 03-Авг-23 01:40 
> Ты взял атрибуты из STDIN. Терминальный эмулятор делал какие-то stty, которые ты
> сам не делаешь.

Спасибо огромное посмотрел что прописывает STDIN, скопировал - всё заработало. Причем раньше читал про подобные ошибки начинающих, но забыл)) Про остальное - еще буду дорабатывать, главное обмен пошел.