Linux led子系统分析1

Linux led子系统分析1(基于Linux6.6)---系统概述介绍

 

一、led子系统概念说明

针对led子系统而言,led子系统主要涉及两个方向的抽象:

  1. 抽象一个leddevice,记为struct led_classdev,该数据结构包括操作一个led器件的方法、led设备相关的参数(led亮度、和触发器的关联等);
  2. 抽象一个led 亮度控制方法的数据结构(又可理解为led触发器),记为struct led_trigger,其主要实现led器件的控制策略(ledtrigger-timer,则实现一个周期亮灭的触发器,亮灭的最小精度为毫秒;而ledtrigger-cpu,则是对cpu的状态进行指示,当cpu处于suspend状态时,则关闭led;当cpu处于工作状态时,则开启led。而针对mmc host创建的ledtrigger,则在mmc进行数据读写时,点亮led;mmc数据传输完成后,则关闭led)。

针对led子系统而言,主要就是这两个数据结构,同时提供了一系列的接口,用于led device、led-trigger的注册。

1. LED 子系统的架构

Linux 的 LED 子系统架构通常包括以下几个部分:

  • LED 驱动程序:这些驱动程序负责与实际的 LED 硬件交互,如点亮、熄灭或控制闪烁等。
  • LED 类和设备:在内核中,LED 设备通常被视为一种特殊类型的设备,并通过 struct led_classdev 结构体来表示。
  • sysfs 接口:通过 sysfs,用户空间可以方便地控制 LED 的状态、模式、亮度等属性。
  • 用户空间工具:例如 ledctl 等命令行工具,允许用户控制 LED 状态。

2. LED 子系统的关键概念

LED 设备(LED device)

在 Linux 内核中,LED 被表示为一种设备(通常是平台设备)。每个 LED 设备通常由一个 led_classdev 结构体表示,该结构体包含了 LED 的各种控制接口、状态信息和配置选项。

struct led_classdev 结构体的定义通常包括如下字段:

  • name: LED 设备的名称。
  • brightness: LED 的亮度。
  • max_brightness: LED 的最大亮度。
  • blink: LED 是否闪烁的状态。
  • trigger: LED 的触发条件(例如,当网络接口活动时点亮)。
  • set: 用于设置 LED 状态的回调函数。

亮度(Brightness)

LED 的亮度通常可以通过设置一个从 0 到最大值之间的整数来控制。0 表示关闭,最大值表示最亮。LED 驱动程序可以根据这个亮度值来调节硬件 LED 的电流或占空比。

闪烁(Blink)

LED 还可以设置为闪烁模式,周期性地开关。闪烁的频率和亮度的控制通常是由内核中的定时器机制来管理的。通过 blink 属性,LED 可以配置成以特定频率闪烁,或者根据某些事件(如硬盘活动、网络流量等)自动切换闪烁状态。

LED 触发器(Trigger)

LED 触发器允许根据外部事件(如按键输入、网络接口活动、系统负载等)来控制 LED 的状态。触发器可以是硬件事件(如 GPIO 引脚的变化)或软件事件(如文件系统的活动)。例如,当网络接口有数据包传输时,LED 可以被触发点亮或闪烁。

3. LED 子系统的工作流程

  1. 设备注册:LED 驱动程序通过调用 led_classdev_register() 注册一个 LED 设备,这个设备会自动出现在 /sys/class/leds/ 目录下。
  2. 属性设置:用户可以通过 sysfs 接口(位于 /sys/class/leds/ 目录下)来设置 LED 的各种属性,例如亮度(brightness)、闪烁周期(blink)等。
  3. 事件触发:LED 可以被配置为响应外部事件,如网络传输、CPU 活动等。当事件发生时,相应的 LED 会被触发,改变其状态。
  4. 卸载与清理:当不再需要 LED 时,驱动程序可以调用 led_classdev_unregister() 注销 LED 设备,清理相关资源。

二、led子系统框架简述

简要说明下led子系统的框架。如下图所示,针对led子系统可包括如下几个方面:

  1. Led trigger层包括所有注册到led子系统的trigger,而led-device可以绑定到一个指定的led-trigger,从而即为该led device绑定了一个操作方法;
  2. led子系统接口层,主要由led-device、led-trigger调用,可由具体的led device驱动调用,而liunx其他子系统模块则可以实现led-trigger,并注册至led子系统,这样led-device即可绑定到注册的led0trigger;
  3. Led device层主要完成led器件的驱动,并将led-device注册至led子系统中,该led device层直接对应到具体的led器件。

针对led-trigger、led-device,它们之间的匹配类似于设备驱动模型中的device、driver的关系,但是比设备驱动模型简单许多。一个led-device仅可绑定一个led-trigger;但一个led-trigger则可以适配多个led-device。

