Qt在工业上的使用场景包括工业自动化、嵌入式系统、汽车行业、航空航天、医疗设备、制造业和物联网应用。Qt被用来开发工业设备的用户界面、控制系统、嵌入式应用和其他工业应用,因其跨平台性和丰富的功能而备受青睐。
Qt能够为工业领域带来什么好处: - Qt提供了强大的图形引擎,使开发人员能够创建具有吸引力和高性能的用户界面 - Qt允许开发人员根据具体需求定制用户界面和功能。这对于满足不同行业和项目的独特需求至关重要,使工业应用能够实现个性化的解决方案 - Qt提供了丰富的库和工具,涵盖了各种应用程序开发需求,包括图形、网络通信、多媒体处理、数据存储等。这简化了工业应用程序的开发流程 - Qt可以轻松与各种硬件设备和通信协议集成,这对于工业自动化和控制系统来说非常重要,因为它们需要与各种传感器、执行器和其他工业设备进行通信
创龙科技基于全志双核Cortex-A7@1.2GHz处理器T113-i,精心设计的全国产工业开发板,它提供了Qt的运行环境,可以让我们快速的部署工业领域的用户交互界面,控制系统等。
接下来我们来聊聊如何在创龙科技T113-i工业开发板上部署Qt应用。
rice@rice:~$ mkdir t113 //创建t113工作目录,然后将压缩包拷贝到此目录
rice@rice:~$ cd t113
....
rice@rice:~/t113$ tar -zxvf SDK-T113-i_v1.0.tar.gz
rice@rice:~/t113$ cd T113-i_v1.0/
rice@rice:~/t113/T113-i_v1.0$ ls
brandy buildroot device install_tools.sh out rtos-dsp tools
build build.sh kernel platform test
rice@rice:~/t113/T113-i_v1.0$ ./install_tools.sh
[sudo] password for rice:
Reading package lists... Done
Building dependency tree
Reading state information... Done
texinfo is already the newest version (6.5.0.dfsg.1-2).
0 upgraded, 0 newly installed, 0 to remove and 121 not upgraded.
Reading package lists... Done
Building dependency tree
Reading state information... Done
pkg-config is already the newest version (0.29.1-0ubuntu2).
0 upgraded, 0 newly installed, 0 to remove and 121 not upgraded.
Reading package lists... Done
......
rice@rice:~/t113$ tar -xvf dl.tar.gz -C ~/t113/buildroot/buildroot-201902/
rice@rice:~/t113/T113-i_v1.0$ ./build.sh distclean
rice@rice:~/t113/T113-i_v1.0$ ./build.sh config
Welcome to mkscript setup progress
All available platform:
0. linux
Choice [linux]: 0
All available linux_dev:
0. bsp
1. dragonboard
2. longan
3. tinyos
Choice [longan]: 2
All available kern_ver:
0. linux-5.4
Choice [linux-5.4]: 0
All available ic:
0. t113
1. t113_i
Choice [t113_i]: 1
All available board:
0. evb1
1. evb1_auto
2. evb1_auto_nand
3. evb1_auto_nor
4. tlt113-evm-emmc
5. tlt113-evm-nand
6. tlt113-minievm-emmc
7. tlt113-minievm-nand
Choice [tlt113-evm-nand]: 5
All available output_configs:
0. hdmi
1. lvds-lcd
2. mipi-lcd
3. tft-lcd
4. cvbs
Choice [hdmi]: 0
All available flash:
0. default
1. nor
Choice [default]: 0
All available build_root:
0. buildroot-201902
1. ubuntu
Choice [buildroot-201902]: 0
All available gnueabi:
0. gnueabi
1. gnueabihf
Choice [gnueabi]: 0
rice@rice:~/t113/T113-i_v1.0$ source ./build/envsetup.sh
rice@rice:~/t113/T113-i_v1.0$ ./build.sh
ACTION List: mklichee;========
Execute command: mklichee
INFO: ----------------------------------------
INFO: build lichee ...
INFO: chip: sun8iw20p1
INFO: platform: linux
INFO: kernel: linux-5.4
INFO: board: tlt113-evm-nand
INFO: output: /home/rice/t113/T113-i_v1.0/out/t113_i/tlt113-evm-nand/longan
INFO: ----------------------------------------
INFO: build buildroot ...
Prepare br toolchain gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabi.tar.xz...
make: Entering directory '/home/rice/t113/T113-i_v1.0/buildroot/buildroot-201902'
...
rice@rice:~/t113/T113-i_v1.0$ ./build.sh qt
ACTION List: mkqt;========
Execute command: mkqt
INFO: build Qt ...
INFO: build arm-linux-gnueabi version's Qt
/home/rice/t113/T113-i_v1.0/platform/framework/qt/qt-everywhere-src-5.12.5
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
.....
rice@rice:~/t113/T113-i_v1.0$ ./build.sh pack
ACTION List: mkpack ;========
Execute command: mkpack
INFO: packing firmware ...
INFO: Use BIN_PATH: /home/rice/t113/T113-i_v1.0/device/config/chips/t113_i/bin
copying tools file
copying configs file
copying product configs file
/home/rice/t113/T113-i_v1.0/out/pack_out/aultls32.fex
/home/rice/t113/T113-i_v1.0/out/pack_out/aultools.fex
/home/rice/t113/T113-i_v1.0/out/pack_out/boot_package.cfg
/home/rice/t113/T113-i_v1.0/out/pack_out/boot_package.fex
......
dsp0.fex Len: 0x3fc78
Vdsp0.fex Len: 0x4
BuildImg 0
Dragon execute image.cfg SUCCESS !
----------image is at----------
size:613M /home/rice/t113/T113-i_v1.0/out/t113_i_linux_tlt113-evm-nand-sdboot_uart0.img
pack finish
rice@rice:~/t113/qt-demos/led_control/bin$ scp led_control root@ip:~/
root@T113-Tronlong:~# killall Launcher
root@T113-Tronlong:~# source /etc/qtenv.sh
add /dev/input/event1 to Qt Application.
find qt5 installed done
root@T113-Tronlong:~# ./led_control
static QString ledPath = "/sys/class/leds/user-led0";
void rice::ledInit()
{
setLedStatus(0);
ui->ledPushButton->setText("LED OFF");
ui->ledPushButton->setStyleSheet("border-width:1px;"
"border-style:solid; "
"border-color:white;"
"background-color:rgba(88, 88, 88, 200)");
}
void rice::ledDeinit()
{
}
bool rice::setLedStatus(int status)
{
QString cmd = "echo " + QString::number(status) + " > " + ledPath + "/brightness";
if (system(cmd.toStdString().c_str()) == -1) {
printf("set led status failed!\n");
return false;
}
return true;
}
int rice::getLedStatus(void)
{
QString cmd = "cat " + ledPath + "/brightness";
FILE *fp = popen(cmd.toStdString().c_str(), "r");
if (fp == nullptr) {
return -1;
}
char led_status[32];
if (fgets(led_status, sizeof(led_status), fp) == nullptr) {
printf("fgets error: %s\n", cmd.toStdString().c_str());
pclose(fp);
return -1;
}
pclose(fp);
return atoi(led_status);
}
void rice::on_ledPushButton_clicked()
{
int ledStatus = getLedStatus();
if (ledStatus == 0) {
setLedStatus(1);
ui->ledPushButton->setText("LED ON");
ui->ledPushButton->setStyleSheet("border-width:1px;"
"border-style:solid; "
"border-color:white;"
"background-color:rgba(00, 205, 00, 255)");
}
else {
setLedStatus(0);
ui->ledPushButton->setText("LED OFF");
ui->ledPushButton->setStyleSheet("border-width:1px;"
"border-style:solid; "
"border-color:white;"
"background-color:rgba(88, 88, 88, 200)");
}
}
void rice::keyInit()
{
keyFd = open(keyPath.toUtf8().data(), O_RDONLY);
if(keyFd == -1)
{
printf("Can not open file(%s)", keyPath.toUtf8().data());
return;
}
ui->keyTextEdit->append("Key Monitor!\n");
ui->keyTextEdit->append("Key user0 pressed!");
keyNotify = new QSocketNotifier(this->keyFd, QSocketNotifier::Read, this);
connect(this->keyNotify, SIGNAL(activated(int)), this, SLOT(keyHandler()));
}
void rice::keyDeinit()
{
}
void rice::keyHandler()
{
struct input_event buf;
if(read(keyFd, &buf, sizeof(struct input_event)) > 0)
{
if(buf.code == KEY_PROG1 && buf.value == 1)
{
ui->keyTextEdit->append("Key user0 pressed!");
}
}
}
void rice::dateInit()
{
struct rtc_time rtc_tm_temp;
dateFd = open(datePath.toUtf8().data(), O_RDONLY);
if(dateFd == -1)
{
printf("Can not open file(%s)", keyPath.toUtf8().data());
return;
}
if(ioctl(dateFd, RTC_RD_TIME, &rtc_tm_temp) < 0)
{
printf("Get date failed");
return;
}
ui->yearLineEdit->setText(QString::number(rtc_tm_temp.tm_year + 1900));
ui->monthLineEdit->setText(QString::number(rtc_tm_temp.tm_mon + 1));
ui->dayLineEdit->setText(QString::number(rtc_tm_temp.tm_mday));
}
void rice::dateDeint()
{
}
void rice::netInit()
{
server = new QTcpServer();
socket = new QTcpSocket();
}
void rice::netDeint()
{
}
void rice::netNewClientConnect()
{
socket = server->nextPendingConnection();
connect(socket, &QTcpSocket::readyRead, this, &rice::netNewRcve);
}
void rice::on_netPushButton_clicked()
{
int port = ui->portLineEdit->text().toInt();
if(ui->netPushButton->text() == tr("Open"))
{
if(ui->typeComboBox->currentText() == tr("Server"))
{
connect(server, &QTcpServer::newConnection, this, &rice::netNewClientConnect);
if(!server->listen(QHostAddress::Any, port))
{
printf("Listen failed\n");
return;
}
}
else if(ui->typeComboBox->currentText() == tr("Client"))
{
QString ip = ui->ipComboBox->currentText();
socket->abort();
socket->connectToHost(ip, port);
if(!socket->waitForConnected(3000))
{
printf("Connect server failed");
return;
}
connect(socket, &QTcpSocket::readyRead, this, &rice::netNewRcve);
}
ui->netPushButton->setText("Close");
}
else if(ui->netPushButton->text() == tr("Close"))
{
if(ui->typeComboBox->currentText() == tr("Server"))
{
socket->abort();
server->close();
}
else if(ui->typeComboBox->currentText() == tr("Client"))
{
socket->disconnectFromHost();
}
ui->netPushButton->setText("Open");
}
}
void rice::on_sendPushButton_clicked()
{
if(socket->isOpen())
{
socket->write(ui->sendLineEdit->text().toUtf8().data());
}
}
void rice::netNewRcve()
{
ui->recvTextEdit->append(socket->readAll());
}
void rice::on_typeComboBox_currentIndexChanged(const QString &arg1)
{
if(arg1 == tr("Server"))
{
ui->ipComboBox->setEditable(false);
}
else
{
ui->ipComboBox->setEditable(true);
}
}