如何将数据发送到QT中打开的tty0tty null调制解调器模拟器端口
How to send data to tty0tty null modem emulator port opened in QT
我通过QSerialPort打开了与tty0tty nullmodem模拟器创建的模拟串行端口的工作连接,我可以向其写入数据,如:
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
但它不起作用。我很高兴得到你的帮助!
使用tty0tty-null调制解调器模拟器(v1.2)通过QSerialPort发送/读取数据
1。建立tty0tty-连接:
有两种方法可以建立tty0tty-连接(在两个虚拟端口之间)。这两种方式都可能需要内核头文件。对于2。这是绝对必要的,否则make时的错误是不可避免的。
(1.)捷径:
- 下载并提取tty0tty(标题中的第一个链接)
- 打开一个端子,
cd
到[Path to tty0tty-folder]/tty0tty/pts
- 执行
sudo ./tty0tty
然后应显示两个连接的伪终端从属设备:
具有X、Y变量的
(/dev/pts/X) <=> (/dev/pts/Y)
。
(2.)较长的方式(但或多或少是永久性的):
- 请遵循本安装指南
可能在引导之间持久化不起作用,因此有必要在重新启动后重复安装指南的以下部分:
- 加载模块
sudo depmod
sudo modprobe tty0tty
- 为新的串行端口(本地终端设备)授予适当的权限
sudo chmod 666 /dev/tnt*
执行ls /dev/tnt*
后,应显示端口列表:
/dev/tnt0 ... /dev/tnt7
2。测试tty0tty-连接是否有效(可选):
可以使用cat:测试连接
-
打开一个终端[1],并显示一个伪/本地终端设备的输出:
- (1.)
cat /dev/pts/X
或(2.)cat /dev/tnt0
- (1.)
-
打开另一个终端[2]并写入该伪/本地终端设备:
- (1.)
echo "message" > /dev/pts/Y
或(2.)echo "hello" > /dev/tnt1
- (1.)
输出应显示在终端[1]:中
message
其他信息:要停止cat,请按:Ctrl+Z
3。在Qt中使用QSerialPort打开终端设备作为端口-项目:
-
将串行端口-引用添加到
[projectname].pro
-文件中的Qt特定配置选项:QT += serialport
附加信息:允许将所有引用放在一行中:
即
QT+= core gui serialport ...
-
在所需的
[name].h
文件中添加所需的头文件:#include <QtSerialPort/QSerialPort>
-
添加两个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:可能需要在超级用户权限下执行编译后的代码:
- 编译代码
- 打开端子,
cd
到[Path to compiled project folder]/[projectname]
- 执行
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()
读取发送的数据。在这里,重要的是要知道,在通过QIODevice::write()
发送数据后,有必要使用bool QIODevice::waitForReadyRead(int msecs)
,否则它将不起作用。我还建议使用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.)有信号:
在类的构造函数中,可以使用QObject::connect()
:将专用时隙连接到readyRead()
信号
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();
...
}
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 如何在 c++ 中'NULL'字符串
- c++使用foreach使数组为null
- 当使用通配符和null指针调用函数时,对输出的说明
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 如何在映射中返回null
- 为什么返回 NULL 不会破坏函数?
- 构造函数中的 QQuickItem 父项 null
- 检查字符串是否"null" C++
- fopen 在 gdb 中返回 NULL
- what(): basic_string::_M_construct null not valid
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- 为什么在排序链表上的这种合并实现总是将两个列表都设置为 NULL,而只有一个应该设置一个列表?
- 为什么要从main()返回NULL?
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 当目标指针不是基类的类型时,为什么允许dynamic_cast为多态类生成 null 指针?
- 是否有通用方法可以找到任何以 null 结尾的字符串的长度?
- 为什么TinyXML2的XMLDocument::FirstChild()函数在尝试解析这个有效的XML文件时返回NULL?
- 使用 curl_easy_cleanup(curl) 时收到未经处理的 NULL 异常
- 如何将数据发送到QT中打开的tty0tty null调制解调器模拟器端口