1)实验平台:正点原子阿尔法Linux开发板
2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434
2)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-300792-1-1.html
3)对正点原子Linux感兴趣的同学可以加群讨论:935446741
4)关注正点原子公众号,获取最新资料更新

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

16.1应用层操控硬件的两种方式
在Linux系统下,一切皆文件!应用层如何操控底层硬件,同样也是通过文件I/O的方式来实现,前面我们给大家介绍了设备文件,包括字符设备文件和块设备文件,为啥叫设备文件?大家有没有想过这个问题呢?其实设备文件便是各种硬件设备向应用层提供的一个接口,应用层通过对设备文件的I/O操作来操控硬件设备,譬如LCD显示屏、串口、按键、摄像头等等,所以设备文件其实是与硬件设备相互对应的。设备文件通常在/dev/目录下,我们也把/dev目录下的文件称为设备节点。
设备节点并不是操控硬件设备的唯一途径,除此之外,我们还可以通过sysfs文件系统对硬件设备进行操控,接下来将进行介绍!
16.1.1sysfs文件系统
简单的说,sysfs是一个基于内存的文件系统,同devfs、proc文件系统一样,称为虚拟文件系统;它的作用是将内核信息以文件的方式提供给应用层使用。7.7小节中我们学习过proc文件系统,应用层可以通过proc文件系统得到系统信息和进程相关信息,与proc文件系统类似,sysfs文件系统的主要功能便是对系统设备进行管理,它可以产生一个包含所有系统硬件层次的视图。
sysfs文件系统把连接在系统上的设备和总线组织成为一个分级的文件、展示设备驱动模型中各组件的层次关系。sysfs提供了一种机制,可以显式的描述内核对象、对象属性及对象间关系,用来导出内核对象(kernel object,譬如一个硬件设备)的数据、属性到用户空间,以文件目录结构的形式为用户空间提供对这些数据、属性的访问支持。表 15.1.1描述了内核对象、对象属性及对象间关系在用户空间sysfs中的的表现:
内核中的组成要素 sysfs中的表现
内核对象(譬如一个硬件设备) 目录
对象属性(譬如设备属性) 文件
对象关系 链接文件
表 15.1.1 内核对象、对象属性及对象间关系在用户空间的表现
16.1.2sysfs与/sys
sysfs文件系统挂载在/sys目录下,启动阿尔法I.MX6U Linux开发板,进入Linux系统(本篇使用的是出厂烧录的系统)之后,我们进入到/sys目录下查看,如下所示:

图 16.1.1 /sys目录
上图显示的便是sysfs文件系统中的目录,包括block、bus、class、dev、devices、firmware、fs、kernel、modules、power等,每个目录下又有许多文件或子目录,对这些目录的说明如所示:
/sys下的子目录 说明
/dev/devices 这是系统中所有设备存放的目录,也就是系统中的所有设备在sysfs中的呈现、表达,也是sysfs管理设备的最重要的目录结构。
/dev/block 块设备的存放目录,这是一个过时的接口,按照sysfs的设计理念,系统所有的设备都存放在/sys/devices目录下,所以/dev/block目录下的文件通常是链接到/sys/devices目录下的文件。
/dev/bus 这是系统中的所有设备按照总线类型分类放置的目录结构,/sys/devices目录下每一种设备都是挂在某种总线下的,譬如i2c设备挂在I2C总线下。同样,/dev/bus目录下的文件通常也是链接到了/sys/devices目录。
/dev/class 这是系统中的所有设备按照其功能分类放置的目录结构,同样该目录下的文件也是链接到了/sys/devices目录。按照设备的功能划分组织在/dev/class目录下,譬如/sys/class/leds目录中存放了所有的LED设备,/sys/class/input目录中存放了所有的输入类设备。
/dev/dev 这是按照设备号的方式放置的目录结构,同样该目录下的文件也是链接到了/sys/devices目录。该目录下有很多以主设备号:次设备号(major:minor)命名的文件,这些文件都是链接文件,链接到/sys/devices目录下对应的设备。
/dev/firmware 描述了内核中的固件。
/dev/fs 用于描述系统中所有文件系统,包括文件系统本身和按文件系统分类存放的已挂载点。
/dev/kernel 这里是内核中所有可调参数的位置。
/dev/module 这里有系统中所有模块的信息。
/dev/power 这里是系统中电源选项,有一些属性可以用于控制整个系统的电源状态。
表 15.1.2 /sys目录结构
系统中所有的设备(对象)都会在/dev/devices体现出来,是sysfs文件系统中最重要的目录结构;而/dev/bus、/dev/class、/dev/dev分别将设备按照挂载的总线类型、功能分类以及设备号的形式将设备组织存放在这些目录中,这些目录下的文件都是链接到了/dev/devices中。
设备的一些属性、数据通常会通过设备目录下的文件体现出来,也就是说设备的数据、属性会导出到用户空间,以文件形式为用户空间提供对这些数据、属性的访问支持,可以把这些文件称为属性文件;读这些属性文件就表示读取设备的属性信息,相反写属性文件就表示对设备的属性进行设置、以控制设备的状态。
16.1.3总结
这里给大家进行一个总结,应用层想要对底层硬件进行操控,通常可以通过两种方式:
/dev/目录下的设备文件(设备节点);
/sys/目录下设备的属性文件。
具体使用哪种方式需要根据不同功能类型设备进行选择,有些设备只能通过设备节点进行操控,而有些设备只能通过sysfs方式进行操控;当然跟设备驱动具体的实现方式有关,通常情况下,一般简单地设备会使用sysfs方式操控,其设备驱动在实现时会将设备的一些属性导出到用户空间sysfs文件系统,以属性文件的形式为用户空间提供对这些数据、属性的访问支持,譬如LED、GPIO等。
但对于一些较复杂的设备通常会使用设备节点的方式,譬如LCD等、触摸屏、摄像头等。
16.2LED硬件控制方式
阿尔法I.MX6U Linux开发板底板上有一颗可被用户控制的LED灯,如下所示:

