RK3588使用笔记:ubuntu/麒麟系统功能测试程序

一、前言

本编文章记录在使用嵌入式系统中的一些功能测试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::Baud9600
    serial->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);//开启CAN0
    startcan(1);//开启CAN1
#endif
    MySleep(1000,500);
    //新建CAN连接//开启图莫斯1个CAN盒2路 CAN3 CAN4
    canThread=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/2
    canThread->stopThread();//程序退出,关闭当前开启的CAN3/4
    delete ui;
}
///////////////////////////////////can1/2通讯配置(系统自带CAN2路)/////////////////////////////////////
//开启can1/2
void MainWindow::startcan(int v)
{
#ifndef WINDOWS
    if(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函数在端口上读不到字符的时候返回0
        fcntl(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函数在端口上读不到字符的时候返回0
        fcntl(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 WINDOWS
    if(t1){//如果线程已经开启,关闭线程
        t1->stop();
        t1->deleteLater();
    }
    if(t2){//如果线程已经开启,关闭线程
        t2->stop();
        t2->deleteLater();
    }
    ::close(socket1);
    ::close(socket2);
    system("sudo ifconfig can0 down");//关闭CAN0
    system("sudo ifconfig can1 down");//关闭CAN1
#endif
}
void MainWindow::sendcan12(int v)
{
#ifndef WINDOWS
    struct 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)); //发送 frame
    else write(socket2, &frame, sizeof(frame)); //发送 frame
    return;
#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;
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大桶矿泉水

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值