NXP i.MX8系列平台开发讲解 - 3.2 Linux 之LED子系统(二)

专栏文章目录传送门返回专栏目录


目录

目录

1. LED设备管理

2. LED核心功能

3. LED触发器管理

4. 总结


根据上一章节讲解LED子系统的使用相关步骤,

 链接:Linux 之LED子系统(一)_led子系统详解-CSDN博客

这里说一说LED子系统的一些核心源代码文件,是如何实现LED子系统。

这里重点关注内核部分的实现:

对于内核中需要重点关注的几个文件如下:

driver/leds/led-class.c
driver/leds/led-core.c
driver/leds/led-triggers.c
include/linux/leds.h

1. 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/<device>/brightness文件进行控制。

  • max_brightness:LED设备的最大亮度值。

  • trigger:表示LED设备当前的触发器名称,可以通过读写

    /sys/class/leds/<device>/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. 总结

文件功能负责的事情
led-class.c注册和管理 LED 设备处理 LED 设备的注册、注销和属性操作
设备类的创建和管理创建 LED 设备类,管理与设备的关联关系
电源管理的支持提供与 LED 设备的电源管理相关的操作
文件系统的创建在 sysfs 文件系统中创建与 LED 设备相关的目录和文件
led-core.c注册和管理 LED 设备提供注册和管理 LED 设备的函数和数据结构
LED 设备属性和操作的支持处理 LED 设备属性和操作的函数
触发器管理支持提供 LED 触发器的注册和管理支持
文件系统的创建在 sysfs 文件系统中创建与 LED 设备相关的目录和文件
led-trigger.c注册和管理 LED 触发器提供注册和管理 LED 触发器的函数和数据结构
内置触发器的支持实现内置的 LED 触发器,改变 LED 的状态
触发器操作的支持提供操作 LED 触发器的函数和机制
触发器状态切换的支持提供切换 LED 触发器状态的函数和机制
文件系统的创建在 sysfs 文件系统中创建与 LED 触发器相关的目录和文件
  • 35
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NXP i.MX8M Mini是NXP公司推出的一款处理器系列。它采用了四核ARM Cortex-A53 + 单核ARM Cortex-M4异构多核处理器设计,具有高性能和低功耗的特点。该处理器广泛应用于工业领域,可以满足复杂应用和工业级温度要求。\[1\]\[3\]针对这款处理器,米尔推出了基于i.MX8M Mini芯片的MYC-C8MMX系列核心板和开发板,提供了丰富的接口和功能,如LVDS显示、MIPI-DSI信号引出、MIPI-CSI摄像头接口、音频输入输出、千兆网、多路USB、多串口、WIFI和蓝牙模块等。此外,该核心板具有高性价比和稳定的供货周期,可满足客户的需求。\[2\] #### 引用[.reference_title] - *1* *2* [基于nxp i.mx8m mini的新一代高性价比核心板之王](https://blog.csdn.net/Jason_zhao_MR/article/details/104608706)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [NXP i.MX 8M Mini 开发板规格参数,四核ARM Cortex-A53 + ARM Cortex-M4](https://blog.csdn.net/Tronlong/article/details/125848422)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值