Qt点亮开发板的一个LED
Qt如何操控开发板上的一个LED
Qt与硬件控制的关系
- Qt本身并不直接控制开发板上的硬件,而是通过中间层进行交互
驱动层的作用
- 驱动层是连接Qt应用层和硬件的关键部分,它提供了必要的接口和功能,使得Qt能够通过这些接口来操控硬件
接口的重要性
- 这些由驱动层提供的接口是Qt应用与硬件交互的桥梁,对于应用开发人员来说,理解这些接口的功能和使用方法是至关重要的
应用开发人员的角色
- 作为应用开发人员,需要与驱动开发人员沟通,确保了解并能够正确使用驱动层提供的接口,以便有效地控制硬件
驱动开发人员的责任
- 驱动开发人员负责开发和维护这些接口,确保它们稳定、高效,并且能够满足应用层的需求
出厂内核设备树中注册的LED设备
编译出厂源码内核及模块
-
获取开发板光盘上的源码
-
路径:A-基础资料->1、例程源码->3、正点原子 Uboot 和 Linux 出厂源码->linux-imx-4.1.15-2.1.0-gxxxxxx-vxx.tar.xz
-
文件格式:可能是 .xz 或者 .bz2
-
-
将源码文件拷贝到Ubuntu虚拟机
- 把 linux-imx-4.1.15-2.1.0-gxxxxxx-vxx.tar.xz 文件拷贝到 Ubuntu 虚拟机中
-
选择目标目录
- 在 Ubuntu 虚拟机的家目录(当前用户目录)下执行操作
-
创建目标解压目录
-
在家目录下创建一个新目录用于存放解压后的Linux源码
-
mkdir -p IMX6/uboot-imx-2016.03-2.1.0
-
-
解压源码文件
-
将 Linux 源码文件解压到刚才创建的目录中
-
tar xf uboot-imx-2016.03-2.1.0-gd3f0479-v1.4.tar.xz -C IMX6/uboot-imx-2016.03-2.1.0/
-
-
cd IMX6/uboot-imx-2016.03-2.1.0
-
ls
-
安装交叉编译工具链
- 在编译 U-boot 之前,需要先安装Poky 交叉编译工具链
-
准备编译脚本
-
在 Linux 源码目录中,有一个已经写好的脚本 build.sh
-
脚本内已经配置好了 deconfig 文件和编译的目标文件
-
-
执行编译脚本
-
直接运行 build.sh 脚本来编译 U-boot 源码
-
build.sh // 开始编译出厂 U-boot 源码,生成 u-boot.imx,第一级启动引导文件
-
-
检查编译结果
- 编译生成的目标文件会位于当前 U-boot 源码顶层目录下的 tmp 文件夹中
-
查看编译文件
- 在编译完成后,需要查看当前目录下的 tmp 文件夹内的编译文件目标
-
了解文件类型
-
*imx 文件
-
这些文件是已经添加头部信息的 U-boot 镜像
-
可以直接使用 dd 指令烧写到 TF 卡和开发板上的 eMMC 存储设备
-
-
*bin 文件
-
这些文件是未添加头部信息的 U-boot 镜像
-
需要使用《【正点原子】I.MX6U 嵌入式 Linux 驱动开发指南》里提到的 imxdownload 工具烧写
-
-
I.MX6U设备树路径为arch/arm/boot/dts/imx6ull-14x14-evk.dts
-
开发板的led接口
-
正点原子的出厂内核已经默认将这个 LED 注册成了 gpio-leds
类型设备 -
可以直接在应用层接口直接可以操作这个 LED 设备
资源简介
ALPHA 开发板的 LED 原理图
应用实例
设置一个按钮,点击按钮即可控制 LED 的状态反转(点亮或者熄灭 LED)
mainwindow.h
-
1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3
4 #include
5 #include
6 #include
7
8 class MainWindow : public QMainWindow
9{
10 Q_OBJECT
11
12 public:
13 MainWindow(QWidget parent = nullptr);
14 ~MainWindow();
15
16 private:
17 / 按钮 */
18 QPushButton pushButton;
19
20 / 文件 /
21 QFile file;
22
23 / 设置 lED 的状态 /
24 void setLedState();
25
26 / 获取 lED 的状态 */
27 bool getLedState();
28
29 private slots:
30 void pushButtonClicked();
31 };
32 #endif // MAINWINDOW_H -
第 24 行声明一个设置 LED 状态方法,另一个是获取状态的方法。另外声明一个槽函数,作用是点击切换 LED 的状态
mainwindow.cpp
-
1 #include “mainwindow.h”
2 #include
3 #include
4 #include
5 #include
6
7 MainWindow::MainWindow(QWidget parent)
8 : QMainWindow(parent)
9{
10 / 获取屏幕的分辨率,Qt 官方建议使用这
11 * 种方法获取屏幕分辨率,防上多屏设备导致对应不上
12 * 注意,这是获取整个桌面系统的分辨率
13 */
14 QList <QScreen > list_screen = QGuiApplication::screens();
15
16 / 如果是 ARM 平台,直接设置大小为屏幕的大小 /
17 #if arm
18 / 重设大小 /
19 this->resize(list_screen.at(0)->geometry().width(),
20 list_screen.at(0)->geometry().height());
21 / 默认是出厂系统的 LED 心跳的触发方式,想要控制 LED,
22 * 需要改变 LED 的触发方式,改为 none,即无 /
23 system(“echo none > /sys/class/leds/sys-led/trigger”);
24 #else
25 / 否则则设置主窗体大小为 800x480 /
26 this->resize(800, 480);
27 #endif
28
29 pushButton = new QPushButton(this);
30
31 / 居中显示 /
32 pushButton->setMinimumSize(200, 50);
33 pushButton->setGeometry((this->width() - pushButton->width()) /2 ,
34 (this->height() - pushButton->height()) /2,
35 pushButton->width(),
36 pushButton->height()
37 );
38 / 开发板的 LED 控制接口 /
39
file.setFileName(“/sys/devices/platform/leds/leds/sys-led/brightness”);
40
41 if (!file.exists())
42 / 设置按钮的初始化文本 /
43 pushButton->setText(“未获取到 LED 设备!”);
44
45 / 获取 LED 的状态 /
46 getLedState();
47
48 / 信号槽连接 /
49 connect(pushButton, SIGNAL(clicked()),
50 this, SLOT(pushButtonClicked()));
51 }
52
53 MainWindow::~MainWindow()
54 {
55 }
56
57 void MainWindow::setLedState()
58 {
59 / 在设置 LED 状态时先读取 /
60 bool state = getLedState();
61
62 / 如果文件不存在,则返回 /
63 if (!file.exists())
64 return;
65
66 if(!file.open(QIODevice::ReadWrite))
67 qDebug()<<file.errorString();
68
69 QByteArray buf[2] = {“0”, “1”};
70
71 / 写 0 或 1 /
72 if (state)
73 file.write(buf[0]);
74 else
75 file.write(buf[1]);
76
77 / 关闭文件 */
78 file.close();
79
80 /*重新获取 LED 的状态 /
81 getLedState();
82 }
83
84 bool MainWindow::getLedState()
85 {
86 / 如果文件不存在,则返回 /
87 if (!file.exists())
88 return false;
89
90 if(!file.open(QIODevice::ReadWrite))
91 qDebug()<<file.errorString();
92
93 QTextStream in(&file);
94
95 / 读取文件所有数据 /
96 QString buf = in.readLine();
97
98 / 打印出读出的值 /
99 qDebug()<<"buf: "<<buf<<endl;
100 file.close();
101 if (buf == “1”) {
102 pushButton->setText(“LED 点亮”);
103 return true;
104 } else {
105 pushButton->setText(“LED 熄灭”);
106 return false;
107 }
108 }
109
110 void MainWindow::pushButtonClicked()
111 {
112 / 设置 LED 的状态 */
113 setLedState();
114 } -
界面初始化设置(第 9 行~24 行)
-
在嵌入式系统中,根据实际屏幕的大小进行全屏显示的设置
-
按钮应居中显示在屏幕上
-
-
改变 LED 触发方式(第 23 行)
-
出厂系统中,LED 的触发方式被设置为心跳方式
-
为了控制此 LED,需要将 LED 的触发方式改为无触发方式(none)
-
为了方便操作,直接使用 system() 函数,通过指令的方式改变 LED 的触发方式
-
-
设置 LED 的方法(第 54~82 行)
-
写入“0”或“1”分别代表关闭和开启 LED
-
在写入之前,先读取 LED 的当前状态,以预防在其他地方有用户设置过 LED
-
-
获取 LED 的状态(第 84 行~108 行)
- 这部分代码负责获取 LED 的当前状态
-
设置 LED 的状态(第 110 行~114 行)
-
这部分代码是一个槽函数,由点击按钮触发
-
该槽函数负责设置 LED 的新状态
-