【IMX6ULL笔记】-- 从驱动到应用(基于Qt)- LED

7 篇文章 3 订阅
6 篇文章 1 订阅

嵌入式点灯正如hello world一样,是我们常写的第一个测试程序,本章将介绍如何从底层内核搭建驱动,到使用Qt应用控制底层led灯显示

前期准备

1.imx6ull 开发板(笔者使用的是 韦东山开发板)

2.内核版本 4.9.88

3.文件系统(buildroot 2019.02工具输出)移植好qt(本章简单介绍)

4.ubuntu 安装好qt

5.交叉编译工具链:gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf

驱动篇

首先看原理图,LED的IO是哪个

请添加图片描述

1.内核配置

因为LED是非常基本的设备驱动,所以内核中已经集成了该功能,如下修改

请添加图片描述

请添加图片描述

2.基于设备驱动卡框架,设备树修改如下

    sys_led2 {
        compatible = "gpio-leds";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_leds>;
        
    //    status = "disabled";     

        led0 {
            label = "green";
            gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
            default-state = "on";
            linux,default-trigger = "heartbeat";
        };
    };
......
        pinctrl_leds: ledgrp {
            fsl,pins = <
                  MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03       0x110A0
            >;
        };

修改完成

make dtbs

启动新的dtb文件,内核系统启动后,led会如心跳一样闪烁,证明led驱动已经搭建完成了

应用篇

1.使用buildroot添加qt,配置如下

请添加图片描述

make 编译输出文件系统,修改文件系统 /etc/profile 文件(也可以在buildroot路径中修改 /output/target/etc/profile,然后编译输出的打包文件系统就不用再修改了),profile文件修改如下(主要看 tslibqt内容,其他先不管):

export PATH="/bin:/sbin:/usr/bin:/usr/sbin"

if [ "$PS1" ]; then
	if [ "`id -u`" -eq 0 ]; then
		export PS1='\u@\h:\w\# '
	else
		export PS1='\u@\h:\w\$'
	fi
fi

export EDITOR='/bin/vi'

# Source configuration files from /etc/profile.d
for i in /etc/profile.d/*.sh ; do
	if [ -r "$i" ]; then
		. $i
	fi
done
unset i

export ALSA_CONFIG_PATH=/usr/share/alsa/alsa.conf

#tslib
export TSLIB_ROOT=/usr/lib/ts
#export TSLIB_ROOT=/usr/lib/arm-tslib
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/lib/ts
#export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
#export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export LD_PRELOAD=/usr/lib/libts.so
#export LD_PRELOAD=$TSLIB_ROOT/lib/libts.so
echo  "tslib init success by l17!"


#qt
#export QT_ROOT=/usr/lib/arm-qt
export QT_ROOT=/usr/lib/qt
#export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event1
export QT_QPA_FONTDIR=/usr/share/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins
export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0
export QT_PLUGIN_PATH=$QT_ROOT/plugins
export LD_LIBRARY_PATH=$QT_ROOT/lib:$QT_ROOT/plugins/platforms
#export QML2_IMPORT_PATH=$QT_ROOT/qml
export QT_QPA_FB_TSLIB=1
echo  "qt5.12 init success by l17!"

export XDG_RUNTIME_DIR=/usr/lib/
export RUNLEVEL=3

2.创建一个QT工程

笔者在网上找了两张灯泡png,一个是开,一个是关,如下图,通过按钮可以实现LED的开关

请添加图片描述

具体代码如下:

//头文件///

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFile>
#include <QMessageBox>
#include <QPushButton>
#include <QLabel>
#include <QImage>
#include <QVBoxLayout>
#include <QHBoxLayout>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    QPushButton *pPushButton;
    QLabel *pLabel;
    QImage *pImg[2];

    /* 文件 */
    QFile file;

    /* 设置lED的状态 */
    void setLedState(bool onOff);

    /* 获取lED的状态 */
    bool getLedState();

private slots:
    void pushButton_Clicked();

};
#endif // MAINWINDOW_H

//cpp文件///

#include "mainwindow.h"
#include <QDebug>
#include <QGuiApplication>
#include <QScreen>

static bool lightOnOff;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QList <QScreen *> list_screen =  QGuiApplication::screens();

