Как отправить данные на порт эмулятора нуль-модема tty0tty, открытый в QT

У меня открытое рабочее соединение с эмулируемым последовательным портом, созданным с помощью эмулятора tty0tty nullmodem через QSerialPort, и я могу записать в него данные следующим образом:

QSerialPort serial_stream;
...
serial_stream.setPortName(QString("/dev/tnt0"));
bool loc = serial_stream.open(serial_stream.ReadWrite)
...
serial_stream.write(buf);

Я открываю терминал и устанавливаю соединение с подключенным (в данном случае tnt1) tnt-портом (например, tnt0 <-> tnt1 подключены) через «экран»:

screen /dev/tnt1

Когда я запускаю программу, я получаю ожидаемый ввод (здесь «buf») на экране. Но как я могу отправить данные обратно на открытый порт в Qt, чтобы я мог сделать следующее для чтения данных:

int size = serial_stream.bytesAvailable();
QByteArray data = serial_stream.read(size);

Я уже пытался остановить программу с помощью «сна» …:

#include <unistd.h>
...
usleep(15*1000000);

…и отправьте данные ему так:

echo “TEXT“ > /dev/tnt1

Но это не работает. Я рад за вашу помощь!

0

Решение

1. Создайте tty0tty-соединения:

Двумя способами можно создать tty0tty-соединение (между двумя виртуальными портами). Оба способа могут потребовать заголовочные файлы ядра. Для 2. это определенно необходимо, иначе ошибка в то время как делать неизбежно

(1.) Короткий путь:

  1. Скачать и извлечь tty0tty (первая ссылка в заголовке).
  2. Откройте терминал и cd в [Path to tty0tty-folder]/tty0tty/pts
  3. казнить sudo ./tty0tty

Тогда два связаны псевдо-терминальные рабы должно быть показано:

(/dev/pts/X) <=> (/dev/pts/Y) с переменной X, Y.

(2.) более длинный путь (но более или менее постоянный):

  1. Следить за этим Инструкция по установке

Может быть сохраняется через сапоги не работает, поэтому необходимо повторить следующие части Инструкция по установке после перезагрузки:

  1. Загрузите модуль
    • sudo depmod
    • sudo modprobe tty0tty
  2. Дать соответствующие разрешения новым последовательным портам (родные терминальные устройства)
    • sudo chmod 666 /dev/tnt*

После выполнения ls /dev/tnt* список портов должен быть показан:

/dev/tnt0 ... /dev/tnt7

2. Проверьте, если tty0tty-подключение работает (опционально):

Соединение может быть проверено с кошка:

  1. Откройте терминал [1] и позвольте показать вывод одного псевдо / родное терминальное устройство:

    • (1.)cat /dev/pts/X или (2.)cat /dev/tnt0
  2. Откройте другой терминал [2] и напишите в него псевдо / родное терминальное устройство:

    • (1.)echo "message" > /dev/pts/Y или (2.)echo "hello" > /dev/tnt1

Вывод должен быть показан на клемме [1]:

message

Дополнительная информация: Прекратить кошка Нажмите: Ctrl + Z

3. Откройте терминальные устройства как порты с QSerialPort в Qt-Проект:

  1. Добавить последовательный порт-ссылка на Qt-специфичные параметры конфигурации в [projectname].pro-файл:

    QT += serialport

    Дополнительная информацияРазрешено помещать все ссылки в одну строку:

    то есть QT+= core gui serialport ...

  2. Добавить обязательно заголовочный файл в желаемом [name].h-файл:

    #include <QtSerialPort/QSerialPort>

  3. Добавьте два QSerialPort-объекты, установите путь оконечные устройства с помощью void QSerialPort::setPortName(const QString &name) и открыть порты через bool QSerialPort::open(OpenMode mode) с желаемыми разрешениями (ReadOnly, WriteOnly, ReadWrite). Пример:

        std::string tty0ttyPort1 = "/dev/tnt0";// or = "/dev/pts/X
    std::string tty0ttyPort2 = "/dev/tnt1";// or = "/dev/pts/Y
    QSerialPort qport1;
    QSerialPort qport2;
    qport1.setPortName(QString(tty0ttyPort1.c_str()));
    bool isOpen1 = qport1.open(qport1.ReadWrite);//Read and Write permission
    std::cout << "isOpen1: " << isOpen1 << std::endl;
    qport2.setPortName(QString(tty0ttyPort2.c_str()));
    bool isOpen2 = qport2.open(qport2.ReadWrite);
    std::cout << "isOpen2: " << isOpen2 << std::endl;
    

isOpen1 а также isOpen2 должно быть true:

isOpen1: 1
isOpen2: 1

Дополнительная информация 1: Возможно, требуется выполнить скомпилированный код с разрешением суперпользователя:

  1. Скомпилируйте Кодекс.
  2. Откройте терминал и cd в [Path to compiled project folder]/[projectname]
  3. казнить sudo [executable_file] или запустить как супер пользователь su (Нецелесообразной)

Дополнительная информация 2: Если появляется следующее предупреждение …:

QSocketNotifier: Can only be used with threads started with QThread

…здесь нет Цикл событий Qt который всегда должен быть в main()-функции:

int main(int argc, char *argv[]){
QCoreApplication a(argc, argv);
//My Testcode (Showed above in section 3.3)
return a.exec();
}

4. Используя открытый QSerialPorts:

(1.) Без сигналов:

использование qint64 QIODevice::write(const char * data) писать от одного QSerialPort другому. использование qint64 QIODevice::read(char * data, qint64 maxSize) или же QByteArray QIODevice::readAll() читать отправленные данные. Здесь важно знать, что нужно использовать bool QIODevice::waitForReadyRead(int msecs) после отправки данных через QIODevice::write() иначе это не будет работать. Я рекомендую также использовать bool QIODevice::waitForBytesWritten(int msecs). Пример:

    const char* sendMessage = "myMessage";
std::cout << "sendMessage: " << sendMessage << std::endl;
qport1.write(sendMessage);
qport1.waitForBytesWritten(2000);
qport2.waitForReadyRead(2000);//required
const char* readMessage = qport2.readAll().data();
std::cout << "readMessage: " << readMessage << std::endl;

Должен дать вывод:

readMessage: myMessage

Если необходимо прочитать определенное количество байтов, используйте QIODevice::read():

    const char* readMessage = qport2.read(5);
std::cout << "readMessage: " << readMessage << std::endl;

Должен дать вывод:

readMessage: myMess

Дополнительная информация: Чтобы проверить, сколько байтов доступно для чтения, используйте qint64 QIODevice::bytesAvailable() const. Пример:

std::cout << qport2.bytesAvailable() << std::endl;

(2.) с сигналами:

В конструкторе класса можно подключить приватный слот к readyRead() использование сигнала QObject::connect():

Classname::Classname(){
...
QObject::connect(&qport1, SIGNAL(readyRead()), this, SLOT(myPrivateSlotFunction()));
//with "qport1" as sender and "this" as receiver
}

...

Classname::myPrivateSlotFunction(){
...
const char* readMessage = qport1.readAll().data();
...
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]