Linux系统点亮LED

news2024/10/6 12:20:04

目录

  • 应用层操控硬件的两种方式
    • sysfs 文件系统
    • sysfs 与/sys
    • 总结
    • 标准接口与非标准接口
  • LED 硬件控制方式
  • 编写LED 应用程序
  • 在开发板上测试

对于一款学习型开发板来说,永远都绕不开LED 这个小小的设备,基本上每块板子都至少会有一颗
LED 小灯,对于我们的ALPHA/Mini I.MX6U 开发板来说同样也是如此。
ALPHA/Mini I.MX6U 开发板(包括核心板和底板)上一共有3 颗LED 小灯,当仅有一颗LED 能够被用户所控制,其它两颗均作为电源指示灯而存在,用户对其不可控制;LED 通常是由GPIO 所控制的,本章我们来学习如何编写应用程序控制LED 灯的亮灭。

应用层操控硬件的两种方式

在Linux 系统下,一切皆文件!应用层如何操控底层硬件,同样也是通过文件I/O 的方式来实现,前面我们给大家介绍了设备文件,包括字符设备文件和块设备文件,为啥叫设备文件?大家有没有想过这个问题呢?其实设备文件便是各种硬件设备向应用层提供的一个接口,应用层通过对设备文件的I/O 操作来操控硬件设备,譬如LCD 显示屏、串口、按键、摄像头等等,所以设备文件其实是与硬件设备相互对应的。设备文件通常在/dev/目录下,我们也把/dev 目录下的文件称为设备节点。
设备节点并不是操控硬件设备的唯一途径,除此之外,我们还可以通过sysfs 文件系统对硬件设备进行操控,接下来将进行介绍!

sysfs 文件系统

简单的说,sysfs 是一个基于内存的文件系统,同devfs、proc 文件系统一样,称为虚拟文件系统;它的作用是将内核信息以文件的方式提供给应用层使用。7.7 小节中我们学习过proc 文件系统,应用层可以通过
proc文件系统得到系统信息和进程相关信息,与proc文件系统类似,sysfs 文件系统的主要功能便是对系统设备进行管理,它可以产生一个包含所有系统硬件层次的视图。
sysfs 文件系统把连接在系统上的设备和总线组织成为一个分级的文件、展示设备驱动模型中各组件的层次关系。sysfs 提供了一种机制,可以显式的描述内核对象、对象属性及对象间关系,用来导出内核对象
(kernel object,譬如一个硬件设备)的数据、属性到用户空间,以文件目录结构的形式为用户空间提供对这些数据、属性的访问支持。表15.1.1 描述了内核对象、对象属性及对象间关系在用户空间sysfs 中的的表现:
在这里插入图片描述

sysfs 与/sys

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

总结

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

标准接口与非标准接口

Linux 内核中为了尽量降低驱动开发者难度以及接口标准化,就出现了设备驱动框架的概念;Linux 针对各种常见的设备进行分类,譬如LED 类设备、输入类设备、FrameBuffer 类设备、video 类设备、PWM 设备等等,并为每一种类型的设备设计了一套成熟的、标准的、典型的驱动实现的框架,这个就叫做设备驱动框架。设备驱动框架为驱动开发和应用层提供了一套统一的接口规范,譬如对LED 类设备来说,内核提供了LED 设备驱动框架,驱动工程师编写LED 驱动时,使用LED 驱动框架来开发自己的LED 驱动程序,这样做的好处就在于,能够对上层应用层提供统一、标准化的接口、同时又降低了驱动开发工程师的难度。
编写LED 驱动程序并不仅仅只能使用内核设计的LED 设备驱动框架,不用内核的LED 驱动框架也是可以开发出LED 驱动程序的,但如果你这样写,使用这个驱动程序注册的LED 那就不是标准设备了,因为该驱动程序向应用层提供的接口并不是统一、标准化接口。
除此之外,还有很多硬件外设,尤其是嵌入式系统中所使用到的这些硬件外设,它们可能并不属于Linux
系统所规划的设备分类当中的任何一种设备类型,譬如在Linux 系统中,有一种设备类型叫杂散/杂项类设备(misc device),大家可以想一想为啥叫杂散类设备,说明这种设备既不属于这种设备类型、又不属于另一种设备类型,无奈只能把它归为杂项类。
因为一个计算机系统所能够连接、使用的外设实在太多了,不可能每一种外设都能够精准地分类到某一个设备类型中,通常把这些无法进行分类的外设就称为杂项设备,杂项设备驱动程序向应用层提供的接口通常都不是标准化接口、它是一种非标准接口,具体如何去操控这个设备通常只有驱动工程师知道。所以在嵌入式系统中,很多硬件外设的驱动程序都是定制的。

