Linux内核之LED子系统(二)

这里说一说led子系统的一些核心源代码文件,是如何实现led子系统。
这里重点关注内核部分的实现:
对于内核中需要重点关注的几个文件如下:
driver/leds/led-class.cdriver/leds/led-core.cdriver/leds/led-triggers.cinclude/linux/leds.h1. led设备管理
driver/leds/led-class.c
led设备的注册和注销实现都在该函数,这里看看里面的重要结构体
struct led_classdev { const char *name; enum led_brightness brightness; enum led_brightness max_brightness; int flags; /* lower 16 bits reflect status */#define led_suspended bit(0)#define led_unregistering bit(1) /* upper 16 bits reflect control information */#define led_core_suspendresume bit(16)#define led_sysfs_disable bit(17)#define led_dev_cap_flash bit(18)#define led_hw_pluggable bit(19)#define led_panic_indicator bit(20)#define led_bright_hw_changed bit(21)#define led_retain_at_shutdown bit(22)#define led_init_default_trigger bit(23) /* set_brightness_work / blink_timer flags, atomic, private. */ unsigned long work_flags;#define led_blink_sw 0#define led_blink_oneshot 1#define led_blink_oneshot_stop 2#define led_blink_invert 3#define led_blink_brightness_change 4#define led_blink_disable 5 /* set led brightness level * must not sleep. use brightness_set_blocking for drivers * that can sleep while setting brightness. */ void (*brightness_set)(struct led_classdev *led_cdev, enum led_brightness brightness); /* * set led brightness level immediately - it can block the caller for * the time required for accessing a led device register. */ int (*brightness_set_blocking)(struct led_classdev *led_cdev, enum led_brightness brightness); /* get led brightness level */ enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); /* * activate hardware accelerated blink, delays are in milliseconds * and if both are zero then a sensible default should be chosen. * and if both are zero then a sensible default should be chosen. * the call should adjust the timings in that case and if it can't * match the values specified exactly. * deactivate blinking again when the brightness is set to led_off * via the brightness_set() callback. */ int (*blink_set)(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off); int (*pattern_set)(struct led_classdev *led_cdev, struct led_pattern *pattern, u32 len, int repeat); int (*pattern_clear)(struct led_classdev *led_cdev); struct device *dev; const struct attribute_group **groups; struct list_head node; /* led device list */ const char *default_trigger; /* trigger to use */ unsigned long blink_delay_on, blink_delay_off; struct timer_list blink_timer; int blink_brightness; int new_blink_brightness; void (*flash_resume)(struct led_classdev *led_cdev); struct work_struct set_brightness_work; int delayed_set_value;#ifdef config_leds_triggers /* protects the trigger data below */ struct rw_semaphore trigger_lock; struct led_trigger *trigger; struct list_head trig_list; void *trigger_data; /* true if activated - deactivate routine uses it to do cleanup */ bool activated; /* leds that have private triggers have this set */ struct led_hw_trigger_type *trigger_type;#endif#ifdef config_leds_brightness_hw_changed int brightness_hw_changed; struct kernfs_node *brightness_hw_changed_kn;#endif /* ensures consistent access to the led flash class device */ struct mutex led_access;};从结构里面可以看到已经定义了led设备的属性和操作函数,包括设备的名称,led的亮度,max 等,设置与获取亮度函数;
重要字段:
name:设备名称,用于在/sys/class/leds/目录下创建设备子目录。brightness:表示led设备的亮度,可以通过读写
/sys/class/leds//brightness文件进行控制。max_brightness:led设备的最大亮度值。trigger:表示led设备当前的触发器名称,可以通过读写
/sys/class/leds//trigger文件进行控制。triggers:指向led设备可用触发器的链表。led框架初始化
static int __init leds_init(void){ leds_class = class_create(this_module, leds); if (is_err(leds_class)) return ptr_err(leds_class); leds_class- >pm = &leds_class_dev_pm_ops; leds_class- >dev_groups = led_groups; return 0;}它创建了一个名为leds的设备类,并设置了与电源管理相关的操作函数和设备属性组。通过这个初始化过程,led设备驱动程序可以注册到该设备类,并与led子系统进行交互。
led 设备注册和注销
int led_classdev_register_ext(struct device *parent, struct led_classdev *led_cdev, struct led_init_data *init_data)这个函数在将可以提供外部其他文件使用
led_classdev_unregister()函数用于注销一个已注册的led设备
2. led核心功能
driver/leds/led-core.c
led 设备注册和管理:led-core.c 提供了函数和数据结构,用于注册和管理 led 设备。它定义了 struct led_classdev 结构体,用于表示一个 led 设备的属性和操作函数。通过使用 led_classdev_register() 函数,可以将一个 led 设备注册到 led 子系统,并将其添加到 sysfs 文件系统中的 /sys/class/leds/ 目录下。
触发器管理:led-core.c 还实现了 led 触发器的注册和管理。触发器是一种机制,根据不同的条件或事件改变 led 的状态。通过使用 led_trigger_register() 函数,可以将一个 led 触发器注册到 led 子系统,并将其添加到 sysfs 文件系统中的 /sys/class/leds/ 目录下的触发器文件中。
电源管理:led 子系统还提供了电源管理的支持。led-core.c 定义了与电源管理相关的操作函数,并将这些操作函数与设备类结构体中的 pm 字段关联起来。通过使用 led_classdev_register() 函数时,可以将 pm 字段设置为相应的电源管理操作函数,以实现对 led 设备的电源管理。
属性和操作的支持:led-core.c 提供了用于处理 led 设备属性和操作的函数。例如,它实现了与 led 亮度相关的操作函数,以便从用户空间调整 led 的亮度。
3. led触发器管理
driver/leds/led-trigger.c
触发器注册和管理:led-trigger.c 提供了函数和数据结构,用于注册和管理 led 触发器。它定义了 struct led_trigger 结构体,用于表示一个 led 触发器的属性和操作函数。通过使用 led_trigger_register() 函数,可以将一个 led 触发器注册到 led 子系统,并将其添加到 sysfs 文件系统中的 /sys/class/leds/ 目录下的触发器文件中。
触发器操作:led-trigger.c 实现了与 led 触发器相关的操作函数。这些操作函数包括触发器的启用、禁用、触发等操作。通过这些操作函数,用户可以与 led 触发器进行交互,并控制触发器的行为。
内置触发器:led-trigger.c 还实现了一些内置的 led 触发器。这些触发器根据不同的条件或事件改变 led 的状态。例如,timer 触发器以指定的时间间隔来闪烁。
struct led_trigger { /* trigger properties */ const char *name; int (*activate)(struct led_classdev *led_cdev); void (*deactivate)(struct led_classdev *led_cdev); /* led-private triggers have this set */ struct led_hw_trigger_type *trigger_type; /* leds under control by this trigger (for simple triggers) */ rwlock_t leddev_list_lock; struct list_head led_cdevs; /* link to next registered trigger */ struct list_head next_trig; const struct attribute_group **groups;};trigger 等于是led处于某种模式,可以闪烁,可以实现具体的一个什么实物的led,比如呼吸道,音频led等等;
4. 总结

高通和Arriver达成长期战略合作 华为发布无线创新产品与解决方案
以太坊将引入ERC-777新代币标准,以取代流行的ERC-20代币标准
HUAWEI Mate Xs系列手机可升级高德地图App至v10.70新版本
人工智能会给电影工业带来什么
从技术角度详细解析LCD与AMOLED区别和优缺点,你喜欢哪一个?
Linux内核之LED子系统(二)
一个简单的无变压器1.5V DC电源电路
DAC如何实现宽带平滑阻抗变换电路的设计
简单介绍基于ZigBee自组网模块的路灯控制网络
韦尔半导体最新推出了三款5G射频开关器件
通过质询和响应身份验证实现安全访问控制
需要做阻抗的信号线时应该怎样计算线宽、线距规则?
物联网应用的一个关键器件,很多人都没有get到的那些要点
工业主板相比普通主板有哪些具体优势?
霍尔传感器关键技术的研究与选型
华为发布2024数据中心能源十大趋势,引领未来变革
看斯柯达柯迪亚克全玻璃屏导航娱乐系统有哪些特点?
2017苹果新MacBook Pro升级机型信息最新曝光 CPU将全面升级
白炽灯和日光灯有什么区别_白炽灯和日光灯的区别
多模光纤的分类、作用及使用方法