首页 > 其他分享 >点亮一个LED指示灯

点亮一个LED指示灯

时间:2024-12-04 21:30:40浏览次数:11  
标签:指示灯 leds led 点亮 Trigger trigger 内核 LED

初心

从事嵌入式开发已经是第七个年头了,想想还从来没有网上发布过一点东西。可能也是由于工作环境没有方便的互联网的原因,更大的原因是我这个人比较懒;但是和公司新人的技术分享,我可从来没有吝啬过,公司内部的共享资料库我的提交量也是第一。找个平台记录一下,至少证明我也在这个行业混过些年。虽然现在也是菜鸟一枚,特别是当前人工智能的功能越来越强大,还不知道还能在这个行业走多久。有段时间啃一些开源的代码,都是找人工智能软件帮我读,或者把需求提明确,直接就能把代码给我写出来了。想想真是可怕呀;
想想当年初入开发岗位,公司的基础库可以说是没有,从点亮一个LED灯都是从头开始,经过这么些年的积累,新人加入也不会束手无策了。
既然开始写东西,按照行规还是从最基础的入门吧,毕竟所有的教程第一课都是“点亮一个LED”!


妖娆多姿的LED指示灯

LED作为一个最基础的元器件。不管是STM32,CPU,FPGA,硬件工程师必然要画一些指示灯上去;可以说是存在与整个板子的开发,交付、维护周期。所有相关人员通过指示灯就能够一目了然的判断设备的基础状态。

那么,一个有内核洁癖的linux工程师是怎么点亮一个LED指示灯的呢?当然是用内核现成的驱动来搞了,能不用自己写代码的干嘛非要动手写呢!而且内核提供的丰富操作接口,可以让一个简单的led指示灯变的丰富多彩,除了可以实现指示灯秒闪、心跳闪烁,还可以用来指示MTD设备的读写、GPIO状态、最新的内核还支持指示网卡的link状态,流量指示等,还可以用户自定义很多指示状态。通过此文分享一些linux内核的leds应用,希望能够抛砖引玉,能够让led在各个领域发挥它的价值。
在此,也希望和同行们一起分享linux内核带给我们的便利,现在的项目我都尽可能去适配内核驱动,不管是一个散热风扇,一个LCD屏幕,或者是一个eeprom,库仑计等等,都是先去内核源码里面去翻一下,看看有没有适配的驱动,可能开发量并不比自己写一个接口或者写一个驱动小。但是能从驱动适配的过程中,去体会到高手们写的去驱动,理解到设计者的设计思想,对我的启发也是非常的大。
分享第一个点就是多去看看内核Documentation目录下的帮助文档,学习怎么配置设备数,怎么使用驱动。自己写的一些驱动,也最好按照内核标准来设计,然后完善相关的devicetree/bingding文档。

内核配置

通常来说,我们的LED指示灯一般都接到CPU的GPIO或者PWM脚,linux内核提供了gpio-led驱动和pwm-led驱动,驱动源码在drivers/led/s目录下: leds-gpio.c leds-pwm.c,内核配置选项中把这两个驱动都选中。
关于GPIO 和 PWM 控制器的驱动,一般都是由芯片厂家适配完成,所以gpio和pwm层的驱动我们一般是不需要关心的,只需要了解怎么在设备树中调用。以上驱动只提供了操作led的基础接口,想要让LED 灯妖娆多姿,那就需要trigger驱动出场了。按照需求使能以下trigger模块,后面会对每个功能模块的功能和使用作出解释。

     --- LED Trigger support                                                         
  │ │     <*>   LED Timer Trigger                                                    
  │ │     <*>   LED One-shot Trigger                                                
  │ │     [*]   LED MTD (NAND/NOR) Trigger                                          
  │ │     <*>   LED Heartbeat Trigger                                               
  │ │     <*>   LED backlight Trigger                                                
  │ │     [*]   LED CPU Trigger                                                      
  │ │     <*>   LED activity Trigger                                                  
  │ │     <*>   LED GPIO Trigger                                                      
  │ │     <*>   LED Default ON Trigger                                                
  │ │           *** iptables trigger is under Netfilter config (LED target) ***       
  │ │     <*>   LED Transient Trigger                                                
  │ │     <*>   LED Camera Flash/Torch Trigger                                       
  │ │     [*]   LED Panic Trigger                                                      
  │ │     <*>   LED Netdev Trigger                                                     
  │ │     <*>   LED Pattern Trigger                                                    
  │ │     <*>   Audio Mute LED Trigger                                               
---

内核选项中把这些trigger类型全部使能,其中有些触发类型我至今也没弄明白该怎么使用,比如camera、Audio、backlight等,由于不从事多媒体类的设备开发,暂时没有机会去尝试这些触发类型调试。

设备树配置

gpio-leds配置:

/{

 leds {
        compatible = "gpio-leds";

        sys_run {
            label = "sys_run";
            gpios = <&gpc 21 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
            linux,default-trigger = "heartbeat";
        };
        
    };
    
};

