基于Linux的Qt串口服务器设计

2016-09-18 08:46赵仁涛田晓晓曹慧芳
山西电子技术 2016年4期
关键词:服务器端串口嵌入式

赵仁涛,田晓晓,曹慧芳

(北方工业大学 机械与材料工程学院,北京 100144)



基于Linux的Qt串口服务器设计

赵仁涛,田晓晓,曹慧芳

(北方工业大学 机械与材料工程学院,北京 100144)

串口通信广泛运用在工业自动化,串口与TCP/IP网络的结合能够实现远程控制以及数据采集等功能。本文基于Linux环境,利用Qt Create设计了串口服务器,实现了串口到以太网的数据转发功能,并给出了程序的设计要点。最后利用交叉编译器将其移植到嵌入式系统平台上。

Linux;Qt Create;串口;TCP/IP网络;嵌入式系统

大多数工业设备都采用串口通信方式,但是串口不具备远程数据传输能力,所以有必要设计一种中间软件将串口通信转化为网络通信。既兼顾了工业设备的串口通信,又可以通过网络实现远程控制和数据传输。

近年来,随着嵌入式系统的发展,这种中间设备的开发变的简单,易行。在嵌入式Linux系统中串口通信和网络编程都是通过具体的API接口实现,而Qt把有关的数据结构和函数都封装成类,实现了很大程度的模块化,使软件的开发变的简洁,高效,使用开发十分便利。

1 串口通信设计

串口是一种常见的通用协议,也是仪器仪表设备的通用协议,串口协议在工业中的使用十分广泛。串口通信十分简单:按位发送和接收字节,虽然相比并行通信慢,但是串口可以同时接收和发送消息。

1.1串口通信的几个重要指标

在串口通信中重要的参数有波特率,数据位,停止位,奇偶校验位。对于串口开发来说,通过串口连接的设备这些参数是必须设置成匹配的。

1) 波特率:衡量符号传输速率的参数,代表每秒传输的比特数。

2) 数据位:表示通信中实际数据的位数。设置数据位参数时,应当按照实际传送的数据类型来选择相应的位数。

3) 停止位:用于表示单个包的最后一位,说明该信息包数据完成,典型值为1,1.5,2位。在通信的两台设备出现了时钟不同步的情况下,给设备一个校正时钟同步的机会。

4) 奇偶校验位:是一种检错方式通过设置校验位,确保传输的数据有偶数个或奇数个逻辑高位。

1.2在Linux系统下使用Qt实现串口通信

Qt是1991年由奇趣科技开发的跨平台C++图形用户界面应用程序开发框架[1]。Qt采用信号与槽的方式来实现对象间的通讯,这种设计简化了程序,避免了大量的指针工作,为编写程序节省了大量的空间。Qt Create可以拖拽控件进行控件布局进行界面的设计[2]。由于Qt是跨平台开发工具的开源项目,所以可以在PC机上编写好Qt的应用程序,然后通过交叉编译,生成在开发板上运行的程序。

由于Qt并没有特定的串口控制类,如果用Qt编写串口程序一般使用Stefan Sander和Michal Policht编写的第三方QextSerialPort类,该类封装了可移植操作系统接口(POSIX)和Windows系统接口[3]。在posix_qextserialport.cpp,posix_qextserialport.h文件中定义了Posix_QextSerialPort类,qextserialport.cpp和头文件定义了QextSerialPort类。Posix_QextSerialPort类添加了Linux平台下操作串口的功能。

在QextSerialBase类中有一个枚举变量QueryMode,可以取两个值Polling和EventDriven。EventDriven是采用事件驱动处理串口读取,一旦串口有可读取的数据,就会发出readyRead()信号,在Windows可以为该信号创建槽函数去读取串口的消息,但是在Linux下只支持Polling查询方式。Polling模式查询是使用轮询的方法查询串口,需要开发人员自己建立定时器来读取串口数据。

1.3利用Qt Create实现串口通信

首先创建工程tcp_serial,将解压的文件添加到工程中,添加Posix_qextserialport.h头文件到mainwindow.h文件中,然后添加私有对象:Posix_QextSerialPort *myttyS1;由于 Linux只能使用Polling查询模式,所以还需要添加定时器QTimer *readTimer;私有对象为读取串口数据发送超时信号。