LED 硬件控制方式

ALPHA/Mini I.MX6U 开发板底板上有一颗可被用户控制的LED 灯,如下所示:
在这里插入图片描述
上图中箭头所指的LED 便是开发板上唯一一个可以被用户所控制的LED,另外一颗LED 则(名称为
PWR)是底板上的电源指示灯。
对于ALPHA/Mini I.MX6U 开发板出厂系统来说,此LED 设备使用的是Linux 内核标准LED 驱动框架注册而成,在/dev 目录下并没有其对应的设备节点,其实现使用sysfs 方式控制。进入到/sys/class/leds 目录下,如下所示:
在这里插入图片描述
上小节介绍了/sys/class 目录,系统中的所有设备根据其功能分类组织到了/sys/class 目录下,所以
/sys/class/leds 目录下便存放了所有的LED 类设备。从上图可以看到该目录下有一个sys-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 值的正整数)两种状态,ALPHA/Mini I.MX6U
开发板上的这颗LED 就是如此,所以自然就不存在亮度等级一说,只有亮和灭两种亮度等级。
⚫ max_brightness:该属性文件只能被读取,不能写,用于获取LED 设备的最大亮度等级。
⚫ trigger:触发模式,该属性文件可读可写,读表示获取LED 当前的触发模式,写表示设置LED 的触发模式。不同的触发模式其触发条件不同,LED 设备会根据不同的触发条件自动控制其亮、灭状态,通过cat 命令查看该属性文件,可获取LED 支持的所有触发模式以及LED 当前被设置的触发模式:

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

通常系统启动之后,会将板子上的一颗LED 设置为heartbeat 触发模式,将其作为系统正常运行的指示灯,譬如ALPHA/Mini I.MX6U 开发板系统启动之后,底板上的用户LED 就会处于心跳呼吸模式,这个大家自己观察便可知道。
通过上面的介绍,已经知道如何去控制ALPHA/Mini I.MX6U 开发板底板上的用户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 的效果。
Tips:命令cat 读取以及echo 写入到属性文件中的均是字符串,所以如果在应用程序中通过write()向属性文件写入数据,同样也要是字符串形式;同理,使用read()读取的数据也是字符串ASCII 编码的。

编写LED 应用程序

通过上一小节的介绍,我们已经知道了如何控制LED,接下来编写一个简单地示例代码演示如何控制
LED,测试代码如下所示:
本例程源码对应的路径为:开发板光盘->11、Linux C 应用编程例程源码->15_led->led.c。

#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); //先将触发模式设置为none
                write(fd2, "1", 1); //点亮LED
        }
        else if (!strcmp(argv[1], "off")) {
                write(fd1, "none", 4); //先将触发模式设置为none
                write(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");
        }
        else
                USAGE();
        exit(0);
}

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

整个代码非常简单,接下来对测试代码进行编译,需要注意的时,由于我们是在ALPHA/Mini I.MX6U
开发板上运行程序,所以需要I.MX6U 平台对应的交叉编译工具来编译测试代码,这样编译得到的可执行文件才能在开发板上运行。
首先大家需要安装I.MX6U 硬件平台对应的交叉编译工具,如何安装呢?直接参考“开发板光盘资料
A-基础资料/【正点原子】I.MX6U 用户快速体验V1.7.3.pdf”文档中的第四章内容,根据文档的指示安装好交叉编译工具,当然如果你已经在Ubuntu 系统下安装过了,就不用再次安装了。
安装完成之后,在使用之前先对交叉编译工具的环境进行设置,使用source 执行安装目录下的
environment-setup-cortexa7hf-neon-poky-linux-gnueabi 脚本文件即可,如下所示:

source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi

/opt/fsl-imx-x11/4.1.15-2.1.0 便是笔者在Ubuntu 系统下安装交叉编译工具时对应的安装目录,大家根据自己的情况设置正确的路径。处理完成之后,接下来我们便可以对示例代码15.3.1 进行编译了:
在这里插入图片描述
CC 变量其实就是交叉编译工具,如下所示:
在这里插入图片描述
所以CC 环境变量其实就是ARM 架构下的gcc 编译器—交叉编译工具arm-poky-linux-gnueabi-gcc,后面指定了一些选项,这些选项就不用管了;编译成功之后,会生成可在开发板上运行的可执行文件testApp,使用file 命令可以查看testApp 可执行文件的类型:
在这里插入图片描述
可以看出该文件是一个32 位ARM 架构下的可执行文件。