以上只是一个最基础的gpio-leds配置,将挂接在GPIO_PC(21)管脚上的一枚低点亮的LED配置为心跳状态(心跳灯的闪烁有点像飞机翅膀上的指示灯)。
进内核后,该指示灯会模拟心跳的跳动节奏闪烁,一般用来指示CPU的正常工作。

pwm-leds配置:
/{

pwm_leds {
                compatible = "pwm-leds";
                kpad0 {
                        label = "keypad0";
                        pwms = <&pwm 2 40000 0>;
                        max-brightness = <255>;
                };
                kpad1 {
                        label = "keypad1";
                        pwms = <&pwm 3 40000 0>;
                        max-brightness = <255>;
                };
        };
        
};

分别配置了两个挂接在pwm控制器的2、3通道上的两个led指示灯,和GPIO 控制的指示灯的区别在于,它可以有亮度的控制,比如很多手机流行的呼吸灯提示新消息等。当然,pwm几乎支持了所有的gpio-led的触发类型。
关于gpio和pwm通道的配置,一般厂商提供的设备树都有可以参考的;一般格式就是<&label x x>,后面的两个值和#gpio-cell以及#pwm-cells有关;

设备树的配置其实很复杂,可以设置各种属性,这里只是简单提一下,详细操作可以参考所使用内核源码工程的/Documentation\devicetree\bindings\leds\leds.gpio.yaml和leds-pwm.txt;
文档有很多更高级的用法,但很多配置可以进系统后,在sys目录的相关属性中手动配置,这样便于测试各种trigger效果。

sys/class下的配置

如果手里没有合适的开发板,随便找一台linux主机也可以测试。低头看看你正在敲击的键盘右上角上,是不是至少有3个灯。
哈哈,capslock、numlock、scrolllock也是通过led子系统管理的,我们可以暂借来玩玩。
进入目录:

cd /sys/class/leds/input3::capslock

查看支持的触发类型:

cat trigger
none usb-gadget usb-host rfkill-any rfkill-none kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock disk-activity disk-read disk-write ide-disk mtd nand-disk cpu cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 panic rc-feedback audio-mute audio-micmute timer [heartbeat]

这个属性会列出所有支持的触发类型,当前的触发类型会用[ ]括起来;
如果没有你想要的触发类型也没有关系,进入(不同版本的系统驱动模块位置可能有所差异)

cd /lib/modules/5.15.0-124-generic/kernel/drivers/leds/trigger/

直接插入你想要的驱动模块就可以支持上了。
当使能不同的触发类型,当前led的属性内容也会发生变化,例如timer触发,则会有属性来配置亮和灭的时间,netdev触发则会有属性来配置指示的网卡等;
说到网卡指示灯,当年有一个项目需要由led来指示,记得好像是4.19版本的内核,还没有支持到netdev-trigger,当年我可是费了很大的心血,在网卡驱动里面去添加了led-trigger来指示linkup 、linkdown、tx、tx等。后来升级到5.10版本内核,居然直接就支持上了。而且还支持usb网卡、甚至是虚拟网卡,功能可比我做的强大多了。

还有一个很好玩的,led One-shot,内核文档是这样描述的:

  • This is a LED trigger useful for signaling the user of an event where
    there are no clear trap points to put standard led-on and led-off
    settings. Using this trigger, the application needs only to signal
    the trigger when an event has happened, than the trigger turns the
    LED on and than keeps it off for a specified amount of time.

    This trigger is meant to be usable both for sporadic and dense
    events. In the first case, the trigger produces a clear single
    controlled blink for each event, while in the latter it keeps
    blinking at constant rate, as to signal that the events are arriving
    continuously.

    A one-shot LED only stays in a constant state when there are no
    events. An additional “invert” property specifies if the LED has to
    stay off (normal) or on (inverted) when not rearmed.
    具体使用场景就是,当用户态需要点亮一段时间后并关闭led指示灯,但是没有适合的位置放置开启和关闭命令,那么可以调用该接口。该触发器可用于间歇性和密集的事件,在第一种情况下,触发器会为每个事件产生一个清晰的单次受控闪烁,而在第二种情况下,它会以恒定的速率持续闪烁,以表示事件正在连续到达。
    使用方法是:

echo oneshot > trigger
echo 1 > shot		#触发一次闪烁,delay也可以通过属性来进行配置

用户编程例如想用来展示串口或则其他通信口的状态,也可以按照系统调用的方法来触发。

再补充一个gpio类型的trigger,使能该触发类型后,还需要传入触发源GPIO,这个触发的功能效果就是,当你检测的那个gpio拉低或则拉高,对应的指示灯亮或则灭。分析这个驱动可以得知,监测原理是将监测gpio配置成输入模式,双边沿中断;分别在中断发生后,作出不同的点灯动作。所以当gpio硬件或则是驱动不支持双边沿中断时,这个功能是没法使用的。
其中也存在一个问题,就是目前很多cpu的usb都支持了otg功能,系统所能够提供的触发类型只有gadget和host ,所以我一般是参考这个框架,实现了usb-both的触发,当设置成OTG功能的时候,就可以两种模式都兼容。
功能太多了,这里就不一一解释了。更多功能等着大家一起区发掘,linux内核像是给我们提供了一个庞大的资源库一样,等着我们区发掘,还是那句话,内核的Documentation下,比我写的详细的多,如果有不对的地方或则不明白的地方,参考内核文档。
以上功能在sys下测试完成后,就可以直接在设备树中配置,这样上电直接就能运行。
仅仅是一个led灯,就可以玩出这么多花活。时间有限,如果有什么不清楚的地方,欢迎下面留言,我会一直维护此帖。

