原子学习笔记3——点亮 LED

一、应用层操控设备的两种方式

应用层如何操控底层硬件,同样也是通过文件 I/O 的方式来实现,设备文件便是各种硬件设备向应用层提供的一个接口,应用层通过对设备文件的 I/O 操作来操控硬件设备,譬如 LCD 显示屏、串口、按键、摄像头等等,所以设备文件其实是与硬件设备相互对应的。设备文件通常在/dev/目录下,我们也把/dev 目录下的文件称为设备节点。
设备节点并不是操控硬件设备的唯一途径,除此之外,我们还可以通过 sysfs 文件系统对硬件设备进行操控。

1、sysfs 文件系统

sysfs 是一个基于内存的文件系统,同 devfs、proc 文件系统一样,称为虚拟文件系统;它的作用是将内核信息以文件的方式提供给应用层使用。

2、sysfs 与/sys

sysfs 文件系统挂载在/sys 目录下,启动 ALPHA 开发板,进入 Linux 系统(开发板出厂系统)之后,我们进入到/sys 目录下查看,如下所示
在这里插入图片描述
上图显示的便是 sysfs 文件系统中的目录,包括 block、bus、class、dev、devices、firmware、fs、kernel、modules、power 等
系统中所有的设备(对象)都会在/sys/devices 体现出来,是 sysfs 文件系统中最重要的目录结构;而
/sys/bus、/sys/class、/sys/dev 分别将设备按照挂载的总线类型、功能分类以及设备号的形式将设备组织存放在这些目录中,这些目录下的文件都是链接到了/sys/devices 中。
设备的一些属性、数据通常会通过设备目录下的文件体现出来,也就是说设备的数据、属性会导出到用户空间,以文件形式为用户空间提供对这些数据、属性的访问支持,可以把这些文件称为属性文件;读这些属性文件就表示读取设备的属性信息,相反写属性文件就表示对设备的属性进行设置、以控制设备的状态。

3、总结

这里给大家进行一个总结,应用层想要对底层硬件进行操控,通常可以通过两种方式:

  • /dev/目录下的设备文件(设备节点);
  • /sys/目录下设备的属性文件。
    具体使用哪种方式需要根据不同功能类型设备进行选择,有些设备只能通过设备节点进行操控,而有些设备只能通过 sysfs 方式进行操控;当然跟设备驱动具体的实现方式有关,通常情况下,一般简单地设备会使用 sysfs 方式操控,其设备驱动在实现时会将设备的一些属性导出到用户空间 sysfs 文件系统,以属性文件的形式为用户空间提供对这些数据、属性的访问支持,譬如 LED、GPIO 等。但对于一些较复杂的设备通常会使用设备节点的方式,譬如 LCD 等、触摸屏、摄像头等。

二、LED 硬件控制方式

对于 ALPHA开发板出厂系统来说,此 LED 设备使用的是 Linux 内核标准 LED 驱动框架注册而成,在/dev 目录下并没有其对应的设备节点,其实现使用 sysfs 方式控制。进入到/sys/class/leds 目录下,如下所示:
在这里插入图片描述
上小节介绍了/sys/class 目录,系统中的所有设备根据其功能分类组织到了/sys/class 目录下,所以/sys/class/leds 目录下便存放了所有的 LED 类设备。从上图可以看到该目录下有一个 sys-led 文件夹,这个便是底板上的用户 LED 设备文件夹。
这里我们主要关注便是 brightness、max_brightness 以及 trigger 三个文件,这三个文件都是 LED 设备的属性文件:
trigger:触发模式,该属性文件可读可写,读表示获取 LED 当前的触发模式,写表示设置 LED 的触发模式。不同的触发模式其触发条件不同,LED 设备会根据不同的触发条件自动控制其亮、灭状态,通过 cat 命令查看该属性文件,可获取 LED 支持的所有触发模式以及 LED 当前被设置的触发模式:
在这里插入图片描述
方括号([heartbeat])括起来的表示当前 LED 对应的触发模式,none 表示无触发,常用的触发模式包括none(无触发)、mmc0(当对 mmc0 设备发起读写操作的时候 LED 会闪烁)、timer(LED 会有规律的一亮一灭,被定时器控制住)、heartbeat(心跳呼吸模式,LED 模仿人的心跳呼吸那样亮灭变化)。
通常系统启动之后,会将板子上的一颗 LED 设置为 heartbeat 触发模式,将其作为系统正常运行的指示灯,譬如 ALPHA 开发板系统启动之后,底板上的用户 LED 就会处于心跳呼吸模式。
通过上面的介绍,已经知道如何去控制 ALPHA开发板底板上的用户 LED 了,譬如通过echo 命令进行控制:

echo timer > trigger //将 LED 触发模式设置为 timer
echo none > trigger //将 LED 触发模式设置为 none
echo 1 > brightness //点亮 LED echo 0 > brightness//熄灭 LED