在开发板上测试

启动开发板进入Linux 系统,将上小节编译得到的可执行文件testApp 拷贝到开发板根文件系统中,譬如拷贝到开发板Linux 系统的家目录下,如下图所示:
在这里插入图片描述
拷贝方法很多,推荐大家使用scp 命令,这里就不再介绍了。
接下来执行testApp 程序测试:

./testApp on # 点亮LED
./testApp off # 熄灭LED
./testApp trigger heartbeat # 将LED 触发模式设置为heartbeat

在这里插入图片描述
查看LED 状态是否与程序执行的效果一致!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Allegro无法打开10度走线命令的原因和解决办法

Allegro无法打开10度走线命令的原因和解决办法 做PCB设计的时候,10度走线也是较为常见的设计方式,Allegro支持10度走线,如下图 需要10度走线的时候,Options只需要勾选Route offset命令即可 但有时options处会看不到10度走线的命令,如下图

从0到1一步一步玩转openEuler--20 openEuler 管理服务-服务管理

文章目录20 管理系统服务20.1 sysvinit命令和systemd命令20.2 显示所有当前服务20.3 显示服务状态20.4 运行服务20.5 关闭服务20.6 重启服务20.7 启用服务20.8 禁用服务20 管理系统服务 systemd提供systemctl命令来运行、关闭、重启、显示、启用/禁用系统服务。 20.1 sysvini…

开源社首届正式成员大会暨2022年度总结会圆满召开

开源社KAIYUANSHE近期微信公众号订阅功能做调整啦&#xff01;没有被星标的账号在信息流里可能不显示大图了&#xff01;快星标⭐我们&#xff0c;就可以及时看到发布的文章啦&#xff01;STEP01 点击右上角标志STEP02 点击【设为星标】开源社 2023 年度首届全体正式成员大会于…

【2】linux命令每日分享——ls列出目录和文件

大家好&#xff0c;这里是sdust-vrlab&#xff0c;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;Linux的基本思想有两点&#xff1a;一切都是文件&#xff1b;每个文件都有确定的用途&#xff1b;linux涉及到IT行业的方方面面&#xff0c;在我们日常的学习中&…

快速制作一个chrome插件

说在前面 在我日常开发以及娱乐生活中&#xff0c;浏览器是我使用频率较高的一个应用&#xff0c;当我大学拥有第一部电脑开始&#xff0c;之后不论电脑换成什么&#xff0c;以及使用的是什么系统&#xff0c;我的首选浏览器都是Chrome&#xff0c;不仅仅是因为其速度快&#x…

Jetpack之ViewModel

The ViewModel class is a business logic or screen level state holder. 上面是官方给的定义&#xff0c;ViewModel 类是业务逻辑或屏幕级状态持有者。 一、业务逻辑持有者 在此之前&#xff0c;无论是MVC模式&#xff0c;还是MVP模式&#xff0c;在视图层&#xff0c;都会…

简化客户服务操作的最佳方式:客户服务响应模板

关键词&#xff1a;客户服务响应模板&#xff1b;SaleSmartly&#xff08;ss客服&#xff09; 客户服务响应模板可以通过提供标准响应来帮助简化客户服务操作。这些客户服务模板可用于各种目的和方案&#xff0c;包括欢迎客户、回复查询、结束对话、请求评论等。请继续阅读&am…

2022年全国职业院校技能大赛(中职组)网络安全竞赛试题A(5)

目录 模块A 基础设施设置与安全加固 一、项目和任务描述&#xff1a; 二、服务器环境说明 三、具体任务&#xff08;每个任务得分以电子答题卡为准&#xff09; A-1任务一 登录安全加固&#xff08;Windows&#xff09; 1.密码策略 a.密码策略必须同时满足大小写字母、数…

【ICLR 2022】重新思考点云中的网络设计和局部几何:一个简单的残差MLP框架

文章目录RETHINKING NETWORK DESIGN AND LOCAL GEOMETRY IN POINT CLOUD: A SIMPLE RESIDUAL MLP FRAMEWORKPointMLP残差点模块几何仿射模块精简版模型&#xff1a;PointMLP-elite实验结果消融实验RETHINKING NETWORK DESIGN AND LOCAL GEOMETRY IN POINT CLOUD: A SIMPLE RESI…

电容的参数-详细描述