图 16.2.1 用户LED灯
上图中箭头所指的LED便是开发板上唯一一个可以被用户所控制的LED(名称为DS0),上面的那颗LED(名称为PWR)是底板的电源指示灯。
对于阿尔法I.MX6U Linux开发板出厂系统来说,此LED设备使用的是Linux内核标准LED驱动框架注册而成,在/dev目录下并没有其对应的设备节点,其实现使用sysfs方式控制。进入到/sys/class/leds目录下,如下所示:

图 16.2.2 /sys/class/leds目录
上小节介绍了/sys/class目录,系统中的所有设备根据其功能分类组织到了/sys/class目录下,所以/sys/class/leds目录下便存放了所有的LED类设备。从上图可以看到该目录下有一个sys-led文件夹,这个便是底板上的用户LED设备文件夹,进入到该目录下,如下所示:

图 16.2.3 sys-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值的正整数)两种状态,阿尔法板子上的这颗LED就是如此,所以自然就不存在亮度等级一说,只有亮和灭。
max_brightness:该属性文件只能被读取,不能写,用于获取LED设备的最大亮度等级。
trigger:触发模式,该属性文件可读可写,读表示获取LED当前的触发模式,写表示设置LED的触发模式。不同的触发模式其触发条件不同,LED设备会根据不同的触发条件自动控制其亮、灭状态,通过cat命令查看该属性文件,可获取LED支持的所有触发模式以及LED当前被设置的触发模式:

图 16.2.4 LED支持的所有触发模式
方括号([heartbeat])括起来的表示当前LED对应的触发模式,none表示无触发,常用的触发模式包括none(无触发)、mmc0(当对mmc0设备发起读写操作的时候LED会闪烁)、timer(LED会有规律的一亮一灭,被定时器控制住)、heartbeat(心跳呼吸模式,LED模仿人的心跳呼吸那样亮灭)。
通常系统启动之后,会将板子上的一颗LED设置为heartbeat触发模式,将其作为系统正常运行的指示灯,譬如阿尔法Linux开发板系统启动之后,底板上的用户LED就会处于心跳呼吸模式,这个大家自己观察便可知道。
通过上面的介绍,已经知道如何去控制阿尔法底板上的用户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编码的。
16.3编写LED应用程序
本例程源码对应的路径为:开发板光盘->11、Linux C应用编程例程源码->16_led->led.c。
通过上一小节的介绍,我们已经知道了如何控制LED,接下来编写一个简单地示例代码演示如何控制LED,测试代码如下所示:
示例代码 16.3.1 LED应用程序

#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属性文件,宏USAGE()用于打印程序的使用方法;程序首先会调用open()函数打开这两个属性文件,之后判断传入参数指向相应的动作,传入"on"表示点亮LED,先调用write()将"none"写入到trigger属性文件中,也就是设置为无触发,接着再向brightness属性文件中写入"1"点亮LED;传入"off"表示熄灭LED,同样也是先调用write()将"none"写入到trigger属性文件设置LED为无触发,接着再向brightness属性文件中写入"0"熄灭LED;传入"trigger"表示设置LED的触发模式,则需要传入第二个参数,第二个参数表示需要设置的模式。
整个代码非常简单,接下来对测试代码进行编译,需要注意的时,由于我们是在阿尔法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进行编译了:

图 16.3.1 交叉编译应用程序
CC变量其实就是交叉编译工具,如下所示:

