Qt控制LED

自己搭建的根文件系统,要确保加载了LED的驱动,以及系统的设备树也是支持LED的。

主要关注便是 brightness、 max_brightness 以及 trigger 三个文件,这三个文件都是 LED 设备的属性文件:
⚫ brightness: 翻译过来就是亮度的意思, 该属性文件可读可写; 所以这个属性文件是用于设置 LED的亮度等级或者获取当前 LED 的亮度等级,譬如 brightness 等于 0 表示 LED 灭, brightness 为正整数表示 LED 亮,其值越大、 LED 越亮; 对于 PWM 控制的 LED 来说, 这通常是适用的,因为它存在亮度等级的问题,不同的亮度等级对应不同的占空比,自然 LED 的亮度也是不同的; 但对于 GPIO控制(控制 GPIO 输出高低电平)的 LED 来说,通常不存在亮度等级这样的说法,只有 LED 亮(brightness 等于 0)和 LED 灭(brightness 为非 0 值的正整数)两种状态。
⚫ max_brightness: 该属性文件只能被读取,不能写,用于获取 LED 设备的最大亮度等级。
⚫ trigger: 触发模式,该属性文件可读可写,读表示获取 LED 当前的触发模式,写表示设置 LED 的触发模式。 不同的触发模式其触发条件不同, LED 设备会根据不同的触发条件自动控制其亮、灭状态, 通过 cat 命令查看该属性文件,可获取 LED 支持的所有触发模式以及 LED 当前被设置的触发模式:

方括号([heartbeat])括起来的表示当前 LED 对应的触发模式, none 表示无触发,常用的触发模式包括none(无触发)、 mmc0(当对 mmc0 设备发起读写操作的时候 LED 会闪烁)、 timer(LED 会有规律的一亮一灭,被定时器控制住)、 heartbeat(心跳呼吸模式, LED 模仿人的心跳呼吸那样亮灭变化)。

设计qt程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//mainwindow.cpp文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QFile>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();

private:
/* 按钮 */
QPushButton *pushButton;
/* 文件 */
QFile file;
/* 设置 lED 的状态 */
void setLedState();
/* 获取 lED 的状态 */
bool getLedState();
private slots:
void pushButtonClicked();
};
#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "mainwindow.h"
#include <QDebug>
#include <QGuiApplication>
#include <QScreen>
#include <QRect>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
/* 获取屏幕的分辨率, Qt 官方建议使用这
* 种方法获取屏幕分辨率,防上多屏设备导致对应不上
* 注意,这是获取整个桌面系统的分辨率
*/
QList <QScreen *> list_screen = QGuiApplication::screens();

/* 如果是 ARM 平台,直接设置大小为屏幕的大小 */
#if __arm__
/* 重设大小 */
this->resize(list_screen.at(0)->geometry().width(),
list_screen.at(0)->geometry().height());
/* 默认是出厂系统的 LED 心跳的触发方式,想要控制 LED,
* 需要改变 LED 的触发方式,改为 none,即无 */
system("echo none > /sys/class/leds/sys-led/trigger");
#else
/* 否则则设置主窗体大小为 800x480 */
this->resize(800, 480);
#endif

pushButton = new QPushButton(this);

/* 居中显示 */
pushButton->setMinimumSize(200, 50);
pushButton->setGeometry((this->width() - pushButton->width()) /2 ,(this->height() - pushButton->height()) /2,
pushButton->width(), pushButton->height());
/* 开发板的 LED 控制接口 */

file.setFileName("/sys/devices/platform/leds/leds/sys-led/brightness");
if (!file.exists())
/* 设置按钮的初始化文本 */
pushButton->setText("未获取到 LED 设备! ");

/* 获取 LED 的状态 */
getLedState();

/* 信号槽连接 */
connect(pushButton, SIGNAL(clicked()),this, SLOT(pushButtonClicked()));
}

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

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

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

QByteArray buf[2] = {"0", "1"};

/* 写 0 或 1 */
if (state)
file.write(buf[0]);
else
file.write(buf[1]);

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

/*重新获取 LED 的状态 */
getLedState();
}

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") {
pushButton->setText("LED 点亮");
return true;
} else {
pushButton->setText("LED 熄灭");
return false;
}
}

void MainWindow::pushButtonClicked()
{
/* 设置 LED 的状态 */
setLedState();
}

brightness文件缺失问题

解决这个问题居然绕了一大圈,居然是因为led的引脚在别的引脚占用了,所以才导致的brightness的文件确实,没找到这个的原因主要是之前写的led驱动居然能加载,设备还能使用,导致没想到能出现这个问题,就没有查设备树。大无语了,测了内核,测了硬件,最后才测了设备树。唉。。。

U盘只读问题的解决

①插入U盘并用df -h查看U盘信息:

1
$df -h

这里写图片描述

这里是我的信息, 可以看到U盘文件系统为/dev/sdb5,挂载点为/media/zoutao/disk

卸载U盘

1
sudo umount /media/zoutao/disk

卸载之后一定不能拔掉U盘

修复U盘文件系统故障

1
sudo dosfsck -v -a /dev/sdb5

重新插拔