原子学习笔记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); //先将触发模式设置为 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 属性文件;程序首先会调用 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 会有规律的一亮一灭,被定时器控制住

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

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值