使用 echo 或 cat 命令进行测试、控制 LED 状态;除了使用 echo 或 cat 命令之后,同样我们编写应用程序,使用 write()、read()函数对这些属性文件进行 I/O 操作以达到控制 LED 的效果。

三、编写 LED 应用程序

1、例程源码

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define LED_TRIGGER "/sys/class/leds/sys-led/trigger"
#define LED_BRIGHTNESS "/sys/class/leds/sys-led/brightness"
#define USAGE() fprintf(stderr, "usage:\n" \" %s <on|off>\n" \" %s <trigger> <type>\n", argv[0], argv[0])
int main(int argc, char *argv[])
{int fd1, fd2;// /* 校验传参 if (2 > argc) {USAGE();exit(-1);}// /* 打开文件 fd1 = open(LED_TRIGGER, O_RDWR);if (0 > fd1) {perror("open error");exit(-1);}fd2 = open(LED_BRIGHTNESS, O_RDWR);if (0 > fd2) {perror("open error");exit(-1);}// /* 根据传参控制 LED if (!strcmp(argv[1], "on")) {write(fd1, "none", 4); //先将触发模式设置为 nonewrite(fd2, "1", 1); //点亮 LED}else if (!strcmp(argv[1], "off")) {write(fd1, "none", 4); //先将触发模式设置为 nonewrite(fd2, "0", 1); //LED 灭}else if (!strcmp(argv[1], "trigger")) {if (3 != argc) {USAGE();exit(-1);}if (0 > write(fd1, argv[2], strlen(argv[2])))perror("write error");}elseUSAGE();exit(0);
}

程序中定义了两个宏,LED_TRIGGER 和 LED_BRIGHTNESS,分别对应/sys/class/leds/sys-led/trigger 和/sys/class/leds/sys-led/brightness 属性文件;程序首先会调用 open()函数打开这两个属性文件,之后判断传入参数指向相应的动作,传入"on"表示点亮 LED,先调用 write()将"none"
写入到 trigger 属性文件中,也就是设置为无触发,接着再向 brightness 属性文件中写入"1"点亮 LED;传入"off"表示熄灭 LED,同样也是先调用 write()将"none"写入到 trigger 属性文件设置 LED 为无触发,接着再向brightness 属性文件中写入"0"熄灭 LED;传入"trigger"表示设置 LED 的触发模式,则需要传入第二个参数,第二个参数表示需要设置的模式。

2、开发板上测试

启动开发板进入 Linux 系统,将上小节编译得到的可执行文件 testApp 拷贝到开发板根文件系统中,譬如拷贝到开发板 Linux 系统的家目录下,如下图所示:
在这里插入图片描述
拷贝方法很多,介绍下 scp 命令:
1、将开发板用网线连接在与虚拟机同一个路由器下,查看下开发板的IP地址。
例如,在 home 目录下有个 test 文件我们要把这个 test 文件传到开发板的/home/root 目录(我们一般传文件都是传文件到家目录(/home/root)的)。指令格式如下

scp 文件 用户名@ip 地址:路径

例:scp testApp root@192.168.5.14:/home/root
指令格式分析:
testApp 要传输的文件
root 为用户名,开发板默认的就是 root 用户,拥有最高权限
@ 一个符号
192.168.5.14 开发板 ip
: 这里要加一个英文字符的“:”,不要忘记了!
/home/root 要传输到开发板的路径
在这里插入图片描述
在开发板/home/root 可以看到 testApp 文件已经通过网络传输到开发板了。
2、用WiFi驱动,同样是获取IP地址
首先插上USBWiFi,进入终端

cd /home/root/shell/wifi
ls

在这里插入图片描述
使用station上网模式

wpa_cli -i wlan0 scan_result // 此指令需要启动进入后再插 WIFI 才生效,需要 wpa_supplicant 在运行。

在这里插入图片描述

source ./alientek_usb_wifi_setup.sh -m station -i ALIENTEK-YF -p 1590202**** -d wlan0

参数解释:
-m station :设置成 station 模式
-i ALIENTEK-YF :无线网络名称(ssid)。
-p 1590202**** :无线网络密码(psk)。
-d wlan0 :USB WIFI 节点
看到下图已经获取到 ip 信息就代表连接无线网络成功,如果没有获取到 ip 信息,请检查密码是否正确或者重试指令。
在这里插入图片描述
若未能正常获取 ip,等待 RTL871X: set group key camid:5 这句话出现后输入 udhcpc -i wlan0 指令重新获取 ip。若没有这句话,请检查无线网络信息是否正确。
测试是否能上网,使用 ping 指令 ping 百度,可按 ctrl+c 终止执行指令

ping www.baidu.com -I wlan0

接下来执行 testApp 程序测试:

./testApp on # 点亮 LED
./testApp off # 熄灭 LED
./testApp trigger timer # LED 会有规律的一亮一灭,被定时器控制住

在这里插入图片描述
结果与执行的一致。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/700882.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nestjs封装一个响应体