贴片电容 如同如所示&#xff0c;MLCC&#xff08;Multi-layer Ceramic Capacitors&#xff09;&#xff0c;外形很好区分。 实际内部结构 使用的还是平行板电容器原理&#xff0c;只是这个是叠层结构&#xff1b;电解电容是卷起来的圆柱状&#xff1b; 容值&#xff1a; …

ChatGPT风口下的中外“狂飙”,一文看懂微软、谷歌、百度、腾讯、华为、字节跳动们在做什么?

毫无疑问&#xff0c;ChatGPT正成为搅动市场情绪的buzzword。 历史经历过无线电&#xff0c;半导体&#xff0c;计算机&#xff0c;移动通讯&#xff0c;互联网&#xff0c;移动互联网&#xff0c;社交媒体&#xff0c;云计算等多个时代&#xff0c;产业界也一直在寻找Next Big…

ElementUI--Dialog 弹框的使用

第一步&#xff1a;从官方文档中拷贝一个对话框到你的页面中 <el-dialog title"为中华民族之崛起而学习" :visible.sync"dialogVisible" width"30%" :fullscreen"false" :close-on-press-escape"false" show-close:close…

大数据处理学习笔记1.4 掌握Scala运算符

文章目录零、本讲学习目标一、运算符等价于方法&#xff08;一&#xff09;运算符即方法&#xff08;二&#xff09;方法即运算符1、单参方法2、多参方法3、无参方法二、Scala运算符&#xff08;一&#xff09;运算符分类表&#xff08;二&#xff09;Scala与Java运算符比较三、…

买什么样的运动型蓝牙耳机好、运动型蓝牙耳机推荐

如今耳机是我们生活中很常见的数码产品了&#xff0c;在街上看到跑步、骑行&#xff0c;室内健身房&#xff0c;都能看到大家人手一副耳机&#xff0c;运动耳机已经成为很多人的运动必备品&#xff0c;因大众佩戴耳机的种类和风格有所不同&#xff0c;这也造就了市场上琳琅满目…

零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]

原创首发于CSDN&#xff0c;转载请注明出处&#xff0c;谢谢&#xff01; 文章目录为何会在Linux下开发单片机个人系统环境与所用开发板安装开源编译器 sdccSTC MCU ISP 闪存工具 stcgal 的安装单片机代码的编译与测试&#xff5c;编写主代码 main.c&#xff5c;使用 sdcc 编译…

基于龙芯 2K1000 的嵌入式 Linux 系统移植和驱动程序设计

2.1 需求分析 本课题以龙芯 2K1000 处理器为嵌入式系统的处理器&#xff0c;需要实现一个完成的嵌 入式软件系统&#xff0c;系统能够正常启动并可以稳定运行嵌入式 Linux。设计网络设备驱 动&#xff0c;可以实现板卡与其他网络设备之间的网络连接和文件传输。设计 PCIE 设备驱…

新时代下的医疗行业新基建研讨会

1、会议纪要 2023年2月17日&#xff0c;HIT专家网进行了《新时代下的医疗行业新基建研讨会》的会议。 对会议内容进行了记录。 会议中有友谊医院、301、北肿主任进行了分享。大纲如下所示 2、本人所想 本人的所想所感&#xff1a; 1、301在多院区的医疗信息建设&#xff0c…

程序员遇到人生低谷期怎么做?

每个人的一生都是起起伏伏的&#xff0c;你不会天天高潮&#xff0c;总会经历一段又一段的不如意&#xff0c;你怎么把握这一段段时间&#xff0c;如何掌控人生节奏&#xff0c;都源于对人生低谷期的回答。 尤其是2022年&#xff0c;程序员受到的冲击并不小&#xff0c;从年初…

车辆调度混乱?看DHTMLX Gantt 如何提高企业调度管理效率

我们公司有一个车辆调度系统&#xff0c;目前能对小规模车队的进行简单管理。但是随着公司的业务越来越复杂&#xff0c;需要调度的车辆种类和人员安排越来越困难&#xff0c;经常出现因安排不当导致货物无车可送或车辆集中闲置情况发生&#xff0c;非常影响货运效率&#xff0…

谈谈接口和抽象类有什么区别?

第13讲 | 谈谈接口和抽象类有什么区别&#xff1f; Java 是非常典型的面向对象语言&#xff0c;曾经有一段时间&#xff0c;程序员整天把面向对象、设计模式挂在嘴边。虽然如今大家对这方面已经不再那么狂热&#xff0c;但是不可否认&#xff0c;掌握面向对象设计原则和技巧&am…