针对具体的开发而言,最简单的led灯即是通过gpio进行控制,而针对gpio而言,linux子系统已经抽象出统一的数据结构,并向其他子系统提供了统一的访问接口。因此针对gpio控制的led而言,led子系统实现了统一的驱动(即leds-gpio.c文件),只要是gpio控制的led,则无需实现led device驱动,另外led子系统还提供了ledtrigger-timer,实现led的周期亮灭设置,那通过leds-gpio、ledtrigger-timer这两个实现模块,即可实现led灯的闪烁、长亮、长灭控制,因此针对gpio控制的led灯,完全不需要写驱动即可实现对该led灯的控制。

另外linux子系统针对gpio、led等系统的抽象,又极大的方便开发,如上面所说的leds-gpio实现,若没有抽象出gpio子系统并提供统一的对外操作接口,就不可能抽象一个统一的leds-gpio。

针对 LED 子系统,以下是可以包括的各个方面。用框表示各个模块的主要功能:

+---------------------------------+
|      LED 设备管理               |
| - 设备注册与注销               |
| - 设备命名                     |
+---------------------------------+

+---------------------------------+
|      亮度控制                   |
| - 设置亮度 (brightness)         |
| - 获取亮度 (brightness)         |
+---------------------------------+

+---------------------------------+
|      闪烁模式                   |
| - 控制闪烁频率与周期           |
| - 设置闪烁延时 (delay_on, delay_off)|
+---------------------------------+

+---------------------------------+
|      触发器 (Triggers)          |
| - 根据系统事件自动控制 LED 状态 |
| - 例如:netdev, cpu, heartbeat  |
+---------------------------------+

+---------------------------------+
|      LED 驱动程序和硬件接口     |
| - 控制硬件接口 (GPIO, PWM等)    |
| - 与硬件平台交互               |
+---------------------------------+

+---------------------------------+
|      Sysfs 接口                 |
| - 通过 /sys 控制 LED           |
| - 读取和设置亮度、触发器等属性 |
+---------------------------------+

+---------------------------------+
|      用户空间控制               |
| - 通过命令行或应用程序控制 LED |
| - 示例:echo 命令设置 LED 状态  |
+---------------------------------+

+---------------------------------+
|      调试与状态监控             |
| - 通过日志调试 LED 状态变化    |
| - 检查 LED 当前状态            |
+---------------------------------+

+---------------------------------+
|      与平台集成                 |
| - 设备树支持                   |
| - 平台驱动与硬件平台集成       |
+---------------------------------+

每个框代表一个重要的模块或功能,所有这些模块共同构成了 Linux LED 子系统的完整架构,允许对 LED 设备进行有效的管理和控制。

三、补充知识

      hwmon、gpio、input、led以及tty、uart等都会涉及在sysfs下创建属性文件,从而可通过sysfs文件直接控制外设的参数。简要说明下,应用程序是如何访问到sysfs下的属性文件的。

如下图所示,sysfs主要是由设备驱动模型调用,而sysfs也提供了针对kobject的操作接口。

  1. 一个struct device对应到sysfs的一个目录,针对sysfs而言,目录或文件均对一个struct sysfs_dirent类型的数据结构;
  2. 针对struct device,注册了kobject的type,该type提供了device属性文件的读写接口,即dev_attr_show、dev_attr_store;
  3. 针对一个属性文件而言,其也对应一个struct sysfs_dirent类型的变量,该变量中包括该属性文件对应的属性参数(即struct device_attribute类型的变量attr);同时包含了一个struct sysfs_open_dirent类型的变量,该变量中包含了已打开的sysfs文件的私有变量(struct sysfs_buffer类型的变量,而sysfs_buffer中又包含了针对该属性文件的操作接口,也就是kobj_type->sysfs_ops(也就是dev_attr_show、dev_attr_store))。
  4. 针对文件描述符struct file,当打开一个sysfs文件后,则在其open接口中设置file->private_data=(struct sysfs_buffer*)buffer(该buffer中已经提供了属性文件的操作接口dev_sysfs_ops);这样当对sysfs进行读写操作时,继而调用dev_attr_show/dev_attr_store进行操作,而在dev_attr_show/dev_attr_store中,则最终调用属性文件已创建的device_attribute->store/show接口
  5. 针对一个struct device相关的属性文件的创建,只需要调用接口sysfs_create_group即可创建相应的属性文件。

通过下面的关联图,把device、sysfs、vfs、task_struct做了关联,借助vfs、task_struct,即实现了与sysfs的关联。

目前的好多设备驱动子系统均会创建sysfs属性文件供应用程序访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值