为连接serial按键添加私有槽函数void serial_clicked();为disserial按键添加私有槽函数void disserial_clicked();为读取串口数据添加私有函数void readmyttyS1()。

在mainwindow的构造函数中添加设置串口参数的代码(产生serial_clicked信号时完成):

1) 指定操作的串口对象和Polling查询模式

myttyS1 = new

Posix_QextSerialPort(“/dev/ttyS0”,QextSerial

Base::Polling);

2) 打开并设置串口参数

myttyS1->open(QIODevice::ReadWrite);

3) 打开串口

myttyS1->setBaudRate(BAUD115200);

4) 设置波特率为115200

myttyS1->setDataBits(DATA_8);

5) 设置数据位为8

myttyS1->setParity(PAR_NONE);

6) 设置无校验

myttyS1->setStopBits(STOP_1);

7) 设置停止位为1

disserial_clicked();

最后,使用myttyS1->close()函数关闭串口。

创建读取串口的槽函数

connect(readTimer,SIGNAL(timeout()),this,SLOT(readmyttyS1()));

readmyttyS1()函数利用myttyS1->readAll();语句读取串口缓冲区的所有数据。如果需要向串口写数据可以使用myttyS1->write();即可向串口写入数据。

串口工作流程图如图1。

图1 串口工作流程图

通过上面的设计可在Linux环境下完成对串口的读取功能。

2 基于TCP/IP的以太网通信设计

基于TCP/IP协议的以太网应用十分广泛。利用TCP/IP可以进行可靠的网络通信。TCP/IP实际上是一组协议族,分别为传输层协议,网络层协议,每种协议都提供不同的功能,在网络层下的IP协议提供了基本的命名方法和传送机制,通过对数据包添加IP协议头能够使该数据从一台因特网主机往其他主机发包(数据报)。在传输层的TCP协议是构建在IP之上的复杂协议,提供了进程间可靠的全双工连接,通过“三次握手”为网络传输数据提供更加可靠安全的服务。

2.1Linux网络通信

Linux通过套接字实现网络通信。大多数现代系统上都实现了套接字接口,通过套接字接口实现C/S模型如图2所示。

客户端首先使用Socket()函数创建一个套接字接口,调用connect()函数与服务器连接就可以通过网络接收和发送数据了。当完成了接收和发送数据最后关闭程序。

服务器端也是通过使用Socket()函数创建一个套接字接口,然后使用bind()函数将网络地址和端口号绑定在该套接字接口上,通过使用listen()函数将创建的主动套接字转化成监听套接字,accept()函数用来接收客户端的连接请求,成功时返回一个已连接描述符,通过对已连接描述符的读写就可以实现网络通信。完成通信后只要close已连接描述符就可以断开与服务器的连接了。

图2 服务器-客户端模型示意图

2.2基于Qt的网络通信

QT中提供了QTcpSocket的类和QTcpServer的类编完成网络编程,QTcpSocket用来编写客户端程序,QTcpServer类用来编写服务器端的程序。

QTcpSocket用来传输数据流的,尤其适合连续的数据传输。在进行数据传输前,需要建立网络连接,通过connectToHost()函数与服务器进行连接。如果连接成功会返回一个connected()信号。连接成功后就可以进行读写操作了。当有新的数据到达时就会收到readyRead()信号。将该信号与读取信息的槽函数相连就可以实现客户端的信息接收功能。

QTcpServer用来建立服务器。首先进行端口的监听,当有连接请求时会收到newConnection()信号,关联该信号的槽函数建立连接。一旦有来自客户端的数据就会发出readyRead()信号,关联该信号进行数据的接收或根据接收的数据进行其他操作。

2.3服务器端实现

创建tcp_server工程在mainwindow.h中添加私有对象QTcpServer *tcpServer作为监听套接字,添加私有对象QTcpSocket *serverConnect当连接后,将连接交给这个对象,由它完成数据传输工作。

添加私有槽函数void acceptConnection()函数,当有新的连接时接受该连接。添加私有槽函数void startButton_clicked()函数,使tcpServer开始监听。添加私有槽函数void disconnect_clicked()函数,关闭tcpServer。

在构造函数中完成初始化:

关联newConnection()信号与槽函数acceptConnection(), connect(&tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));

acceptConnection()函数中使用serverConnect=tcpServer.nextPendingConnection()函数将网络连接交给QTcpSocket对象处理。同时在已连接的后设置readyRead()信号的槽函数connect(serverConnect,SIGNAL(readyRead()),this,SLOT(getMessage()));

