The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



"Проблема обмена данными через виртуальный USB-com порт"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"Проблема обмена данными через виртуальный USB-com порт"  +/
Сообщение от EdiRu (ok), 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 и т.д.

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения [Сортировка по ответам | RSS]

1. Сообщение от ACCA (ok), 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...

Ответить | Правка | Наверх | Cообщить модератору
Ответы: #2

2. Сообщение от EdiRu (ok), 03-Авг-23, 01:40   +/
> Ты взял атрибуты из STDIN. Терминальный эмулятор делал какие-то stty, которые ты
> сам не делаешь.

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

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #1


Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру