1.在 Linux 系统下,一切皆文件!应用层如何操控底层硬件,同样也是通过文件 I/O 的方式来实现。
设备文件通常在/dev/目录下,我们也把/dev 目录下的文件称为设备节点。
设备节点并不是操控硬件设备的唯一途径,除此之外,我们还可以通过 sysfs 文件系统对硬件设备进行
操控。
2.sysfs 是一个基于内存的文件系统, 同 devfs、 proc 文件系统一样,称为虚拟文件系统;它的作用是将内核信息以文件的方式提供给应用层使用。
sysfs 文件系统把连接在系统上的设备和总线组织成为一个分级的文件、 展示设备驱动模型中各组件的层次关系。
sysfs 提供了一种机制,可以显式的描述内核对象、对象属性及对象间关系, 用来导出内核对象(kernel object,譬如一个硬件设备)的数据、属性到用户空间,以文件目录结构的形式为用户空间提供对这些数据、属性的访问支持。
3.sysfs 文件系统挂载在/sys 目录下,启动 I.MX6U 开发板,进入 Linux 系统(开发板出厂系统) 之后,我们进入到/sys 目录下查看
上图显示的便是 sysfs 文件系统中的目录,包括 block、 bus、 class、 dev、 devices、 firmware、 fs、 kernel、modules、 power 等,每个目录下又有许多文件或子目录,对这些目录的说明如所示:
/sys 下的子目录说明
/sys/devices
这是系统中所有设备存放的目录, 也就是系统中的所有设备在 sysfs 中的呈现、表达,也是 sysfs 管理设备的最重要的目录结构。
/sys/block
块设备的存放目录,这是一个过时的接口,按照 sysfs 的设计理念,系统所有的设备都存放在/sys/devices 目录下,所以/sys/block 目录下的文件通常是链接到/sys/devices 目录下的文件。
/sys/bus
这是系统中的所有设备按照总线类型分类放置的目录结构, /sys/devices 目录下每一种设备都是挂在某种总线下的,譬如 i2c 设备挂在 I2C 总线下。同样, /sys/bus 目录下的文件通常也是链接到了/sys/devices 目录。
/sys/class
这是系统中的所有设备按照其功能分类放置的目录结构,同样该目录下的文件也是链接到了/sys/devices 目录。 按照设备的功能划分组织在/sys/class 目录下,譬如/sys/class/leds目录中存放了所有的 LED 设备, /sys/class/input 目录中存放了所有的输入类设备。
/sys/dev
这是按照设备号的方式放置的目录结构,同样该目录下的文件也是链接到了/sys/devices 目录。该目录下有很多以主设备号:次设备号(major:minor)命名的文件,这些文件都是链接文件,链接到/sys/devices 目录下对应的设备。
/sys/firmware 描述了内核中的固件。
/sys/fs
用于描述系统中所有文件系统,包括文件系统本身和按文件系统分类存放的已挂载点。
/sys/kernel 这里是内核中所有可调参数的位置。
/sys/module 这里有系统中所有模块的信息。
/sys/power
这里是系统中电源选项,有一些属性可以用于控制整个系统的电源状态。
系统中所有的设备(对象)都会在/sys/devices 体现出来,是 sysfs 文件系统中最重要的目录结构;
而/sys/bus、 /sys/class、 /sys/dev 分别将设备按照挂载的总线类型、功能分类以及设备号的形式将设备组织存放在这些目录中,这些目录下的文件都是链接到了/sys/devices 中
4.应用层想要对底层硬件进行操控,通常可以通过两种方式:
1) /dev/目录下的设备文件(设备节点) ;
2) /sys/目录下设备的属性文件。
其设备驱动在实现时会将设备的一些属性导出到用户空间 sysfs 文件系统,以属性文件的形式为用户空间提供对这些数据、属性的访问支持,譬如 LED、 GPIO 等。
5./sys/class 目录,系统中的所有设备根据其功能分类组织到了/sys/class 目录下,所以/sys/class/leds 目录下便存放了所有的 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 值的正整数)两种状态,I.MX6U开发板上的这颗 LED 就是如此,所以自然就不存在亮度等级一说,只有亮和灭两种亮度等级。
max_brightness: 该属性文件只能被读取,不能写,用于获取 LED 设备的最大亮度等级。
trigger: 触发模式,该属性文件可读可写,读表示获取 LED 当前的触发模式,写表示设置 LED 的触发模式。 不同的触发模式其触发条件不同, LED 设备会根据不同的触发条件自动控制其亮、灭状态, 通过 cat 命令查看该属性文件,可获取 LED 支持的所有触发模式以及 LED 当前被设置的触发模式:
none 表示无触发,常用的触发模式包括none(无触发)、
mmc0(当对 mmc0 设备发起读写操作的时候 LED 会闪烁)、
timer(LED 会有规律的一亮一灭,被定时器控制住)、
heartbeat(心跳呼吸模式, LED 模仿人的心跳呼吸那样亮灭变化)。
6.通过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 的效果。