getMessage()函数使用serverConnect->readAll()函数读取客户端发送的数据。

开始和结束按键槽函数实现

void startButton_clicked()函数使用tcpServer.listen()函数实现监听。

void disconnect_clicked()函数使用tcpServer.close()函数关闭服务器。

如果要向客户端发送数据可以使用

QTextStream os(serverConnect);

os<write()发送数据。

服务器端的流程图如图3。

图3 服务器端工作流程图

通过图3的流程图与之前的分析。可以创建服务器端,使其可以监听网络连接,当有网络连接请求时接受连接请求,并进行数据的接收和发送。

3 功能验证

在虚拟机的环境下创建两个串口设备,用以进行串口通信,连接选项选择使用命名的管道,管道名都为.pipecom_1。ttyS2设置成服务器,ttyS1设置成客户端,另一端都为虚拟机。用于连接的服务器ip使用的是Linux下的回环

ip地址127.0.0.1,端口使用的是8888。这样串口通信环境和以太网通信环境都已经建立。下图为使用Qt编写客户端,服务器的图形应用程序运行效果。运行服务器程序和客户端程序,测试前在服务器程序上打开串口,使服务器处于监听状态,客户端连接至服务器。然后打开终端在终端输入echo “123abc”>/dev/ttyS2就可以在服务器和客户端看到下面的效果,服务器通过串口接收到了”123abc”,通过以太网发送给了客户端,然后在客户端的窗口显示出来。

客户端与服务器端运行效果如图4所示。

图4 运行效果图

综上所述该方法可以实现串口与网口的通信。在实际情况下嵌入式系统利用其体积小,能耗低等特点在工控领域占据了越来越重要的位置。通过Qt编写的程序利用交叉编译器可以生成在嵌入式平台上运行的程序[4]。在PC机上编译Qt/E的库文件,将Qt/E的库放在根文件系统后,就可以在嵌入式平台上运行设计的服务器。

4 结束语

本文介绍了在Linux环境下通过Qt create编程,实现了读取串口数据,并通过以太网转发串口数据的基本功能,并完成了ARM平台上的程序移植,且在PC机上运行证明本程序可以完成数据转发的功能。

[1]张新村,严殊.基于ARM的Linux系统下Qt串口助手的设计[J].软件导刊,2011(8):64-66.

[2]陈静.基于Ubuntu13.04系统下QT串口通信设计[J].电子世界,2014(18):244.

[3]杨都,赖东锋,肖焕明,等.基于ARM-Linux-Qt的空调集中控制系统设计[J].日用电器,2015(8):184-186.

[4]王浩南,刘益成.基于嵌入式Linux系统下的Qt开发[J].电脑开发与应用,2010(1):11-13.

[5]梅小龙.基于Linux/QT的嵌入式管理系统的开发[D].南京:南京信息工程大学,2014.

Design of Qt Serial Port Server Base on in Linux OS

Zhao Rentao, Tian Xiaoxiao, Cao Huifang

(MechanicalEngineeringDepartment,NorthChinaUniversityofTechnology,Beijing100144,China)

Serial communication is widely utilized in industrial automation, and the remote control and data acquisition can be realized with the combination of serial and TCP/IP network. A serial server is designed via Qt Create under the Linux OS in the thesis to transmit the data information from serial to Ethernet, and the key of the program is presented. Besides, the program is transported to Embedded System by Cross Compiler.

Linux; Qt Create; serial communication; TCP/IP network; embedded system

2016-05-10

赵仁涛(1970- ),男,副教授,博士研究生,主要从事数据处理与系统识别。

1674- 4578(2016)04- 0063- 03

TP 31

A

猜你喜欢
服务器端串口嵌入式
浅谈AB PLC串口跟RFID传感器的通讯应用
Linux环境下基于Socket的数据传输软件设计
搭建基于Qt的嵌入式开发平台
浅析异步通信层的架构在ASP.NET 程序中的应用
基于Qt的安全即时通讯软件服务器端设计
嵌入式软PLC在电镀生产流程控制系统中的应用
数字电源内部数据传输的串口通信方法实现
USB接口的多串口数据并行接收方法探索
基于蓝牙串口适配器的GPS接收机与AutoCAD的实时无线通信
Altera加入嵌入式视觉联盟