上海做网站收费2024年3月份病毒会爆发吗
一、前言
本编文章记录在使用嵌入式系统中的一些功能测试demo程序,大部分都是AI写的,哈哈哈,确实很有帮助,但是得根据自身设备实际情况和知道如何问AI,才能得出你想要的结果,本文就记录一些ubuntu/麒麟系统实际使用过程中测试程序。
目录
1.串口测试程序
2.CAN测试程序
3.背光测试程序(弥补系统pwm匹配异常)
4.电量获取程序(弥补底系统版本不支持电池管理)
5.GPIO测试程序控制状态led灯
6.时间测试程序
7.redis通信测试程序
8.温度、CPU主频测试程序
9.msata挂载稳定性测试程序
二、环境
RK3588(linux5.10.66+debian/ubuntu/麒麟是桌面文件系统)
调试笔记本window10,安装常用工具winscp,xshell,finalshell,secureRTP等等
VMware17+Ubuntu20.04源码开发环境(这里就依赖于各个硬件平台的厂家提供资料了)
QT5.7
三、正文
程序都是QT环境开发的程序,程序内容放的都是核心代码,相关头文件简单补充,或者直接参考核心代码继续询问AI即可,大部分AI都是可以解决的
统一说明main.cpp引用了全局函数MySleep(),common.h也都是头文件
main.cpp
//延时usetime:非阻塞时间 waittime:阻塞时间
void MySleep(uint usetime,ulong waittime)
{QCoreApplication::processEvents(QEventLoop::AllEvents, usetime);//进入此函数内给之前数据usetime毫秒时间处理,处理完立马退出执行之后,超时立马退出QThread::msleep(waittime);//阻塞延时waittime毫秒
}
common.h
#ifndef COMMON_H
#define COMMON_H
#include <QVector>
#include <QMap>
#include <QApplication>
#include <QMainWindow>
#include <QtSql>
#include <QSqlQuery>
#include <QSqlTableModel>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QProcess>
#include <QPixmap>
#include <QPaintEvent>
#include <QPainter>
#include <QScrollBar>
#include <QTableWidget>
#include <QListWidgetItem>
#include <QTimer>
#include <QTime>
#include <QSystemTrayIcon>
#include <QGridLayout>
#include <QPushButton>
#include <QDoubleSpinBox>
#include <QAbstractItemView>
#include <QDoubleSpinBox>
#include <QThread>extern void MySleep(uint usetime,ulong waittime);#endif // COMMON_H
1.串口测试程序
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);this->setWindowModality(Qt::ApplicationModal);this->setWindowTitle("RK3588 串口接口测试软件V1.0/20241016");//初始化串口open_serialport(0,NULL);//初始化串口connect(ui->pushButton_refresh,&QPushButton::clicked,[=](){//刷新串口按键回调函数ui->comboBox->clear();//遍历当前存在的串口端口号if(!serial->portName().isNull())ui->comboBox->addItem(serial->portName());//显示已经开启的串口到列表foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){QSerialPort serial;serial.setPort(info);if(serial.open(QIODevice::ReadWrite)){ui->comboBox->addItem(serial.portName());serial.close();}}});QTimer::singleShot(100,this,[=](){ui->pushButton_refresh->click();});//点击一次按键timeserialCOM=new QTimer(this);connect(timeserialCOM,&QTimer::timeout,[=](){timeserialCOM->stop();comBatAnalyze(allDataCOM);//处理串口得到的数据});//发送数据connect(ui->btn_send_1,&QPushButton::clicked,[=](){if(serial->isOpen()){QByteArray sd=QByteArray::fromHex("11223344556677889900aabbccddeeffAABBCCDDEEFF");serial->write(sd);}});QTimer *time1=new QTimer(this);time1->start(10);connect(time1,&QTimer::timeout,[=](){if(ui->checkBox_1->isChecked())ui->btn_send_1->click();});//清空数据connect(ui->btn_clear_1,&QPushButton::clicked,[=](){ui->textEdit_1->clear();});}MainWindow::~MainWindow()
{serial->clear();//先关闭之前的串口serial->close();delete ui;
}//初始化/复位串口
void MainWindow::open_serialport(bool reset,QString comstr)
{if(reset){serial->clear();//先关闭之前的串口serial->close();}serial = new QSerialPort(comstr,this);serial->open(QIODevice::ReadWrite);//读写打开serial->setBaudRate(QSerialPort::Baud115200); //波特率QSerialPort::Baud9600serial->setDataBits(QSerialPort::Data8); //数据位serial->setParity(QSerialPort::NoParity); //无奇偶校验serial->setStopBits(QSerialPort::OneStop); //1停止位serial->setFlowControl(QSerialPort::NoFlowControl); //无控制connect(serial,SIGNAL(readyRead()),this,SLOT(serialRead()));//连接串口读取函数bool open=serial->isOpen();if(open){ui->comboBox->setCurrentText(comstr);if(comstr.isNull())ui->label_324->setText("当前未开启串口,请选择");else ui->label_324->setText("当前开启串口:"+comstr);}else{if(comstr.isNull())ui->label_324->setText("当前未开启串口,请选择");else ui->label_324->setText("串口打开失败,无效或被占用");}
}
void MainWindow::serialRead()
{timeserialCOM->start(10);//设置判断10ms内接收完毕数据,在处理while (!serial->atEnd()){allDataCOM += serial->readAll().toHex();}
}void MainWindow::comBatAnalyze(QByteArray &allData)
{QByteArray dataTemp;dataTemp=allData.toUpper();
// qDebug()<<"comBatAnalyze:"<<dataTemp;QString str;QByteArray aaa=QByteArray::fromHex(dataTemp);for(int i=0;i<aaa.size();i++)str.append(QString("%1 ").arg((uchar)aaa[i],2,16,QChar('0')).toUpper());ui->textEdit_1->append(QDateTime::currentDateTime().toString("hh:mm:ss zzz : ")+str);dataTemp.clear();//若没有需求的数据,则清除整个数据内容,重新接收判断allData=dataTemp;
}void MainWindow::on_comboBox_activated(const QString &arg1)
{open_serialport(1,arg1);//重新连接选择的串口ui->pushButton_refresh->click();//点击一次按键刷新串口资源
}
2.CAN测试程序
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);this->setWindowModality(Qt::ApplicationModal);this->setWindowTitle("RK3588 CAN接口测试软件V1.0/20240925");#ifndef WINDOWS//新建CAN连接//开启原生CAN2路startcan(0);//开启CAN0startcan(1);//开启CAN1
#endifMySleep(1000,500);//新建CAN连接//开启图莫斯1个CAN盒2路 CAN3 CAN4canThread=new canRevThread(this);connect(canThread,&canRevThread::threadRev1,this,&MainWindow::canAnalyze3);connect(canThread,&canRevThread::threadRev2,this,&MainWindow::canAnalyze4);canThread->start();//发送数据connect(ui->btn_send_1,&QPushButton::clicked,[=](){sendcan12(0);});connect(ui->btn_send_2,&QPushButton::clicked,[=](){sendcan12(1);});connect(ui->btn_send_3,&QPushButton::clicked,[=](){sendcan3();});connect(ui->btn_send_4,&QPushButton::clicked,[=](){sendcan4();});QTimer *time1=new QTimer(this);time1->start(10);connect(time1,&QTimer::timeout,[=](){if(ui->checkBox_1->isChecked())ui->btn_send_1->click();if(ui->checkBox_2->isChecked())ui->btn_send_2->click();if(ui->checkBox_3->isChecked())ui->btn_send_3->click();if(ui->checkBox_4->isChecked())ui->btn_send_4->click();});//清空数据connect(ui->btn_clear_1,&QPushButton::clicked,[=](){ui->textEdit_1->clear();});connect(ui->btn_clear_2,&QPushButton::clicked,[=](){ui->textEdit_2->clear();});connect(ui->btn_clear_3,&QPushButton::clicked,[=](){ui->textEdit_3->clear();});connect(ui->btn_clear_4,&QPushButton::clicked,[=](){ui->textEdit_4->clear();});}MainWindow::~MainWindow()
{stopcan();//程序退出,关闭当前开启的CAN1/2canThread->stopThread();//程序退出,关闭当前开启的CAN3/4delete ui;
}
///can1/2通讯配置(系统自带CAN2路)/
//开启can1/2
void MainWindow::startcan(int v)
{
#ifndef WINDOWSif(v == 0){
// setuid(0);system("sudo ifconfig can0 down");system("sudo ip link set can0 up type can bitrate 500000 triple-sampling on");system("sudo ifconfig can0 up");//创建套接字//PF_CAN 为域位 同网络编程中的AF_INET 即ipv4协议//SOCK_RAW使用的协议类型 SOCK_RAW表示原始套接字 报文头由自己创建//CAN_RAW为使用的具体协议 为can总线协议socket1 = ::socket(PF_CAN,SOCK_RAW,CAN_RAW);//创建套接字struct ifreq ifr;//接口请求结构体strcpy((char *)(ifr.ifr_name),v == 0 ? "can0" : "can1");//判断开启的是can0/1//fcntl(socket, F_SETFL, 1); //标志FNDELAY可以保证read函数在端口上读不到字符的时候返回0fcntl(socket1, F_SETFL, 0); //回到正常(阻塞)模式ioctl(socket1,SIOCGIFINDEX,&ifr);//指定 CAN0/1 设备addr1.can_family = AF_CAN;//协议类型addr1.can_ifindex = ifr.ifr_ifindex;//can总线外设的具体索引 类似 ip地址bind(socket1,(struct sockaddr*)&addr1,sizeof(addr1));//将套接字和canbus外设进行绑定,即套接字与 can0/1 绑定//禁用过滤规则,进程不接收报文,只负责发送,如需接受注释掉此函数即可//setsockopt(stSocket_LO, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);t1 = NULL;t1 = new Thread(socket1);//开启单独线程接受监听connect(t1,SIGNAL(message(QString,int,QString)),this,SLOT(msg1(QString,int,QString)));t1->start();}else{
// setuid(0);system("sudo ifconfig can1 down");system("sudo ip link set can1 up type can bitrate 500000 triple-sampling on");system("sudo ifconfig can1 up");//创建套接字//PF_CAN 为域位 同网络编程中的AF_INET 即ipv4协议//SOCK_RAW使用的协议类型 SOCK_RAW表示原始套接字 报文头由自己创建//CAN_RAW为使用的具体协议 为can总线协议socket2 = ::socket(PF_CAN,SOCK_RAW,CAN_RAW);//创建套接字struct ifreq ifr;//接口请求结构体strcpy((char *)(ifr.ifr_name),v == 0 ? "can0" : "can1");//判断开启的是can0/1//fcntl(socket, F_SETFL, 1); //标志FNDELAY可以保证read函数在端口上读不到字符的时候返回0fcntl(socket2, F_SETFL, 0); //回到正常(阻塞)模式ioctl(socket2,SIOCGIFINDEX,&ifr);//指定 CAN0/1 设备addr2.can_family = AF_CAN;//协议类型addr2.can_ifindex = ifr.ifr_ifindex;//can总线外设的具体索引 类似 ip地址bind(socket2,(struct sockaddr*)&addr2,sizeof(addr2));//将套接字和canbus外设进行绑定,即套接字与 can0/1 绑定//禁用过滤规则,进程不接收报文,只负责发送,如需接受注释掉此函数即可//setsockopt(stSocket_LO, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);t2 = NULL;t2 = new Thread(socket2);//开启单独线程接受监听connect(t2,SIGNAL(message(QString,int,QString)),this,SLOT(msg2(QString,int,QString)));t2->start();}
#endif
}
void MainWindow::stopcan()
{
#ifndef WINDOWSif(t1){//如果线程已经开启,关闭线程t1->stop();t1->deleteLater();}if(t2){//如果线程已经开启,关闭线程t2->stop();t2->deleteLater();}::close(socket1);::close(socket2);system("sudo ifconfig can0 down");//关闭CAN0system("sudo ifconfig can1 down");//关闭CAN1
#endif
}
void MainWindow::sendcan12(int v)
{
#ifndef WINDOWSstruct can_frame frame;memset(&frame,0,sizeof(struct can_frame));if(v==0){
// frame.can_id = (0x00123456 & CAN_EFF_MASK) | CAN_EFF_FLAG;//扩展帧frame.can_id = (0x11 & CAN_SFF_MASK);//标准帧frame.can_dlc= 8;frame.data[0]= 0x11;frame.data[1]= 0xaa;frame.data[2]= 0x11;frame.data[3]= 0xaa;frame.data[4]= 0x11;frame.data[5]= 0xaa;frame.data[6]= 0x11;frame.data[7]= 0xaa;}else{
// frame.can_id = (0x00abcdef & CAN_EFF_MASK) | CAN_EFF_FLAG;//扩展帧frame.can_id = (0x22 & CAN_SFF_MASK);//标准帧frame.can_dlc= 8;frame.data[0]= 0x22;frame.data[1]= 0xbb;frame.data[2]= 0x22;frame.data[3]= 0xbb;frame.data[4]= 0x22;frame.data[5]= 0xbb;frame.data[6]= 0x22;frame.data[7]= 0xbb;}//发送can数据:方式一//sendto(socket,&frame,sizeof(struct can_frame),0,(struct sockaddr*)&addr,sizeof(addr));//发送can数据:方式二if(v==0)write(socket1, &frame, sizeof(frame)); //发送 frameelse write(socket2, &frame, sizeof(frame)); //发送 framereturn;
#endif
}
//can1接收槽函数
void MainWindow::msg1(QString addr,int num,QString data)
{QString str = QString("%1\r\n%2,%3,%4").arg(QDateTime::currentDateTime().toString("hh:mm:ss zzz")).arg(addr).arg(num).arg(data);ui->textEdit_1->append(str);
}
//can2接收槽函数
void MainWindow::msg2(QString addr,int num,QString data)
{QString str = QString("%1\r\n%2,%3,%4").arg(QDateTime::currentDateTime().toString("hh:mm:ss zzz")).arg(addr).arg(num).arg(data);ui->textEdit_2->append(str);
}///can3/4通讯配置(图莫斯1个盒2路)/
//发送can3
void MainWindow::sendcan3()
{CAN_MSG CanMsg;CanMsg.ExternFlag = 0;//是否是扩展帧CanMsg.RemoteFlag = 0;//是否是远程帧CanMsg.ID = 0x33;CanMsg.DataLen = 8;CanMsg.Data[0]=0x33;CanMsg.Data[1]=0xcc;CanMsg.Data[2]=0x33;CanMsg.Data[3]=0xcc;CanMsg.Data[4]=0x33;CanMsg.Data[5]=0xcc;CanMsg.Data[6]=0x33;CanMsg.Data[7]=0xcc;canThread->sendcanData(0,CanMsg);
}
//发送can4
void MainWindow::sendcan4()
{CAN_MSG CanMsg;CanMsg.ExternFlag = 0;//是否是扩展帧CanMsg.RemoteFlag = 0;//是否是远程帧CanMsg.ID = 0x44;CanMsg.DataLen = 8;CanMsg.Data[0]=0x44;CanMsg.Data[1]=0xdd;CanMsg.Data[2]=0x44;CanMsg.Data[3]=0xdd;CanMsg.Data[4]=0x44;CanMsg.Data[5]=0xdd;CanMsg.Data[6]=0x44;CanMsg.Data[7]=0xdd;canThread->sendcanData(1,CanMsg);
}
//处理can3数据
void MainWindow::canAnalyze3(CAN_MSG *CanMsgtmp,char dwRel)
{for(int i = 0 ; i < dwRel ; i++){QString address=QString().sprintf("%08X",CanMsgtmp[i].ID&0x7fffffff);QString datastr=NULL;for(int j=0;j<CanMsgtmp[i].DataLen;j++)datastr.append(QString().sprintf("%02X",CanMsgtmp[i].Data[j]));QString str = QString("%1\r\n%2,%3,%4").arg(QDateTime::currentDateTime().toString("hh:mm:ss zzz")).arg(address).arg(CanMsgtmp[i].DataLen).arg(datastr);ui->textEdit_3->append(str);}
}
//处理can4数据
void MainWindow::canAnalyze4(CAN_MSG *CanMsgtmp, char dwRel)
{for(int i = 0 ; i < dwRel ; i++){QString address=QString().sprintf("%08X",CanMsgtmp[i].ID&0x7fffffff);QString datastr=NULL;for(int j=0;j<CanMsgtmp[i].DataLen;j++)datastr.append(QString().sprintf("%02X",CanMsgtmp[i].Data[j]));QString str = QString("%1\r\n%2,%3,%4").arg(QDateTime::currentDateTime().toString("hh:mm:ss zzz")).arg(address).arg(CanMsgtmp[i].DataLen).arg(datastr);ui->textEdit_4->append(str);}
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include "common.h"namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();protected:private slots://CAN12 linux自带的socketcanvoid sendcan12(int v);void stopcan();void startcan(int v);void msg1(QString addr, int num, QString data);void msg2(QString addr, int num, QString data);//CAN34 USB扩展图莫斯canvoid sendcan3();void sendcan4();void canAnalyze3(CAN_MSG *CanMsgtmp, char dwRel);void canAnalyze4(CAN_MSG *CanMsgtmp, char dwRel);private:Ui::MainWindow *ui;#ifndef WINDOWSint socket1;struct sockaddr_can addr1;//can总线的地址 同socket编程里面的 socketaddr结构体 用来设置can外设的信息Thread *t1;int socket2;struct sockaddr_can addr2;//can总线的地址 同socket编程里面的 socketaddr结构体 用来设置can外设的信息Thread *t2;
#endifcanRevThread *canThread;};#endif // MAINWINDOW_H
thread
cpp
#include "thread.h"
#include "mainwindow.h"
Thread::Thread(int s,QObject *parent) :QThread(parent)
{socket = s;running = true;
}void Thread::run()
{
#ifndef WINDOWS//qDebug()<<"start can receive Thread!";int nbytes;
// int len;struct can_frame frame;
// struct sockaddr_can addr;
// char buf[8];while(running){
// nbytes=recvfrom(socket,&frame,sizeof(struct can_frame),0,(struct sockaddr *)&addr,(socklen_t*)&len);//接收can数据:方式一
// if(nbytes>0){
// memset(buf,0,8);
// strncpy(buf,(char*)frame.data,8);
// //emit message(&addr,&len);
// printf("id=%x,len=%d\n",(struct sockaddr *)&addr,(socklen_t*)&len);
// }//接收can数据:方式二nbytes = read(socket, &frame, sizeof(frame)); //接收报文if(nbytes > 0){QString address=QString().sprintf("%08X",frame.can_id&0x7fffffff);QString data=NULL;for(int i=0;i<frame.can_dlc;i++)data.append(QString().sprintf("%02X",frame.data[i]));emit message(address,frame.can_dlc,data);
// printf("iiid=%x,len=%d,data=%x%x%x%x%x%x%x%x\n",frame.can_id&0x7fffffff,frame.can_dlc,frame.data[0],frame.data[1],frame.data[2],frame.data[3],frame.data[4],frame.data[5],frame.data[6],frame.data[7]);}}
#endif
}void Thread::stop()
{running = false;
}h
#ifndef THREAD_H
#define THREAD_H#include <QThread>#ifndef WINDOWS
extern "C" {
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/can.h>
}
#endif#ifndef PF_CAN
#define PF_CAN 29
#endif#ifndef AF_CAN
#define AF_CAN PF_CAN
#endifclass Thread : public QThread
{Q_OBJECT
public:explicit Thread(int s,QObject *parent = 0);signals:void message(QString addr,int num,QString data);
public slots:void run();void stop();private:int socket;bool running;};#endif // THREAD_H
usbcanthread
cpp
#include "canrevthread.h"
#include <QMessageBox>canRevThread::canRevThread( QObject *parent):QThread(parent)
{DevHandle=0x04ff;stopped = 1;bool state;int ret;int DevHdle[10];//扫描查找设备ret = USB_ScanDevice(DevHdle);if(ret <= 0){qDebug()<<QString().sprintf("No device connected!");stopped=0;return;}else{qDebug()<<"handle:"<<DevHdle[0];}//打开设备DevHandle=DevHdle[0];state = USB_OpenDevice(DevHandle);if(!state){qDebug()<<QString().sprintf("Open device error!");stopped=0;return;}//初始化配置CANCAN_INIT_CONFIG CANConfig;// CANConfig.CAN_Mode = 1;//环回模式CANConfig.CAN_Mode = 0;//正常模式CANConfig.CAN_ABOM = 0;//禁止自动离线CANConfig.CAN_NART = 1;//禁止报文重传CANConfig.CAN_RFLM = 0;//FIFO满之后覆盖旧报文CANConfig.CAN_TXFP = 1;//发送请求决定发送顺序//配置波特率,波特率 = 42M/(BRP*(SJW+BS1+BS2))//can通信波特率500kCANConfig.CAN_BRP = 4;//4CANConfig.CAN_BS1 = 16;//16CANConfig.CAN_BS2 = 4;//4CANConfig.CAN_SJW = 1;//1CANConfig.CAN_Mode |= 0x80; //使能接入内部终端电阻ret = CAN_Init(DevHandle,0,&CANConfig);if(ret != CAN_SUCCESS){qDebug()<<QString().sprintf("Config CAN 3 failed!");stopped=0;return;}else{qDebug()<<QString().sprintf("Config CAN 3 Success!");}ret = CAN_Init(DevHandle,1,&CANConfig);if(ret != CAN_SUCCESS){qDebug()<<QString().sprintf("Config CAN 4 failed!");stopped=0;return;}else{qDebug()<<QString().sprintf("Config CAN 4 Success!");}//配置过滤器,必须配置,否则可能无法收到数据CAN_FILTER_CONFIG CANFilter;CANFilter.Enable = 1;CANFilter.ExtFrame = 0; //过滤的帧类型标志,为1 代表要过滤的为扩展帧,为0 代表要过滤的为标准帧。CANFilter.FilterIndex = 0;CANFilter.FilterMode = 0;CANFilter.MASK_IDE = 0;CANFilter.MASK_RTR = 0;CANFilter.MASK_Std_Ext = 0;CAN_Filter_Init(DevHandle,0,&CANFilter);CAN_Filter_Init(DevHandle,1,&CANFilter);}
canRevThread::~canRevThread()
{stopped = 0; requestInterruption();quit();wait();USB_CloseDevice(DevHandle);
}void canRevThread::sendcanData(uchar index,CAN_MSG &CanD)
{int SendedNum = CAN_SendMsg(DevHandle,index,&CanD,1);if(SendedNum <= 0){
// qDebug()<<QString().sprintf("CAN1 send FAIL %1",SendedNum);}
}
void canRevThread::run()
{ CAN_MSG CanMsgBuffer1[100],CanMsgBuffer2[100];//最大支持100帧char CanNum1=0;char CanNum2=0;while(stopped){CanNum1 = CAN_GetMsg(DevHandle,0,CanMsgBuffer1);CanNum2 = CAN_GetMsg(DevHandle,1,CanMsgBuffer2);if(CanNum1 > 0){emit threadRev1(CanMsgBuffer1,CanNum1);}if(CanNum2 > 0){emit threadRev2(CanMsgBuffer2,CanNum2);}msleep(5);}
}
void canRevThread::stopThread()
{stopped = 0;
}h
#ifndef CANREVTHREAD_H
#define CANREVTHREAD_H#include <QThread>#include <QString>#include <QDebug>
#include <QtCore/qglobal.h>
//#define OS_UNIX
#include "usb_device.h"
#include "usb2can.h"
#if defined(CANTHREAD_COMPILE_LIBRARY)
# define CANTHREAD_LIB_DECL Q_DECL_EXPORT
#elif defined(CANTHREAD_USE_LIBRARY)
# define CANTHREAD_LIB_DECL Q_DECL_IMPORT
#else
# define CANTHREAD_LIB_DECL
#endifclass CANTHREAD_LIB_DECL canRevThread: public QThread
{Q_OBJECT
signals:void threadRev1(CAN_MSG *data,char dwRel);void threadRev2(CAN_MSG *data,char dwRel);public:canRevThread(QObject *parent);~canRevThread();void sendcanData(uchar index,CAN_MSG &CanD);void run();void stopThread();
private:int stopped;int DevHandle;
};
#endif
pro
QT += core gui sql network printsupport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = RK3588porttest
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
DEPENDPATH += .
INCLUDEPATH += .# Input
HEADERS += \mainwindow.h \common.h \CustomWidget/Thread/thread.h \CustomWidget/usbcanthread/canrevthread.h \CustomWidget/usbcanthread/usb_device.h \CustomWidget/usbcanthread/usb2can.hSOURCES += \main.cpp \mainwindow.cpp \CustomWidget/Thread/thread.cpp \CustomWidget/usbcanthread/canrevthread.cppFORMS += \mainwindow.uiCONFIG += mobility
MOBILITY =win32{message($$QT_ARCH)contains(QT_ARCH, i386) {LIBS += -L$$PWD/CustomWidget/usbcanthread/window/ -lUSB2XXX} else {}
}unix:!macx{message($$QMAKE_HOST.arch)unix:contains(QMAKE_HOST.arch, x86_64){
# LIBS += -L$$PWD/CustomWidget/usbcanthread/linux-A40i/ -lUSB2XXXLIBS += -L$$PWD/CustomWidget/usbcanthread/linux-RK3588/ -lUSB2XXX -lusb-1.0}unix:contains(QMAKE_HOST.arch, x86){}unix:contains(QMAKE_HOST.arch, aarch64){}unix:contains(QMAKE_HOST.arch, armv7){}unix:contains(QMAKE_HOST.arch, mips64){}
}win32: DEFINES += WINDOWS
!win32: DEFINES += OS_UNIX
前两路2是调用系统自带的CAN,用socketcan,可以参考我A40i帖子中的一个CAN文章
后两路CAN是其他厂家的一个USB转CAN模块,需要匹配相关的驱动,与厂家要驱动文件,引用,可能需要重新根据系统编译一下libusb-1.0.so,才能在交叉编译环境中编译通过
3.背光测试程序(弥补系统pwm匹配异常)
麒麟系统连接edp或mipi屏幕时,会出现pwm不受控现象,麒麟系统与硬件没有完成适配兼容,因为在系统设置中调节亮度不好使
下面通过第三方软件或其他方法尝试解决此问题
1第三方软件方式
未找到合适工具,最终通过自己写程序修改亮度
2自写脚本定时设置亮度方式。
命令参考手册的亮度设置章节
ls /sys/class/backlight
cat /sys/class/backlight/backlight-edp1/brightness
echo 0 > /sys/class/backlight/backlight-edp1/brightness
echo 125 > /sys/class/backlight/backlight-edp1/brightness
echo 255 > /sys/class/backlight/backlight-edp1/brightness
写了一个test_backlight测试程序,当检测到亮度为0时自动设置亮度信息为上次配置的
缺点是会出现一下黑屏,闪一下
最佳解决方式是后期更换稳定系统
后续测试高版本的linux源码尝试
#include "mainwindow.h"
#include <QVBoxLayout>
#include <QFile>
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), currentBrightness(200)
{// 初始化滑动条和标签brightnessSlider = new QSlider(Qt::Horizontal, this);brightnessSlider->setRange(0, 255);brightnessSlider->setValue(currentBrightness);brightnessLabel = new QLabel("亮度: " + QString::number(currentBrightness), this);brightnessLabel->setFont(QFont("黑体",50));// 布局QWidget *centralWidget = new QWidget(this);centralWidget->setMinimumSize(500,300);QVBoxLayout *layout = new QVBoxLayout(centralWidget);layout->addWidget(brightnessLabel);layout->addWidget(brightnessSlider);centralWidget->setLayout(layout);setCentralWidget(centralWidget);// 连接滑动条信号connect(brightnessSlider, &QSlider::valueChanged, this, &MainWindow::onSliderValueChanged);// 初始化定时器brightnessTimer = new QTimer(this);connect(brightnessTimer, &QTimer::timeout, this, &MainWindow::checkAndRestoreBrightness);brightnessTimer->start(1000); // 每1s检查一次// 初始设置亮度setBrightness(currentBrightness);
}MainWindow::~MainWindow()
{delete brightnessSlider;delete brightnessLabel;delete brightnessTimer;
}void MainWindow::onSliderValueChanged(int value)
{currentBrightness = value;brightnessLabel->setText("亮度: " + QString::number(currentBrightness));setBrightness(currentBrightness);
}void MainWindow::checkAndRestoreBrightness()
{int actualBrightness = getBrightness();if (actualBrightness == 0) {qDebug() << "亮度被重置为 0,恢复为" << currentBrightness;setBrightness(currentBrightness);}
}void MainWindow::setBrightness(int value)
{QFile brightnessFile("/sys/class/backlight/backlight-edp1/brightness");if (brightnessFile.open(QIODevice::WriteOnly)) {brightnessFile.write(QString::number(value).toUtf8());brightnessFile.close();} else {qWarning() << "无法设置亮度,请检查权限或路径。";}
}int MainWindow::getBrightness()
{QFile brightnessFile("/sys/class/backlight/backlight-edp1/brightness");if (brightnessFile.open(QIODevice::ReadOnly)) {QString brightnessValue = brightnessFile.readAll().trimmed();brightnessFile.close();return brightnessValue.toInt();} else {qWarning() << "无法读取亮度,请检查权限或路径。";return -1;}
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSlider>
#include <QLabel>
#include <QTimer>class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void onSliderValueChanged(int value);void checkAndRestoreBrightness();private:QSlider *brightnessSlider;QLabel *brightnessLabel;QTimer *brightnessTimer;int currentBrightness;void setBrightness(int value);int getBrightness();
};#endif // MAINWINDOW_H
4.电量获取程序(弥补底系统版本不支持电池管理)
麒麟系统V10 2303默认不支持电源管理功能,没有电池图标右下角的显示
使用xx电源模块在国防版麒麟系统可以显示电量信息,但是国防版系统镜像不好用缺图标
最终还是使用2303系统,需要自己通过软件获取电量信息
等以后有了2403系统,就没有这个问题了
方法:
upower -e
upower -i /org/freedesktop/UPower/devices/ups_hiddev0
后续写了一个demo程序 test_power,用于监测电源模块电量信息,等以后写程序可以集成在程序之中
#include "mainwindow.h"
#include <QApplication>
#include <QMenu>
#include <QAction>
#include <QProcess>
#include <QMessageBox>
#include <QDebug>
#include <QPainter>
#include <QFontMetrics>
#include <QVBoxLayout>
#include <QWidget>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), isCharging(false), batteryPercentage(0), timeToEmpty(0)
{// 创建托盘图标createTrayIcon();// 创建桌面 UIQWidget *centralWidget = new QWidget(this);QVBoxLayout *layout = new QVBoxLayout(centralWidget);percentageLabel = new QLabel("电量: 未知", centralWidget);timeToEmptyLabel = new QLabel("剩余时长: 未知", centralWidget);layout->addWidget(percentageLabel);layout->addWidget(timeToEmptyLabel);centralWidget->setLayout(layout);setCentralWidget(centralWidget);
centralWidget->show();// 定时器,每分钟更新一次电量信息timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &MainWindow::updateBatteryStatus);timer->start(60000); // 每分钟更新一次// 初始更新updateBatteryStatus();
}MainWindow::~MainWindow()
{delete trayIcon;delete timer;
}void MainWindow::createTrayIcon()
{trayIcon = new QSystemTrayIcon(this);updateTrayIcon(); // 初始化图标QMenu *menu = new QMenu(this);QAction *quitAction = new QAction("退出", this);connect(quitAction, &QAction::triggered, qApp, &QApplication::quit);menu->addAction(quitAction);trayIcon->setContextMenu(menu);trayIcon->show();connect(trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::iconActivated);
}void MainWindow::updateBatteryStatus()
{QProcess process;process.start("upower -i /org/freedesktop/UPower/devices/ups_hiddev0");process.waitForFinished();QString output = process.readAllStandardOutput();parseBatteryStatus(output);// 更新托盘图标和桌面 UIupdateTrayIcon();updateDesktopUI();
}void MainWindow::parseBatteryStatus(const QString &output)
{QStringList lines = output.split("\n");for (const QString &line : lines) {if (line.contains("percentage")) {batteryPercentage = line.split(":").last().trimmed().replace("%", "").toInt();}if (line.contains("time to empty")) {timeToEmpty = line.split(":").last().trimmed().replace("hours", "").toDouble();// 如果剩余时长为 18.2 小时,则认为充电器接入isCharging = (timeToEmpty == 18.2);}}
}void MainWindow::updateTrayIcon()
{// 创建一个 64x64 的画布QPixmap pixmap(64, 64);pixmap.fill(Qt::transparent); // 透明背景QPainter painter(&pixmap);painter.setRenderHint(QPainter::Antialiasing);// 绘制电池外框painter.setPen(Qt::white);painter.setBrush(Qt::transparent);painter.drawRect(15, 20, 34, 20); // 电池外框// 绘制电池正极painter.drawRect(49, 25, 4, 10);// 绘制电量填充int fillWidth = static_cast<int>(32 * (batteryPercentage / 100.0));painter.setBrush(Qt::green);painter.drawRect(16, 21, fillWidth, 18);// 绘制百分比文字painter.setPen(Qt::white);QFont font = painter.font();font.setPixelSize(16); // 增大字体大小painter.setFont(font);// 计算文字居中位置QFontMetrics metrics(font);QString text = QString::number(batteryPercentage) + "%";int textWidth = metrics.width(text); // 使用 width 替代 horizontalAdvanceint textHeight = metrics.height();int textX = (pixmap.width() - textWidth) / 2;int textY = (pixmap.height() + textHeight) / 2;painter.drawText(textX, textY, text);// 如果是充电状态,绘制闪电符号if (isCharging) {QPolygon lightning;lightning << QPoint(32, 10) << QPoint(40, 20) << QPoint(32, 20)<< QPoint(44, 40) << QPoint(32, 30) << QPoint(40, 30);painter.setBrush(Qt::yellow);painter.drawPolygon(lightning);}// 设置托盘图标trayIcon->setIcon(QIcon(pixmap));
}void MainWindow::updateDesktopUI()
{// 更新电量百分比percentageLabel->setText(QString("电量: %1%").arg(batteryPercentage));// 更新剩余使用时长if (isCharging) {timeToEmptyLabel->setText("状态: 充电中");} else {timeToEmptyLabel->setText(QString("剩余时长: %1 小时").arg(timeToEmpty));}
}void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
{if (reason == QSystemTrayIcon::Trigger) {updateBatteryStatus();}
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSystemTrayIcon>
#include <QTimer>
#include <QPixmap>
#include <QPainter>
#include <QLabel>class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void updateBatteryStatus();void iconActivated(QSystemTrayIcon::ActivationReason reason);private:QSystemTrayIcon *trayIcon;QTimer *timer;bool isCharging;int batteryPercentage;double timeToEmpty; // 剩余使用时长(小时)QLabel *percentageLabel;QLabel *timeToEmptyLabel;void createTrayIcon();void updateTrayIcon();void updateDesktopUI();void parseBatteryStatus(const QString &output);
};#endif // MAINWINDOW_H
5.GPIO测试程序控制状态led灯
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);static bool ledflag=false;
#ifdef WINDOWS#else//开机指令初始化指示灯gpiosystem("echo 24 > /sys/class/gpio/export");//led1system("echo out > /sys/class/gpio/gpio24/direction");system("echo 27 > /sys/class/gpio/export");//led2system("echo out > /sys/class/gpio/gpio27/direction");QTimer *timeled=new QTimer(this);timeled->start(500);connect(timeled,&QTimer::timeout,[=](){ledflag=!ledflag;if(ledflag){system("echo 0 > /sys/class/gpio/gpio24/value");system("echo 1 > /sys/class/gpio/gpio27/value");ui->label->setStyleSheet("background-color: rgb(0, 255, 0);");ui->label_2->setStyleSheet("background-color: rgb(255, 0, 0);");}else{system("echo 1 > /sys/class/gpio/gpio24/value");system("echo 0 > /sys/class/gpio/gpio27/value");ui->label->setStyleSheet("background-color: rgb(255, 0, 0);");ui->label_2->setStyleSheet("background-color: rgb(0, 255, 0);");}qDebug()<<"ledflag:"<<QString::number(ledflag);});//绑定定时分析数据函数槽
#endifqDebug()<<"ledflag:"<<QString::number(ledflag);ui->label->setStyleSheet("background-color: rgb(0, 255, 0);");ui->label_2->setStyleSheet("background-color: rgb(255, 0, 0);");}
MainWindow::~MainWindow()
{delete ui;
}
6.时间测试程序
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDate>
#include <QTime>
#include <QPalette>
#include <stdio.h>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);//setWindowState(Qt::WindowMaximized);setWindowFlags(Qt::FramelessWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);QPalette pal;pal.setColor(QPalette::Text,QColor(255,0,0));ui->year->setPalette(pal);ui->month->setPalette(pal);ui->day->setPalette(pal);ui->hour->setPalette(pal);ui->minute->setPalette(pal);ui->second->setPalette(pal);QDate d = QDate::currentDate();QTime t = QTime::currentTime();ui->year->setValue(d.year());ui->month->setValue(d.month());ui->day->setValue(d.day());ui->hour->setValue(t.hour());ui->minute->setValue(t.minute());ui->second->setValue(t.second());ui->year->setEnabled(false);ui->month->setEnabled(false);ui->day->setEnabled(false);ui->hour->setEnabled(false);ui->minute->setEnabled(false);ui->second->setEnabled(false);timer.start(1000,this);connect(ui->exitBtn, &QPushButton::clicked, this, [=](){close(); });
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::timerEvent(QTimerEvent *event)
{QDate d = QDate::currentDate();QTime t = QTime::currentTime();if(ui->set->text()=="set"){ui->year->setValue(d.year());ui->month->setValue(d.month());ui->day->setValue(d.day());ui->hour->setValue(t.hour());ui->minute->setValue(t.minute());ui->second->setValue(t.second());}QWidget::timerEvent(event);
}void MainWindow::on_set_clicked()
{if(ui->set->text()=="set"){ui->set->setText("save");ui->year->setEnabled(true);ui->month->setEnabled(true);ui->day->setEnabled(true);ui->hour->setEnabled(true);ui->minute->setEnabled(true);ui->second->setEnabled(true);timer.stop();}else{char buf[128];ui->set->setText("set");memset(buf,0,128);sprintf(buf,"date -s '%4d-%02d-%02d %02d:%02d:%02d'",ui->year->text().toInt(),ui->month->text().toInt(),ui->day->text().toInt(),ui->hour->text().toInt(),ui->minute->text().toInt(),ui->second->text().toInt());system(buf);system("hwclock -w");ui->year->setEnabled(false);ui->month->setEnabled(false);ui->day->setEnabled(false);ui->hour->setEnabled(false);ui->minute->setEnabled(false);ui->second->setEnabled(false);timer.start(1000,this);}
}void MainWindow::closeEvent(QCloseEvent *)
{//system("killall matrix_gui");//system("/etc/init.d/qt.sh");exit(0);
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QBasicTimer>
#include <QTimerEvent>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();
protected:void timerEvent(QTimerEvent *event);void closeEvent(QCloseEvent *);
private slots:void on_set_clicked();private:Ui::MainWindow *ui;QBasicTimer timer;
};#endif // MAINWINDOW_H
7.redis通信测试程序
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);// 连接到 Redis 服务器,用于发布命令publishContext = redisConnect("127.0.0.1", 6379);if (publishContext == NULL || publishContext->err) {if (publishContext) {qDebug() << "Error: " << publishContext->errstr;ui->textEdit->setText(QString("Error: %1").arg(publishContext->errstr));redisFree(publishContext);} else {qDebug() << "Can't allocate redis context for publishing";ui->textEdit->setText("Can't allocate redis context for publishing");}return;}else {ui->textEdit->append("redis 发布 connect successful");}// 连接到 Redis 服务器,用于订阅命令subscribeContext = redisConnect("127.0.0.1", 6379);if (subscribeContext == NULL || subscribeContext->err) {if (subscribeContext) {qDebug() << "Error: " << subscribeContext->errstr;ui->textEdit->setText(QString("Error: %1").arg(subscribeContext->errstr));redisFree(subscribeContext);} else {qDebug() << "Can't allocate redis context for subscribing";ui->textEdit->setText("Can't allocate redis context for subscribing");}return;}else {ui->textEdit->append("redis 订阅 connect successful");}// 订阅结果频道if (subscribeContext && !subscribeContext->err) {redisReply *reply = static_cast<redisReply*>(redisCommand(subscribeContext, "SUBSCRIBE numpy_result pandas_result tensorflow_result sklearn_result matplotlib_result"));if (reply) {freeReplyObject(reply);}}// 创建并启动 Redis 订阅线程subscriberThread = new RedisSubscriberThread(subscribeContext, this);connect(subscriberThread, &RedisSubscriberThread::messageReceived, this, [this](const QString &channel, const QString &message) {ui->textEdit->append(channel + ": " + message);});subscriberThread->start();
}MainWindow::~MainWindow()
{if (publishContext) {redisFree(publishContext);}if (subscribeContext) {redisFree(subscribeContext);}if (subscriberThread) {subscriberThread->quit();subscriberThread->wait();}delete ui;
}void MainWindow::on_pushButton_clicked()
{if (publishContext && !publishContext->err) {redisReply *reply = static_cast<redisReply*>(redisCommand(publishContext, "PUBLISH numpy_command run_numpy"));if (reply) {if (reply->type == REDIS_REPLY_ERROR) {qDebug() << "Error publishing to Redis: " << reply->str;} else {qDebug() << "Message published successfully to numpy_command";}freeReplyObject(reply);} else {qDebug() << "Error: Failed to execute Redis command";}} else {qDebug() << "Redis publish context is invalid";}
}void MainWindow::on_pushButton_2_clicked()
{if (publishContext && !publishContext->err) {redisReply *reply = static_cast<redisReply*>(redisCommand(publishContext, "PUBLISH pandas_command run_pandas"));if (reply) {if (reply->type == REDIS_REPLY_ERROR) {qDebug() << "Error publishing to Redis: " << reply->str;} else {qDebug() << "Message published successfully to pandas_command";}freeReplyObject(reply);} else {qDebug() << "Error: Failed to execute Redis command";}} else {qDebug() << "Redis publish context is invalid";}
}void MainWindow::on_pushButton_3_clicked()
{if (publishContext && !publishContext->err) {redisReply *reply = static_cast<redisReply*>(redisCommand(publishContext, "PUBLISH tensorflow_command run_tensorflow"));if (reply) {if (reply->type == REDIS_REPLY_ERROR) {qDebug() << "Error publishing to Redis: " << reply->str;} else {qDebug() << "Message published successfully to tensorflow_command";}freeReplyObject(reply);} else {qDebug() << "Error: Failed to execute Redis command";}} else {qDebug() << "Redis publish context is invalid";}
}void MainWindow::on_pushButton_4_clicked()
{if (publishContext && !publishContext->err) {redisReply *reply = static_cast<redisReply*>(redisCommand(publishContext, "PUBLISH sklearn_command run_sklearn"));if (reply) {if (reply->type == REDIS_REPLY_ERROR) {qDebug() << "Error publishing to Redis: " << reply->str;} else {qDebug() << "Message published successfully to sklearn_command";}freeReplyObject(reply);} else {qDebug() << "Error: Failed to execute Redis command";}} else {qDebug() << "Redis publish context is invalid";}
}void MainWindow::on_pushButton_5_clicked()
{if (publishContext && !publishContext->err) {redisReply *reply = static_cast<redisReply*>(redisCommand(publishContext, "PUBLISH matplotlib_command run_matplotlib"));if (reply) {if (reply->type == REDIS_REPLY_ERROR) {qDebug() << "Error publishing to Redis: " << reply->str;} else {qDebug() << "Message published successfully to matplotlib_command";}freeReplyObject(reply);} else {qDebug() << "Error: Failed to execute Redis command";}} else {qDebug() << "Redis publish context is invalid";}
}void MainWindow::on_pushButton_6_clicked()
{ui->textEdit->clear();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QDebug>
#include <QThread>
#include <QTimer>
#include <QMetaObject>
#include "QtHiRedis/hiredis.h" // 包含 hiredis 头文件// 定义一个新的线程类来处理 Redis 订阅
class RedisSubscriberThread : public QThread {Q_OBJECT
public:RedisSubscriberThread(redisContext *context, QObject *parent = nullptr): QThread(parent), subscribeContext(context) {}signals:void messageReceived(const QString &channel, const QString &message);protected:void run() override {if (subscribeContext && !subscribeContext->err) {redisReply *reply;while (true) {int retval = redisGetReply(subscribeContext, (void**)&reply);if (retval == REDIS_OK && reply != NULL && reply->type == REDIS_REPLY_ARRAY && reply->elements == 3) {QString messageType = QString::fromUtf8(reply->element[0]->str);if (messageType == "message") {QString channel = QString::fromUtf8(reply->element[1]->str);QString result = QString::fromUtf8(reply->element[2]->str);emit messageReceived(channel, result);}}if (reply) {freeReplyObject(reply);}}}}private:redisContext *subscribeContext;
};namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_3_clicked();void on_pushButton_4_clicked();void on_pushButton_5_clicked();void on_pushButton_6_clicked();private:Ui::MainWindow *ui;redisContext *publishContext; // 使用 hiredis 的上下文redisContext *subscribeContext; // 使用 hiredis 的上下文RedisSubscriberThread *subscriberThread;
};#endif // MAINWINDOW_H
附件太多了,自己下载开源的,或者下载我的全套资源吧
文章参考链接
程序下载链接
8.温度、CPU主频测试程序
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);#ifdef WINDOWSm_path=qApp->applicationDirPath();
#elsem_path="/media/root/sata";//sata是更改挂载点后的文件名,默认是UUID,没法通过程序去识别每个设备的硬盘
#endif///timer定时器初始化,3秒进行一次数据分析,不管数据是否接收,定时分析数据以UDP形式发送到指定目标IPQTimer *time1=new QTimer(this);time1->start(3000);connect(time1,&QTimer::timeout,[=](){AnalyseData();});//绑定定时分析数据函数槽}
MainWindow::~MainWindow()
{delete ui;
}///******************************************************************定时分析数据**************************************************************///
//在时钟和硬盘挂载正常的情况下分析内存容量是否充足,大于80%要删除到60%以下,最少保留当天日期数据不可删除
//分析数据采集盒状态:时钟状态、时间、固态硬盘挂载状态、固态硬盘容量、CPU温度、CPU主频、采集盒版本信息,将数据打包放入待发送缓存中
//分析整车全部系统状态:xxx,将数据打包放入待发送缓存中
//
void MainWindow::AnalyseData()
{
///分析硬盘容量ui->textEdit->clear();qDebug()<<"\r\n";qDebug()<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");ui->textEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));qDebug()<<"/*****************check disk used******************/";ui->textEdit->append("/*****************check disk used******************/");if(QFile::exists(m_path)){//判断硬盘状态是否正常,异常后出正常也不给予正常状态,只要出现判断不到即报错,单次即一直触发,不消除故障m_mSATAstatus=true;//mSATA挂载正常QTime get_disk_usetime;//记录查询日志数据列表消耗时间get_disk_usetime.start();//计算mSATA_size,mSATA_used,mSATA_persentQStorageInfo storage = QStorageInfo::root();storage.refresh(); //获得最新磁盘信息storage.device();storage.setPath(m_path);mSATA_size=storage.bytesTotal()/(1024*1024);//单位MBytemSATA_used=mSATA_size-storage.bytesFree()/(1024*1024);mSATA_persent=mSATA_used*100/mSATA_size;qDebug()<<"mSATA used:"<<getsize(mSATA_used)<<",mSATA allsize:"<<getsize(mSATA_size);qDebug()<<"mSATA use persent is "<<QString::number(mSATA_persent)<<"%,get mSATA used persent usetime:"<<QString::number(get_disk_usetime.elapsed())<<"ms";ui->textEdit->append("mSATA used:"+getsize(mSATA_used)+",mSATA allsize:"+getsize(mSATA_size));ui->textEdit->append("mSATA use persent is "+QString::number(mSATA_persent)+"%,get mSATA used persent usetime:"+QString::number(get_disk_usetime.elapsed())+"ms");}else{qDebug()<<"mSATA err!";ui->textEdit->append("mSATA err!");m_mSATAstatus=false;//赋值硬盘错误状态}
///获取数据采集盒状态QString m_freq0,m_freq4,m_temp;//本机工作频率和温度QString m_cpu0,m_cpu4;
#ifndef WINDOWSQFile file("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");//获取cpu工作主频if (file.open(QIODevice::ReadOnly | QIODevice::Text)){m_freq0 = file.readLine();file.close();}QFile file2("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq");//获取cpu工作主频if (file2.open(QIODevice::ReadOnly | QIODevice::Text)){m_freq4 = file2.readLine();file2.close();}QFile file1("/sys/class/thermal/thermal_zone0/temp");//获取cpu工作温度if (file1.open(QIODevice::ReadOnly | QIODevice::Text)){m_temp = file1.readLine();file1.close();}QFile file3("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies");//获取cpu主频范围if (file3.open(QIODevice::ReadOnly | QIODevice::Text)){m_cpu0 = file3.readLine();file3.close();}QFile file4("/sys/devices/system/cpu/cpu4/cpufreq/scaling_available_frequencies");//获取cpu主频范围if (file4.open(QIODevice::ReadOnly | QIODevice::Text)){m_cpu4 = file4.readLine();file4.close();}
#elsem_freq0="99999";m_freq4="99999";m_temp="99.99";m_cpu0="";m_cpu4="";
#endifqDebug()<<"/*****************check CPU used******************/";qDebug()<<tr("cpu0 range %1").arg(m_cpu0);qDebug()<<tr("cpu4 range %1").arg(m_cpu4);qDebug()<<tr("cpu0 freq %1,cpu4 freq %2,now temp %3").arg(m_freq0).arg(m_freq4).arg(m_temp);qDebug()<<"/*****************check end******************/";ui->textEdit->append("/*****************check CPU used******************/");ui->textEdit->append(tr("cpu0 range %1").arg(m_cpu0));ui->textEdit->append(tr("cpu4 range %1").arg(m_cpu4));ui->textEdit->append(tr("cpu0 freq %1,cpu4 freq %2,now temp %3").arg(m_freq0).arg(m_freq4).arg(m_temp));ui->textEdit->append("/*****************check end******************/");
}
QString MainWindow::getsize(qint64 m_allsizie)
{QString fileSize;if (m_allsizie >= 0 && m_allsizie < 1024){fileSize = QString::number(m_allsizie) + "Byte";}else if (m_allsizie >= 1024 && m_allsizie < 1024 * 1024){fileSize = QString::number(m_allsizie / 1024.0, 'f', 2) + "KB";}else if (m_allsizie >= 1024 * 1024 && m_allsizie < 1024 * 1024 * 1024){fileSize = QString::number(m_allsizie / 1024 / 1024.0, 'f', 2) + "MB";}else if (m_allsizie >= 1024 * 1024 * 1024){fileSize = QString::number(m_allsizie / 1024 / 1024 / 1024.0, 'f', 2) + "GB";}return fileSize;
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include "header.h"namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();protected:private slots:void AnalyseData();QString getsize(qint64 m_allsizie);
private:Ui::MainWindow *ui;bool m_mSATAstatus=false;//固态硬盘是否正常,不正常不能建立文件夹存储数据QString m_path;//记录当前存储文件的路径,在WINDOWS的路径还是在linux中的固态硬盘中路径qint64 mSATA_size,mSATA_used,mSATA_persent;//mSATA硬盘总容量,已经使用容量,容量使用百分比};#endif // MAINWINDOW_H
9.msata挂载稳定性测试程序
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);//读取配置信息QString line_config;QFile file_config(qApp->applicationDirPath()+"/test_msata_config.txt");if(file_config.open(QIODevice::ReadOnly|QIODevice::Text)){while(!file_config.atEnd()){line_config=file_config.readLine();}file_config.close();}else{file_config.open(QIODevice::WriteOnly|QIODevice::Text);QTextStream in(&file_config);in<<"0";line_config="0";file_config.close();}qDebug()<<"config:"<<line_config;ui->spinBox->setValue(line_config.toInt());if(line_config=="0")ui->checkBox->setChecked(false);else ui->checkBox->setChecked(true);//读取配置信息QString line_path;QFile file_path(qApp->applicationDirPath()+"/test_msata_path.txt");if(file_path.open(QIODevice::ReadOnly|QIODevice::Text)){while(!file_path.atEnd()){line_path=file_path.readLine();}file_path.close();}else{file_path.open(QIODevice::WriteOnly|QIODevice::Text);QTextStream in(&file_path);in<<"/dev/sda5";line_path="/dev/sda5";file_path.close();}qDebug()<<"path:"<<line_path;ui->lineEdit->setText(line_path);//读取配置信息QString line_history;QFile file_history(qApp->applicationDirPath()+"/test_msata_history.txt");if(file_history.open(QIODevice::ReadOnly|QIODevice::Text)){while(!file_history.atEnd()){line_history=file_history.readLine().replace("\n","");qDebug()<<"history:"<<line_history;if(line_history.contains("yes")){QTextCharFormat fmt;fmt.setForeground(Qt::green);ui->textEdit->setCurrentCharFormat(fmt);ui->textEdit->append(line_history);}else if(line_history.contains("err")){QTextCharFormat fmt;fmt.setForeground(Qt::red);ui->textEdit->setCurrentCharFormat(fmt);ui->textEdit->append(line_history);}}file_history.close();}QTimer *time1=new QTimer(this);time1->start(2000);//20sconnect(time1,&QTimer::timeout,[=](){AnalyseData();});//绑定定时分析数据函数槽}
MainWindow::~MainWindow()
{delete ui;
}///******************************************************************定时分析数据**************************************************************///void MainWindow::AnalyseData()
{
///获取数据采集盒状态QString m_temp="66666";//本机工作频率和温度QFile file1("/sys/class/thermal/thermal_zone0/temp");//获取cpu工作温度if (file1.open(QIODevice::ReadOnly | QIODevice::Text)){m_temp = file1.readLine();file1.close();}m_temp = QString::number((double)m_temp.toInt()/1000,'f',2);if(ui->checkBox->isChecked()){int num=ui->spinBox->value();if(num>0){ui->spinBox->setValue(num-1);QFile file(ui->lineEdit->text());if(file.exists()) {// 文件存在QTextCharFormat fmt;fmt.setForeground(Qt::green);ui->textEdit->setCurrentCharFormat(fmt);ui->textEdit->append(QString("%1,msata fstab yes,CPU temp %2,has %3").arg(QDateTime::currentDateTime().toString("hh:mm:ss")).arg(m_temp).arg(ui->spinBox->value()));}else {// 文件不存在QTextCharFormat fmt;fmt.setForeground(Qt::red);ui->textEdit->setCurrentCharFormat(fmt);ui->textEdit->append(QString("%1,msata fstab err,CPU temp %2,has %3").arg(QDateTime::currentDateTime().toString("hh:mm:ss")).arg(m_temp).arg(ui->spinBox->value()));}QFile file_path(qApp->applicationDirPath()+"/test_msata_history.txt");file_path.open(QIODevice::WriteOnly|QIODevice::Text);QTextStream in(&file_path);in<<ui->textEdit->toPlainText();file_path.close();qDebug()<<"重启";system("reboot");}
// else
// ui->textEdit->append("测试完毕!");}
}
//按键点击事件
void MainWindow::on_checkBox_clicked()
{
// QFile file_config(qApp->applicationDirPath()+"/test_msata_config.txt");
// file_config.open(QIODevice::WriteOnly|QIODevice::Text);
// QTextStream in(&file_config);
// QString res;
// if(ui->checkBox->isChecked()==false)
// res="0";
// in<<res;
// file_config.close();
}
void MainWindow::on_pushButton_clicked()
{QFile file_path(qApp->applicationDirPath()+"/test_msata_path.txt");file_path.open(QIODevice::WriteOnly|QIODevice::Text);QTextStream in(&file_path);in<<ui->lineEdit->text();file_path.close();
}
void MainWindow::on_pushButton_2_clicked()
{QFile file_path(qApp->applicationDirPath()+"/test_msata_history.txt");file_path.open(QIODevice::WriteOnly|QIODevice::Text);QTextStream in(&file_path);in<<"";file_path.close();ui->textEdit->clear();
}void MainWindow::on_spinBox_valueChanged(int arg1)
{QFile file_config(qApp->applicationDirPath()+"/test_msata_config.txt");file_config.open(QIODevice::WriteOnly|QIODevice::Text);QTextStream in(&file_config);in<<QString::number(arg1);file_config.close();
}
四、结语
未完待续。。。
可以用AI生成,很多平台都可以,描述清楚就可以对症下药,用起来