图 16.3.2 变量CC
所以CC环境变量其实就是ARM架构下的gcc编译器—交叉编译工具arm-poky-linux-gnueabi-gcc,后面指定了一些选项,这些选项就不用管了;编译成功之后,会生成可在阿尔法IMX6U开发板上运行的可执行文件testApp,使用file命令可以查看testApp可执行文件的类型:

图 16.3.3 testApp文件类型
可以看出该文件是一个32位ARM架构下的可执行文件。
16.4在开发板上测试
启动开发板进入Linux系统,将上小节编译得到的可执行文件testApp拷贝到开发板根文件系统中,譬如拷贝到开发板Linux系统的家目录下,如下图所示:

图 16.4.1 testApp拷贝到开发板
拷贝方法很多,推荐大家使用scp命令,这里就不再介绍了。
接下来执行testApp程序测试:

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

图 16.4.2 测试结果
查看LED状态是否与程序执行的效果一致!

【正点原子Linux连载】第十五章点亮LED-摘自【正点原子】I.MX6U嵌入式Linux C应用编程指南V1.1相关推荐

  1. 【正点原子Linux连载】第五章 文件属性与目录-摘自【正点原子】I.MX6U嵌入式Linux C应用编程指南V1.1

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  2. 【正点原子STM32连载】第四十五章 SD卡实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  3. 异步fifo_正点原子开拓者FPGA开发板资料连载第十五章 IP核之FIFO实验

    1)实验平台:正点原子开拓者FPGA 开发板 2)摘自<开拓者FPGA开发指南>关注官方微信号公众号,获取更多资料:正点原子 3)全套实验源码+手册+视频下载地址:http://www.o ...

  4. 【正点原子STM32连载】 第十五章 按键输入实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

    1)实验平台:正点原子stm32f103战舰开发板V4 2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420 3)全套实验源码+手册+视 ...

  5. 【正点原子Linux连载】第十四章 Qt控制LED 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  6. 【正点原子Linux连载】第十七章GPIO中断试验-摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  7. 32 串口波特率_「正点原子FPGA连载」第五章串口中断实验

    1)实验平台:正点原子达芬奇FPGA开发板 2) 摘自[正点原子]达芬奇之Microblaze 开发指南 3)购买链接:https://detail.tmall.com/item.htm?id=624 ...

  8. 【正点原子MP157连载】 第五章 STM32MP1启动详解-摘自【正点原子】【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  9. 【正点原子Linux连载】第五章 RKMedia编译和使用 摘自【正点原子】ATK-DLRV1126系统开发手册

    第五章 RKMedia编译和使用 5.1 RKMedia编译 Rkmedia是RK官方封装一层简易的API,把RGA.MPP.RKNN等等这些接口封装成高级的接口.在SDK官方的源码目录下,运行以下命 ...

最新文章

  1. 今天写了个Win32服务设置软件,呵呵,纯绿色软件
  2. python回归分析预测模型_Python与线性回归模型预测房价
  3. Redis的8大数据类型,写的真好
  4. leetcode 190 python
  5. Linux下source命令
  6. nacl溶解度_运用溶解度曲线判断混合物分离、提纯的方法
  7. 如何向枚举中添加新值
  8. 2.1.1 理论模型
  9. npm查看源地址以及更换源地址
  10. IT女神说自然语言处理(1)----LDA
  11. [个人笔记]HCIP-Routing Switching-IEEP/H12-223
  12. windows核心编程--2、windows的画笔画刷以及一些简单的应用
  13. 网络营销与传统营销的区别
  14. 【找不到SQL Server ODBC 驱动程序的安装例程】的解决
  15. [原创] 利用busybox, extlinux 在工控机CompactFlash(CF卡)上构建Linux系统(上)
  16. 广州IATF16949认证_广州IATF16949咨询_8.3.3.3特殊特性
  17. 千兆TCP拥塞控制算法分析
  18. 第6章——马斯洛:需要层次理论
  19. 二 需求工程和设计模式
  20. 【狮子数学】chapter4-02-偏导数的计算(第78——80)

热门文章

  1. [转] C#开源项目大全
  2. Bootstrap Metronic 学习记录(一)简介
  3. a星算法实现8数码问题c语言,A星算法求八数码问题实验报告.doc
  4. [会议系统 | 手拉手会议]100㎡手拉手会议系统解决方案
  5. 微信小程序的基础知识点汇总
  6. 学习CSS Scroll Snapping与scroll-snap-align
  7. mybatis plus查询上个月和本月的数据
  8. Three.js学习
  9. 个人永久性免费-Excel催化剂功能第17波-批量文件改名、下载、文件夹创建等
  10. 用canvas实现刮刮卡特效