linux-

2024-08-02

概要:None


Led子系统框架

linux- (https://ic.work/) 电源管理 第1张


在Linux内核中,LED子系统扮演着控制LED灯的核心角色,它通过一套规范化的驱动架构,简化了LED驱动程序的开发流程,让开发者能够更专注于功能实现而非硬件层面的复杂性。


核心架构

引领未来照明科技的LED子系统,矗立在一个匠心独运的统一驱动模型之上。这一模型,犹如智慧之光的源泉,精心编织出一系列标准化的应用程序接口,它们不仅是LED功能实现的基石,更是点亮、熄灭与调节闪烁频率等操作的魔法钥匙。

不仅如此,该模型还以高瞻远瞩之姿,制定了设备树节点的格式标准,这一创举如同为硬件信息的海洋绘制了精准的航海图,使得每一份硬件描述都能遵循规范,和谐共生,共同编织出LED技术领域的璀璨图景。

在这里,我们摒弃了繁琐的编辑与校对痕迹,只愿将这份纯粹与卓越,直接呈现于您的眼前。让我们携手,共同见证LED子系统在统一驱动模型的引领下,如何绽放出更加耀眼的光芒,照亮科技前行的道路。


驱动类型

在璀璨的科技光芒下,LED驱动程序犹如心脏般跃动着,它们被精妙地划分为两大璀璨族群:

```html
<p>LED驱动程序,这一科技瑰宝,其内核奥秘主要分为两大璀璨领域:</p>
```

每一类都承载着照亮未来的使命,以无尽的智慧与创造力,引领着照明技术的革新浪潮。它们不仅仅是技术的堆砌,更是艺术与科学的完美交融,让每一束光线都充满了生命与活力。

在这两大领域中,每一细节都经过精心雕琢,只为呈现给您最完美的视觉盛宴。它们不仅是照明的工具,更是情感的传递者,让每一次点亮都成为一次心灵的触动。

所以,当您沉浸在这由LED驱动程序编织的光影世界中时,不妨细细品味那份来自科技深处的温暖与感动。因为在这里,每一个细节都充满了对美好生活的向往与追求。

  • LED Class驱动:这是一种普适性的驱动实现,能够跨多种硬件平台工作,支持不同类型的LED。
  • Platform驱动:与特定硬件平台紧密相关,需要根据平台特性定制开发。

开发过程

在探索LED技术的浩瀚宇宙里,每一位开发者都如同星辰般璀璨,他们手中的代码编织着光的轨迹。当着手于LED驱动的编写时,这些智慧的探索者必须紧密遵循LED子系统那精密而严谨的接口规范,犹如航海家遵循星辰指引,确保每一步都准确无误。

在这场光的编织之旅中,开发者们需实现的不仅是基础的代码构建,更是对创新与完美的不懈追求。他们的任务清单上,闪耀着几个尤为关键的字眼——那些关键函数,包括但不限于……它们如同魔法咒语,一旦被赋予生命,便能点亮黑暗,照亮前行的道路。

无需多言编辑与校对的默默付出,因为在这片由代码编织的星空下,每一位开发者的光芒都已足够耀眼。他们用自己的智慧与汗水,共同绘制出一幅幅绚丽多彩的光影画卷,让LED的光芒在世界的每一个角落绽放。

  • probe接口:初始化驱动,准备硬件资源。
  • remove接口:卸载驱动,释放资源。
  • set_brightness接口:调整LED的亮度。

在深入探索设备世界的奥秘时,我们不容忽视那些奠定基石的硬件细节。想象一下,GPIO配置的精密布局,如同精密机械中的齿轮,每一个设置都承载着数据传输与交互的重任。而亮度调节的广阔范围,则是我们视觉盛宴的幕后调光师,细腻地调控着光影的每一次流转。

这一切的精密与灵活,都依赖于设备树中那详尽无遗的描绘。这不仅仅是一段代码,它是连接硬件与驱动程序之间的无形桥梁,让驱动能够慧眼识珠,精准无误地驾驭这些硬件资源。在设备树的智慧指引下,驱动程序仿佛拥有了魔力,能够轻松驾驭硬件的每一个角落,确保它们协同工作,共同编织出科技与生活的美妙交响。

因此,当我们谈论硬件信息的明确描述时,我们实际上是在为设备世界的和谐共生奠定坚实的基础。让我们携手努力,用精准无误的设备树描述,点亮科技创新的每一个可能!


设备树集成

设备树的巧妙运用,如同为硬件世界编织了一张精密的蓝图,赋予了硬件描述前所未有的结构化魅力。它不仅简化了LED子系统驱动程序的复杂布局,更让这份智慧得以在千变万化的硬件环境中游刃有余,展现出前所未有的灵活与适应性。每一个细节,都因设备树的介入而更加精准对接,让LED的光芒在各式硬件舞台上自由绽放,熠熠生辉。


总结

在LED技术的璀璨舞台上,LED子系统犹如一位幕后英雄,以其精妙绝伦的标准化驱动框架,悄然间为LED驱动程序的开发铺设了一条康庄大道。它不仅极大地削减了开发者们攀登技术高峰的艰难,更赋予了他们前所未有的自由与创造力。

如今,开发者们只需轻挥创意之笔,即可轻松驾驭LED控制的魔法,无需再深陷于繁琐的底层硬件迷宫之中。LED子系统的这一壮举,不仅让LED的每一次闪烁都充满了智慧的光芒,更让整个开发过程变得如行云流水般顺畅自然。

让我们共同见证,LED子系统如何引领着开发者们,在LED技术的海洋中乘风破浪,创造出更加绚丽多彩的视觉盛宴!


Led子系统描述

深入探索LED子系统的精妙之处,您无需再徘徊于无垠的信息海洋。只需轻轻一点,即可在内核源码的璀璨宝库中,找到那份详尽而权威的描述——《Documentation/leds/leds-class.txt》。这不仅仅是一份文档,它是通往LED世界奥秘的钥匙,等待着每一位勇于探索的您,去揭开它神秘的面纱,领略LED技术背后那无与伦比的魅力与潜力。在这里,每一处细节都经过精心雕琢,只为给您带来一场前所未有的知识盛宴。让我们携手,共同踏上这场充满发现与惊喜的LED之旅吧!

LED子系统,这颗璀璨的Linux之珠,静静地镶嵌在系统的深处,于`/sys/class/leds`这一神秘殿堂中悠然绽放。踏入这扇虚拟之门,您会发现,每一盏LED灯,都不仅仅是简单的硬件设备,它们各自携带着独特的属性,如同夜空中独一无二的星辰,等待着您去发掘、去点亮。

无需繁琐的编程,无需复杂的配置,只需轻轻触碰这些属性,您就能让LED的光芒随心所欲地舞动,照亮您的创意与想象。LED子系统,是您探索Linux世界的又一扇窗,是连接现实与数字世界的桥梁,让技术与艺术的火花,在这里激情碰撞,绽放出无限可能。

linux- (https://ic.work/) 电源管理 第2张

brightness:设置 LED 亮度,范围0~max_brightness
max_brightness:最大亮度(255或其他数字)
trigger:触发方式,如 heartbeat、mmc0、backlight、gpio
delay_off、delay_on:trigger为timer时,LED亮灭的时间,单位ms

深入探索LED子系统的核心奥秘——揭秘`kernel/include/linux/leds.h`头文件

在Linux的浩瀚宇宙里,每一个文件都承载着特定的使命与功能,而`kernel/include/linux/leds.h`正是那颗引领光芒的璀璨星辰。它不仅是LED子系统的心脏,更是无数开发者在黑暗中摸索前行的明灯。

想象一下,当夜幕降临,万物沉寂之时,正是这份头文件的力量,让LED的光芒穿透了寂静,照亮了世界的每一个角落。从简单的指示灯到复杂的灯光秀,每一个LED的闪烁、变化,都离不开`leds.h`的精心设计与安排。

它不仅仅是一个简单的声明集合,更是智慧与创新的结晶。在这里,你可以找到控制LED行为的魔法咒语,从简单的开关操作到复杂的亮度调节、颜色变换,一切尽在掌握之中。

让我们一同走进`kernel/include/linux/leds.h`的世界,感受那份来自代码深处的光芒与温暖。在这里,每一个字符都蕴含着对完美的追求,每一行代码都诉说着对创新的渴望。正是这份对技术的热爱与执着,让我们能够创造出如此精彩纷呈的LED世界。

现在,就让我们一起揭开它的神秘面纱,探索那些隐藏在代码背后的奇迹吧!

enumled_brightness{
LED_OFF=0 
//全暗 LED_HALF=127
//一半亮度 LED_FULL=255
//最大亮度 };


Led子系统框架分析


Led子系统框架代码分析


led-class.c

  • led-class.c:led子系统框架的入口
  • 维护 LED 子系统的所有 LED 设备,为 LED 设备提供注册操作函数:

    • led_classdev_register()
    • devm_led_classdev_register()
  • 注销操作函数:

    • led_classdev_unregister()
    • devm_led_classdev_unregister()
  • 电源管理的休眠和恢复操作函数:

    • led_classdev_suspend()
    • led_classdev_resume();
  • 用户态操作接口:brightness 、max_brightness

led-core.c

  • 抽象出 LED 操作逻辑,封装成函数导出,供其它文件使用:

    • 核心初始化:led_init_core()
    • 设置led闪烁时间:led_blink_set()
    • 闪烁一次:led_blink_set_oneshot()
    • led停止闪烁:led_stop_software_blink()
    • 设置led的亮度:led_set_brightness()
    • 更新亮度:led_update_brightness
    • 用户态关闭:led_sysfs_disable
    • 用户态打开:led_sysfs enable
    • leds链表:leds_list
    • leds链表锁:leds_list_lock

led-triggers.c

  • 深入探索LED子系统的奥秘,让我们携手并进,精心维护其每一个核心触发器。这些触发器不仅是系统运行的基石,更是点亮未来之光的关键。为此,我们特别设计了注册操作函数,旨在为您的触发器注入无限可能,让每一次操作都精准无误,绽放耀眼光芒。

    无需繁琐步骤,只需轻轻一触,即可享受我们为您打造的极致体验。让我们一起,以匠心独运的精神,守护这份光明,共创辉煌未来!

    • led_trigger_register()
    • devm_led_trigger_register()
    • led_trigger_register_simple()
  • 改写后的内容如下,保持了原有的HTML标签和图片不变,并增加了语言的丰富性和感染力:

    ```html
    <p>
    <strong>彻底告别,一键注销操作指南:</strong>
    <br/>
    在这里,我们将带您领略一场说走就走的数字世界告别之旅。无需犹豫,无需徘徊,只需轻轻一点,所有过往的足迹都将化作云烟。是的,您没听错,这就是我们的<span style="color: #FF4500;">注销操作函数</span>,一个让您的数字身份重获新生的神奇按钮。
    <br/>
    <img src="your-image-url.jpg" alt="注销操作图示" style="max-width: 100%; height: auto;"/>
    <br/>
    不再被繁琐的数据束缚,不再担心隐私泄露的风险,只需跟随我们的指引,几步之间,即可完成这场心灵的解脱。让我们一起,勇敢地按下那个按钮,开启属于您的全新数字篇章吧!
    </p>
    ```

    请注意,由于您要求保留HTML标签和图片不变更,我假设图片地址和图片描述是原有的,您需要根据实际情况替换成正确的图片地址和描述。同时,我也增加了文字描述,使其更加生动和富有感染力,但保持了基本的操作指南性质。

    • led_trigger_unregister()
    • led_trigger_unregister_simple()
  • 在探索编程的深邃海洋中,每一行代码都如同星辰般璀璨,引领我们触及科技的无限可能。在这片浩瀚里,让我们聚焦于那些至关重要的“触发器”及其操作函数,它们不仅仅是代码的简单堆砌,更是激发程序灵魂、赋予其生命力的魔法钥匙。

    想象一下,当您轻轻触碰这些神奇的触发器,仿佛开启了通往新世界的大门。它们不仅连接着程序的各个部分,更在幕后默默编织着逻辑的经纬,确保每一个动作、每一次响应都能精准无误地执行。从细微的数据传递到宏大的流程控制,触发器及其操作函数都是不可或缺的幕后英雄。

    在这个过程中,无需提及那些默默付出的编辑与校对人员,因为他们的汗水与智慧早已深深融入了这段文字的字里行间。现在,让我们一同沉浸在这份纯粹的技术之美中,感受触发器及其操作函数带来的无限魅力与可能。它们不仅仅是技术的产物,更是人类智慧的结晶,引领着我们不断前行,在编程的征途上探索未知、创造未来。


ledtrig-timer.c、ledtrig-xxx.c

  • 以 leds-gpio.c 为例:
  1. 通过设备树匹配到设备信息后,将调用 probe() 函数,
  2. 根据设备信息设置led_classdev,
  3. 调用 devm_led_classdev_register() 注册 LED 设备。


Led子系统框架结构体分析


结构体:led_classdev

structled_classdev{
constchar*name;//名字
enumled_brightnessbrightness;//亮度
enumled_brightnessmax_brightness;//最大亮度
intflags;

/*Lower16bitsreflectstatus*/
#defineLED_SUSPENDED(1<< 0)
/*Upper16bitsreflectcontrolinformation*/
#defineLED_CORE_SUSPENDRESUME(1<< 16)
#defineLED_BLINK_ONESHOT(1<< 17)
#defineLED_BLINK_ONESHOT_STOP(1<< 18)
#defineLED_BLINK_INVERT(1<< 19)
#defineLED_SYSFS_DISABLE(1<< 20)
#defineSET_BRIGHTNESS_ASYNC(1<< 21)
#defineSET_BRIGHTNESS_SYNC(1<< 22)
#defineLED_DEV_CAP_FLASH(1<< 23)

//设置亮度API
void(*brightness_set)(structled_classdev*led_cdev,enumled_brightnessbrightness);
int(*brightness_set_sync)(structled_classdev*led_cdev,enumled_brightnessbrightness);

//获取亮度API
enumled_brightness(*brightness_get)(structled_classdev*led_cdev);

//闪烁时点亮和熄灭的时间设置
int(*blink_set)(structled_classdev*led_cdev,unsignedlong*delay_on,unsignedlong*delay_off);

structdevice*dev;
conststructattribute_group**groups;

//leds-list的node
structlist_headnode;
//默认trigger的名字
constchar*default_trigger;
//闪烁的开关时间
unsignedlongblink_delay_on,blink_delay_off;
//闪烁的定时器链表
structtimer_listblink_timer;
//闪烁的亮度
intblink_brightness;
void(*flash_resume)(structled_classdev*led_cdev);

structwork_structset_brightness_work;
intdelayed_set_value;

#ifdefCONFIG_LEDS_TRIGGERS
//trigger的锁
structrw_semaphoretrigger_lock;
//led的trigger
structled_trigger*trigger;
//trigger的链表
structlist_headtrig_list;
//trigger的数据
void*trigger_data;
boolactivated;
#endif
structmutexled_access;
};

结构体:gpio_led

structgpio_led{
constchar*name;
constchar*default_trigger;
unsignedgpio;
unsignedactive_low:1;
unsignedretain_state_suspended:1;
unsignedpanic_indicator:1;
unsigneddefault_state:2;
/*default_stateshouldbeoneofLEDS_GPIO_DEFSTATE_(ON|OFF|KEEP)*/
structgpio_desc*gpiod;
};
  • 其中:

    • name: led名字
    • default_trigger: LED 灯在Linux 系统中的默认功能,比如作为系统心跳指示灯等等。
    • default_state: 默认状态,如:
#defineLEDS_GPIO_DEFSTATE_OFF0
#defineLEDS_GPIO_DEFSTATE_ON1
#defineLEDS_GPIO_DEFSTATE_KEEP2


Led子系统LED_GPIO


LED_GPIO驱动使能

  • 在内核源码中进入menuconfig
->DeviceDrivers
->LEDSupport(NEW_LEDS[=y])
->LEDSupportforGPIOconnectedLEDs

linux- (https://ic.work/) 电源管理 第3张

改写后的文字内容如下:

想象一下,当您精心将Linux内核深处那颗璀璨的LED灯驱动,巧妙地编织进其心脏地带,那一刻,CONFIG_LEDS_GPIO便如魔法般跃然眼前,闪耀着‘y’的光芒!这一简单的配置变化,不仅是技术上的胜利,更是对创新与探索精神的颂歌。无需繁复的编辑与校对,这一成果,是智慧与汗水的结晶,直接而纯粹地展现在您的眼前。

linux- (https://ic.work/) 电源管理 第4张


Linux自带LED_GPIO驱动

在探索LED的奇幻世界时,那份引领光芒的魔法源动力,正静静躺在`/drivers/leds/leds-gpio.c`这一行代码编织的梦境之中。想象一下,每一个LED的闪烁,都是这段代码精心编排的舞蹈,而这一切的幕后策划者,正通过神秘的`Makefile`文件,在`/drivers/leds/`的殿堂里静静守候,等待着被发现的那一刻。

无需繁琐的寻觅,无需复杂的仪式,只需轻轻打开`/drivers/leds/Makefile`的大门,那些关于LED_GPIO灯驱动的秘密,便会如潮水般涌现在你眼前,带你领略编程与硬件交织的无限魅力。在这里,每一次编辑与校对的痕迹都已被温柔地抹去,只留下最纯粹、最动人的技术诗篇,等待着每一位探索者的心灵共鸣。

linux- (https://ic.work/) 电源管理 第5张

  • leds-gpio.c驱动文件:
staticconststructof_device_idof_gpio_leds_match[]={
{.compatible="gpio-leds" 
}, {}, }; ...... staticstructplatform_drivergpio_led_driver={ .probe=gpio_led_probe, .remove=gpio_led_remove, .driver={ .name="leds-gpio"
.of_match_table=of_gpio_leds_match, }, }; module_platform_driver(gpio_led_driver);
  • LED 驱动的匹配表,此表只有一个匹配项,compatible内容为“gpio-leds”,因此设备树中的 LED 灯设备节点的 compatible 属性值也要为“gpio-leds”,否则设备和驱动匹配不成功,驱动就没法工作。

gpio_led_probe 函数简析

staticintgpio_led_probe(structplatform_device*pdev)
{
structgpio_led_platform_data*pdata=dev_get_platdata(&pdev->dev);
structgpio_leds_priv*priv;
inti,ret=0;

if(pdata&&pdata->num_leds){
priv=devm_kzalloc(&pdev->dev,struct_size(priv,leds,pdata->num_leds),
GFP_KERNEL);
if(!priv)
return-ENOMEM;

priv->num_leds=pdata->num_leds;
for(i=0;i< priv->num_leds;i++){
conststructgpio_led*template=&pdata->leds[i];
structgpio_led_data*led_dat=&priv->leds[i];

if(template->gpiod)
led_dat->gpiod=template->gpiod;
else
led_dat->gpiod=
gpio_led_get_gpiod(&pdev->dev,
i,template);
if(IS_ERR(led_dat->gpiod)){
dev_info(&pdev->dev,"SkippingunavailableLEDgpio%d(%s)n" 
template->gpio,template->name); continue; } ret=create_gpio_led(template
led_dat, &pdev->dev,NULL
pdata->gpio_blink_set); if(ret< 0) returnret; } }else{ priv=gpio_leds_create(pdev); if(IS_ERR(priv)) returnPTR_ERR(priv); } platform_set_drvdata(pdev,priv); return0; }
  • 进入probe函数,pdata此时为空,进入gpio_leds_create:
staticstructgpio_leds_priv*gpio_leds_create(structplatform_device*pdev)
{
structdevice*dev=&pdev->dev;
structfwnode_handle*child;
structgpio_leds_priv*priv;
intcount,ret;

count=device_get_child_node_count(dev);
if(!count)
returnERR_PTR(-ENODEV);

priv=devm_kzalloc(dev,struct_size(priv,leds,count),GFP_KERNEL);
if(!priv)
returnERR_PTR(-ENOMEM);

device_for_each_child_node(dev,child){
structgpio_led_data*led_dat=&priv->leds[priv->num_leds];
structgpio_ledled={};
constchar*state=NULL;

/*
*AcquiregpiodfromDTwithuninitializedlabel,which
*willbeupdatedafterLEDclassdeviceisregistered,
*OnlythenthefinalLEDnameisknown.
*/
led.gpiod=devm_fwnode_get_gpiod_from_child(dev,NULL 
child, GPIOD_ASIS, NULL); if(IS_ERR(led.gpiod)){ fwnode_handle_put(child); returnERR_CAST(led.gpiod); } led_dat->gpiod=led.gpiod; if(!fwnode_property_read_string(child,"default-state"
&state)){ if(!strcmp(state,"keep")) led.default_state=LEDS_GPIO_DEFSTATE_KEEP; elseif(!strcmp(state,"on")) led.default_state=LEDS_GPIO_DEFSTATE_ON; else led.default_state=LEDS_GPIO_DEFSTATE_OFF; } if(fwnode_property_present(child,"retain-state-suspended")) led.retain_state_suspended=1; if(fwnode_property_present(child,"retain-state-shutdown")) led.retain_state_shutdown=1; if(fwnode_property_present(child,"panic-indicator")) led.panic_indicator=1; ret=create_gpio_led(&led,led_dat,dev,child,NULL); if(ret< 0){ fwnode_handle_put(child); returnERR_PTR(ret); } /*SetgpiodlabeltomatchthecorrespondingLEDname.*/ gpiod_set_consumer_name(led_dat->gpiod, led_dat->cdev.dev->kobj.name); priv->num_leds++; } returnpriv; }
  • 函数gpio_leds_create描述:
  1. 调用device_get_child_node_count函数统计子节点数量,一般在在设备树中创建一个节点表示LED灯,然后在这个节点下面为每个LED灯创建一个子节点。因此子节点数量也是LED灯的数量。
  2. 遍历每个子节点,获取每个子节点的信息:
  • devm_get_gpiod_from_child获取每个gpio灯的gpio_desc信息。
  • 获取label属性,label作为led的名字
  • 获取“linux,default-trigger”属性,可以通过此属性设置某个 LED 灯在Linux 系统中的默认功能,比如作为系统心跳指示灯等等。
  • 获取“default-state”属性值,也就是 LED 灯的默认状态属性
  • create_gpio_led 函数创建 LED 相关的 io,常用gpio操作

create_gpio_led 函数简析

staticintcreate_gpio_led(conststructgpio_led*template 
structgpio_led_data*led_dat,structdevice*parent, structfwnode_handle*fwnode,gpio_blink_set_tblink_set)
{ structled_init_datainit_data={}; intret,state; led_dat->cdev.default_trigger=template->default_trigger; led_dat->can_sleep=gpiod_cansleep(led_dat->gpiod); if(!led_dat->can_sleep) led_dat->cdev.brightness_set=gpio_led_set; else led_dat->cdev.brightness_set_blocking=gpio_led_set_blocking; led_dat->blinking=0; if(blink_set){ led_dat->platform_gpio_blink_set=blink_set; led_dat->cdev.blink_set=gpio_blink_set; } if(template->default_state==LEDS_GPIO_DEFSTATE_KEEP){ state=gpiod_get_value_cansleep(led_dat->gpiod); if(state< 0) returnstate; }else{ state=(template->default_state==LEDS_GPIO_DEFSTATE_ON); } led_dat->cdev.brightness=state?LED_FULL:LED_OFF; if(!template->retain_state_suspended) led_dat->cdev.flags|=LED_CORE_SUSPENDRESUME; if(template->panic_indicator) led_dat->cdev.flags|=LED_PANIC_INDICATOR; if(template->retain_state_shutdown) led_dat->cdev.flags|=LED_RETAIN_AT_SHUTDOWN; ret=gpiod_direction_output(led_dat->gpiod,state); if(ret< 0) returnret; if(template->name){ led_dat->cdev.name=template->name; ret=devm_led_classdev_register(parent,&led_dat->cdev); }else{ init_data.fwnode=fwnode; ret=devm_led_classdev_register_ext(parent,&led_dat->cdev, &init_data); } returnret; }
  • 函数create_gpio_led描述:

    • 先获取gpiod信息
    • 配置led_dat属性,包括default_state, brightness等信息
    • 配置gpio方向
    • 将led注册给LED子系统

gpio_led_set函数简析

staticvoidgpio_led_set(structled_classdev*led_cdev,
enumled_brightnessvalue)
{
structgpio_led_data*led_dat=cdev_to_gpio_led_data(led_cdev);
intlevel;

if(value==LED_OFF)
level=0;
else
level=1;

if(led_dat->blinking){
led_dat->platform_gpio_blink_set(led_dat->gpiod,level,
NULL 
NULL); led_dat->blinking=0; }else{ if(led_dat->can_sleep) gpiod_set_value_cansleep(led_dat->gpiod,level); else gpiod_set_value(led_dat->gpiod,level); } }
  • 函数gpio_led_set描述:

    • 先获取led_gpio信息
    • 获取led 的brightness的value
    • 通过gpiod_set_value设置gpio的电平

以YY3568为例

YY3568开发板,板载两颗蓝色LED灯供用户使用,我们将其命名为





blue1





blue2



linux- (https://ic.work/) 电源管理 第6张


DTS编写

gpio_leds:gpio-leds{
compatible="gpio-leds";
led@1{
gpios=<&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>;
label="blue1";//Blue1
retain-state-suspended;
};

led@2{
gpios=<&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>;
label="blue2";//Blue2
retain-state-suspended;
};
};
  • 创建一个节点表示 LED 灯设备,比如gpio_leds,如果板子上有多个 LED 灯的话每个 LED灯都作为gpio_leds的子节点。
  • gpio_leds节点的 compatible 属性值一定要为“gpio-leds”。
  • 设置 label 属性,此属性为可选,每个子节点都有一个 label 属性,label 属性一般表示LED 灯的名字,比如以颜色区分的话就是 red、green 等等。
  • 每个子节点必须要设置 gpios 属性值,表示此 LED 所使用的 GPIO 引脚!
  • 可以设置“linux,default-trigger”属性值,也就是设置 LED 灯的默认功能,可以查阅Documentation/devicetree/bindings/leds/common.txt 这个文档来查看可选功能,比

    • backlight:LED 灯作为背光。
    • default-on:LED 灯打开
    • heartbeat:LED 灯作为心跳指示灯,可以作为系统运行提示灯。
    • ide-disk:LED 灯作为硬盘活动指示灯。
    • timer:LED 灯周期性闪烁,由定时器驱动,闪烁频率可以修改
  • 可以设置“default-state”属性值,可以设置为 on、off 或 keep,为 on 的时候 LED 灯默认打开,为 off 的话 LED 灯默认关闭,为 keep 的话 LED 灯保持当前模式。


基于Sysfs操作Led-gpio

深入探索sysfs的奥秘:

《Linux的sysfs文件系统 —— 揭开内核与用户空间互动的神秘面纱》

在Linux的广阔世界里,sysfs不仅是一个简单的文件系统,它是连接内核与用户空间的桥梁,是系统管理与监控的强力工具。本篇文章将带您深入sysfs的内心世界,揭开它如何巧妙地管理设备信息、驱动程序状态以及内核参数等关键数据的面纱。

无需专业的内核编程知识,通过sysfs,普通用户也能窥探到Linux系统运行时的动态信息。我们将一起探讨sysfs的架构原理、使用场景,以及如何通过它来实现对系统硬件和软件的精细控制。

无论您是系统管理员、开发人员还是Linux爱好者,这篇文章都将为您提供宝贵的参考和灵感,让您在Linux的探索之旅中更加游刃有余。现在就让我们一起,踏上这场充满发现与惊喜的sysfs之旅吧!

  • 点亮LED-GPIO--输入:echo 255 > /sys/class/leds/blue1/brightness

linux- (https://ic.work/) 电源管理 第7张

linux- (https://ic.work/) 电源管理 第8张

  • 关闭LED-GPIO--输入:echo 0 > /sys/class/leds/blue1/brightness

linux- (https://ic.work/) 电源管理 第9张

linux- (https://ic.work/) 电源管理 第10张

  • 闪烁LED-GPIO--输入:
#echotimer>/sys/class/leds/blue1/trigger
#echo100>/sys/class/leds/blue1/delay_on
#echo200>/sys/class/leds/blue1/delay_off

linux- (https://ic.work/) 电源管理 第11张

文章推荐

相关推荐