#if __arm__
    /* 重设大小 */
    this->resize(list_screen.at(0)->geometry().width(),
                 list_screen.at(0)->geometry().height());
        
     //先关闭心跳
    system("echo none > /sys/class/leds/green/trigger");
#else
    this->setGeometry(0, 0, 800, 480);
#endif

    pPushButton = new QPushButton("light switch",this);

    /* 居中显示 */
    pPushButton->setMinimumSize(200, 50);
    pPushButton->setGeometry((this->width() - pPushButton->width()) /2 ,this->height() - 120,
                            pPushButton->width(),pPushButton->height());

    pLabel = new QLabel(this);
    pImg[0]=new QImage; //新建一个image对象
    pImg[1]=new QImage; //新建一个image对象

#if __arm__
    pImg[0]->load("/img/light_off");
    pImg[1]->load("/img/light_on");
#else
    pImg[0]->load("/home/l17/qt_workspace/pngBtn/img/light_off");
    pImg[1]->load("/home/l17/qt_workspace/pngBtn/img/light_on");
#endif

    pLabel->setPixmap(QPixmap::fromImage(*pImg[0]));
    pLabel->resize(pImg[0]->width(),pImg[0]->height());
    pLabel->setGeometry((this->width() - pLabel->width()) /2 ,(this->height() - pLabel->height()) /4,
                        pImg[0]->width(),pImg[0]->height());


    file.setFileName("/sys/class/leds/green/brightness");

    if (!file.exists())
    {
        /* 设置按钮的初始化文本 */
        pPushButton->setText("not find LED device!");
    }
    else
    {
        lightOnOff = getLedState();

        if(lightOnOff)
        {
            this->setStyleSheet("QMainWindow { background-color: rgba(0, 204,68, 100%); }");
            pLabel->setPixmap(QPixmap::fromImage(*pImg[1]));
            pPushButton->setText("LED ON");
        }
        else
        {
            this->setStyleSheet("QMainWindow { background-color: rgba(255, 245,238, 100%); }");
            pLabel->setPixmap(QPixmap::fromImage(*pImg[0]));
            pPushButton->setText("LED OFF");
        }
    }

    connect(pPushButton, SIGNAL(clicked()), this,SLOT(pushButton_Clicked()));
}

MainWindow::~MainWindow()
{
}

/*bt click*/
void MainWindow::pushButton_Clicked()
{
    lightOnOff ^= 1;

    setLedState(lightOnOff);

    if(lightOnOff)
    {
        this->setStyleSheet("QMainWindow { background-color: rgba(0, 204,68, 100%); }");
        pLabel->setPixmap(QPixmap::fromImage(*pImg[1]));
        pPushButton->setText("LED ON");
    }
    else
    {
        this->setStyleSheet("QMainWindow { background-color: rgba(255, 245,238, 100%); }");
        pLabel->setPixmap(QPixmap::fromImage(*pImg[0]));
        pPushButton->setText("LED OFF");
    }
}


void MainWindow::setLedState(bool onOff)
{
    /* 在设置LED状态时先读取 */
    //bool state = getLedState();

    /* 如果文件不存在,则返回 */
    if (!file.exists())
        return;

    if(!file.open(QIODevice::ReadWrite))
        qDebug()<<file.errorString();

    QByteArray buf;

    buf = (onOff)?"1":"0";

    file.write(buf);

    /* 关闭文件 */
    file.close();
}

bool MainWindow::getLedState()
{
    /* 如果文件不存在,则返回 */
    if (!file.exists())
        return false;

    if(!file.open(QIODevice::ReadWrite))
        qDebug()<<file.errorString();

    QTextStream in(&file);

    /* 读取文件所有数据 */
    QString buf = in.readLine();

    /* 打印出读出的值 */
    qDebug()<<"buf: "<<buf<<endl;
    file.close();

    if (buf == "1")
    {
        pPushButton->setText("LED ON");
        return true;
    }
    else
    {
        pPushButton->setText("LED OFF");
        return false;
    }
}

通过ubuntu调试Qt工程,测试OK后,交叉编译适合arm的执行文件,将执行文件拷贝到开发板文件系统,启动开发板执行qt输出的可执行文件

请添加图片描述

另外注意将图片拷贝到文件系统根目录下 /img下(这个随便放哪里没有特别要求,保证我们代码能找到就行)

qt工程 界面操作驱动LED

输出结果,绿灯亮灭:

请添加图片描述
请添加图片描述

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值