标签:指示灯,leds,led,点亮,Trigger,trigger,内核,LED
From: https://blog.csdn.net/weixin_41972926/article/details/143780768

相关文章

  • socket() failed (24: Too many open files)
     这个错误因为超出了ulimitnofile当前bash的这样修改:[root@A06~]#ulimit-n200[root@A06~]#ulimit-n2000000[root@A06~]#ulimit-n2000000 systemd启动的程序这样修改[root@A06~]#cat/usr/lib/systemd/system/nginx.service|grep-C1-inofile[Ser......
  • 26 基于STM32的智能门禁系统(指纹、蓝牙、刷卡、OLED、电机)
    目录一、主要功能二、硬件资源三、程序编程四、实现现象一、主要功能基于STM32单片机,六个按键,分别代表指纹、蓝牙、刷卡的正确进门与错误进门;比如第一个按键按下,表示指纹正确,OLED显示指纹正确,开门,第二个按键按下的话,则指纹错误,OLED显示指纹错误,请重试,第二个按键连......
  • 【StableDiffusion教程】 SD超实用功能——图生图 之 局部重绘
    StableDiffusion图生图(局部重绘):局部重绘:·在图生图界面中关于局部重绘有三个[标签页]·这三个标签页主要是蒙版的使用方式不同.局部重绘标签.图片可以通过上传,或者是从文生图发送到局部重绘.右边是局部重绘的画笔工具.·局部重绘中,画布和画笔大小有......
  • 【stablediffusion动画教程】AnimateDiff 目前生成视频最流畅的SD插件 | stablediffus
    前言测试了下最近比较火的AnimateDiff,感觉确实蛮棒的,画面流畅没有闪帧的问题,真的感觉视频生成又近了一步,下面小刚分享下基本的使用方法。效果预览(电脑配置不行仅作参考):一、安装插件(以秋叶大佬的整合包为例):AnimateDiff项目:https://github.com/guoyww/AnimateDiffWe......
  • 【stablediffusion教程】AIGC技巧:SD图生图 如何控制变量生成想要的效果?
    SD(StableDiffusion)是目前最流行的本地部署类AIGC工具,它可以说既简单又复杂。简单是因为完全没有绘画功底的用户也可以做出各种风格的精美图片,而复杂则是因为AIGC相对没有那么“听话”,想要AI完全按照自己的想法实现内容还是颇有难度的。此前我们简单介绍过大家最常用的文生......
  • 达梦网络通信异常-断开的管道(write failed)报错排查及解决过程
    应用连接数据库偶发性报网络通信异常,报错截图如下:查看驱动版本,应用所用的驱动和数据库当前版本匹配 数据库版本 网络和数据库日志方面也没有问题,连接池超时设置调整之后还是报错 应用报错日志有断开的管道 根据网上参考类似错误。应该是长时间没有刷新页面导致数......
  • HTC8 - 点亮第一盏灯
    一、环境的搭建需要使用到的工具开发软件:KeiluVision5烧录工具:stcai-isp-v6.94C开发板:STC8H核心板,采用的是STC8H8K64U芯片二、单片机介绍原理图:二、点亮第一盏灯通过控制5.3引脚输出高电平时,LED灯就点亮,输出低电平时LED灯就熄灭1.新建项目2.配置开发板的......
  • 【stable diffusion部署】电脑再差也不怕,教你白嫖谷歌玩StableDiffusion教程
    前言最近总有同学找我,想玩想学[AI绘画],但是无奈自己的电脑配置太低,玩不了AI绘画,非常难过。但是升级电脑低端的显卡不想要,好的配置又觉得太贵买不起。于是找到我,说:救救孩子吧,孩子也想玩AI绘画。我:上次不是教了用那个什么rightbrain.art在线网站画画吗?同学:那个网站好是好......
  • flutter项目运行卡在Running Gradle task 'assembleDebug'?
    flutter项目运行卡在RunningGradletask'assembleDebug'?也修改了项目build.gradle和flutter.gradle文件,替换为阿里地址,还是卡在那,没用呀?flutter/packages/flutter_tools/gradle/resolve_dependencies.gradle改为url"http://download.flutter.io"flutter/packages/flutte......
  • 永嘉VINKA-LED显示驱动数显驱动芯片VK1640 SOP28适用于血氧仪,温控仪LED驱动
    产品品牌:永嘉微电/VINKA产品型号:VK1640封装形式:SOP28概述VK1640是一种数码管或点阵LED驱动控制专用芯片,内部集成有数据锁存器、LED驱动等电路。SEG脚接LED阳极,GRID脚接LED阴极,可支持8SEGx16GRID的点阵LED显示。适用于小型LED显示屏驱动。采用SOP28的封装形式。LJQ3501特......