封装一个DTO // response.dto.tsimport {CallHandler,ExecutionContext,Injectable,NestInterceptor, } from "nestjs/common"; import { FastifyReply } from "fastify"; import { Observable } from "rxjs"; import { map } from "rxjs/…

数据分离和混淆矩阵的学习

1.明确意义 通过训练集建立模型的意义是对新的数据进行准确的预测&#xff08;测试集的准度高才代表good fit&#xff09;&#xff1b; 2.评估流程 3.单单利用准确率accuracy进行模型评估的局限性 模型一&#xff1a;一共1000个数据&#xff08;分别为900个1和100个0&#x…

搜索引擎的设计与实现(三)

目录 5 系统详细实现 5.1实现环境配置 5.2功能实现 5.2.1 建立索引 5.2.2 文件搜索实现 5.2.3 数据库的连接配置 5.2.4 数据库搜索实现 5.2.5 后台数据编辑实现 前面内容请移步 搜索引擎的设计与实现&#xff08;二&#xff09; 免费源代码&毕业设计论文 搜索…

8.基于鱼鹰优化算法(OOA)优化VMD参数(OOA-VMD)

代码原理 鱼鹰优化算法&#xff08;Osprey Optimization Algorithm, OOA&#xff09;是一种基于仿生学原理的启发式优化算法&#xff0c;它模拟了鱼鹰觅食的行为&#xff0c;通过调整搜索空间中的个体位置来优化目标函数。 鱼鹰优化算法可参考&#xff1a;鱼鹰优化算法(Ospre…

企业运维背后的故事:TASKCTL带你了解日常工作与技术演进

今天&#xff0c;作为一名经验丰富、从业多年经常与运维人员打交道的人&#xff0c;我想与大家聊聊运维的日常工作、部门协调以及未来发展&#xff0c;希望能为即将转行或正在从事运维工作的你&#xff0c;提供一些新的视角和启发。 运维的日常工作&#xff1a;挑战与乐趣并存 …

ConfigError: Main class ‘XXX’ doesn’t exist in the workspace.Vscode

前言 唉&#xff0c;又是被Vscode折磨的一个晚上&#xff0c;本想好好写点代码的&#xff0c;却被一个个小问题搞得团团转&#xff0c;服了。 错误原因分析 正如标题所示&#xff0c;这是扩展“Java->debug”抛出的一个错误&#xff0c;意思是这个“XXX”主类不在工作区内…

【35分钟掌握金融风控策略27】贷中风控策略与客户运营体系

目录 贷中风控策略与客户运营体系 贷中风控日标 贷中风控数据源 贷中风控策略与客户运营体系 贷中是风控的第二道防线&#xff0c;贷中阶段风控的重点工作就是存量客户风控及运营。在当下&#xff0c;新客市场趋于饱和且获客成本越来越高&#xff0c;所以&#xff0c;在做好…

【Unity Shader入门精要 第7章】基础纹理补充内容:MipMap原理

1.纹理采样 我们对纹理采样进行显示的过程&#xff0c;可以理解为将屏幕上的一个像素&#xff08;下文用像素表示&#xff09;映射到纹理上的一个像素&#xff08;下文用纹素表示&#xff09;&#xff0c;然后用纹理上的这个像素的颜色进行显示。 理想情况下&#xff0c;屏幕…

C++ 多态性

一 多态性的分类 编译时的多态 函数重载 运算符重载 运行时的多态 虚函数 1 运算符重载的引入 使用C编写程序时&#xff0c;我们不仅要使用基本数据类型&#xff0c;还要设计新的数据类型-------类类型。 一般情况下&#xff0c;基本数据类型的运算都是运算符来表达&#x…

弥合孤岛:克服构建 DevOps 文化的挑战

持续变革正在发生软件开发行业。DevOps 因其对自动化、协作和持续改进的关注而成为优化软件交付并弥合开发和运营团队之间鸿沟的重要方法。然而&#xff0c;过渡到真正的 DevOps 文化并非没有挑战。本文探讨了您在追求 DevOps 时可能面临的障碍并提供了解决方案。 01 了解 Dev…

听说SOLIDWORKS科研版可以节约研发成本?

近几年来&#xff0c;政府越来越重视科研带动产业&#xff0c;绩效优良的产业技术研究院对于国家和地区的学术成果转化、技术创新、产业发展等具有不可忽视的促进和带动作用。研究院会承担众多新产业的基础研究工作&#xff0c;而常规的基础研究需要长期的积累&#xff0c;每个…

探讨 cs2019 c++ 的STL 库中的模板 conjunction 与 disjunction

&#xff08;1&#xff09;在 STL 库源码中这俩模板经常出现&#xff0c;用来给源码编译中的条件选择&#xff0c;模板的版本选择等提供依据。先给出其定义&#xff1a; 以及&#xff1a; 可以得出结论&#xff1a; conj 是为了查找逻辑布尔型模板参数中的第一个 false &#x…