Linux内核LED子系统、请务必看

前言

LED子系统你要是说很难嘛,但是它就是控制一些简单的GPIO口,但是你要是说它很简单嘛,但是我也不见得一个初学者很快就能掌握,你如果是刚入门这部分的话,我觉得你还是要去仔细研究下这些驱动。前两天在网上看到一句话,初学者喜欢研究语法,大牛喜欢研究数据结构,Linux下的数据结构非常多,把这些东西搞明白对你非常有帮助。

简单说下LED子系统


  • 应用的话不是很想解释,应用就是调用驱动的接口,打开、关闭、设置等等操作。

  • 核心是为驱动和效果和应用服务的,所以我们很多东西都依赖于核心,所以会有一些基本的数据结构,注册、卸载等函数。

  • 驱动的用法很简单,但是在简单的用法后面蕴藏着巨大的秘密,Linux下的很多驱动都是如此,填充好一些数据结构,然后调用register函数注册,这样之后,就能把驱动注册起来。

  • trigger指的是一种效果,比如亮、灭、是一个效果,驱动里面就做成了default-on的效果,还有闪烁、呼吸等,都是不同的效果。


AW9110 LED驱动芯片

我们分析下这个芯片的硬件连接吧,先分析下硬件有啥特点。

这是一款I2C接口的LED驱动IC,默认的驱动电流大小是37mA,有256个驱动等级,读到这里我们应该可以知道,我们可以用这个IC做呼吸的功能。

看一个驱动的流程理解

我吹几句

我们写程序的时候,需要注意的是在dts里面可以设置什么,这个应该是关键,如果这个是一个LED灯驱动,那么,在dts里面就需要设置LED的属性,比如这个LED灯有什么效果,默认效果是什么。

还有就是要注意led_classdev,因为register注册的时候就是把这个结构体填充的东西给注册起来的。

dts

+       aw9110b: aw9110b@5b {
+               compatible = "aw9110b-leds";
+               gpio_out_drv = <AW9110B_TOTEM_POLE>;
+               shdn-gpio = <&pio 19 GPIO_ACTIVE_HIGH>;
+               reg = <0x5b>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "okay";
+
+               led1: led@1 {
+                               label = "led_cam1";
+                               reg = <1>;
+                               flags = <AW_MAKE_FLAGS(AW_GROUPB, AW_OUT0, AW_MODE_LED, 255)>;
+                               led-max-microamp = <10000>;
+                               linux,default-trigger = "default-on";
+               };
}

led_classdev 结构体

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  (1 << 0)/* Upper 16 bits reflect control information */
#define LED_CORE_SUSPENDRESUME (1 << 16)
#define LED_BLINK_ONESHOT (1 << 17)
#define LED_BLINK_ONESHOT_STOP (1 << 18)
#define LED_BLINK_INVERT (1 << 19)
#define LED_SYSFS_DISABLE (1 << 20)
#define SET_BRIGHTNESS_ASYNC (1 << 21)
#define SET_BRIGHTNESS_SYNC (1 << 22)
#define LED_DEV_CAP_FLASH (1 << 23)/* Set LED brightness level *//* Must not sleep, use a workqueue if needed */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_sync)(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.* 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 a fixed* value via the brightness_set() callback.*/int  (*blink_set)(struct led_classdev *led_cdev,unsigned long *delay_on,unsigned long *delay_off);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;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;
#endif/* Ensures consistent access to the LED Flash Class device */struct mutex  led_access;
};



LED trigger 的理解


我这里打开的是呼吸的trigger,这个trigger是用来实现呼吸效果的,但是我们这个IC没有自主呼吸的功能,所以我们需要实现呼吸的话,肯定是离不开定时器的,我们使用一个定时器在一个时间段内不断的改变输出的电流,以此来改变输出的亮度。这样让用户就看到呼吸的效果了。

我简单的说下这个呼吸曲线,因为人眼对亮度的观察并不是线性的,举个例子,理想的做法是,我们的曲线在一个时间内递增一样大小的电流,这样输出看到的亮度也是曲线增加的,但是因为我们人眼对亮度观察并不是理想的,所以我们可能看到的是突然变亮,变灭的过程也会极其尴尬。

赠送一段不健全的呼吸曲线

static const uint8_t s_breath_effect[] = {0, 0, 0, 0, 1, 2, 3, 4, 6, 8,10, 12, 14, 16, 19, 22, 25, 28, 32, 36,40, 44, 48, 52, 57, 62, 67, 72, 78, 84,90, 96, 102, 108, 115, 122, 129, 136, 144, 152,160, 168, 176, 184, 193, 202, 211, 220, 230, 240,250, 240, 230, 220, 211, 202, 193, 184, 176, 168,160, 152, 144, 136, 129, 122, 115, 108, 102, 96,90, 84, 78, 72, 67, 62, 57, 52, 48, 44,40, 36, 32, 28, 25, 22, 19, 16, 14, 12,10, 8, 6, 4, 3, 2, 1, 0, 0, 0,
};

LED sys节点

节点

android:/sys/class/leds # ls
blue          led_cam_b led_key1 

属性

android:/sys/class/leds/led_key1 # ls
brightness device max_brightness power subsystem trigger uevent

trigger

android:/sys/class/leds/led_key1 # cat trigger
[none] rc-feedback nand-disk mmc0 timer oneshot heartbeat breath

  推荐阅读:

  专辑|Linux文章汇总

  专辑|程序人生

  专辑|C语言

嵌入式Linux

微信扫描二维码,关注我的公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467525.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UVALive 4394 String painter

题目大意&#xff1a;有两个字符串A,B&#xff0c;一次刷可以把A串一段刷成同一个字母&#xff0c;问至少要刷几次才能把A串变成B串。串长≤100。 本来以为是个很简单的区间DP&#xff0c;后来发现直接区间DP是不行的&#xff0c;这玩意有后效性&#xff1a;刷完一整块之后这一…

centos 6.5 安装 lamp 后mysql不能启动_CentOS 6.5 系统 LAMP(Apache+MySQL+PHP)安装步骤

先来解释一下&#xff0c;什么是 LAMP。正如标题所言&#xff0c;LAMP 实际上就是 Linux、Apache、MySQL、PHP 四个名称的缩写&#xff0c;当然最后一个 “P” 还有其他说法是 Perl 或者 Python。不用多说了&#xff0c;本文讲解的就是 Linux、Apache、MySQL、PHP 这四个东西&a…

Redis连接实例

ECS Windows服务器 如果您本地需要通过公网访问 云数据库 Redis&#xff0c;可以在 ECS Windows 云服务器中通过 netsh 进行端口映射实现。 1. 登录 ECS Windows 服务器&#xff0c;在 CMD 执行以下命令。&#xff08;公网地址与 连接地址 请替换 为您的实际地址。&#xff09;…

什么是高内聚,低耦合?

高内聚&#xff0c;低耦合是一个老生常谈的话题&#xff0c;所以拿出来说一下我们在看Linux的一些资料&#xff0c;或者是在面试&#xff0c;又或者跟一个比较牛的大佬讨论技术的时候&#xff0c;可能会听到这个概念。所以&#xff0c;什么是高内聚&#xff0c;低耦合呢&#x…

Web API 2 入门——创建ASP.NET Web API的帮助页面(谷歌翻译)

在这篇文章中 创建API帮助页面将帮助页面添加到现有项目添加API文档在敞篷下下一步作者&#xff1a;Mike Wasson 创建Web API时&#xff0c;创建帮助页面通常很有用&#xff0c;以便其他开发人员知道如何调用API。您可以手动创建所有文档&#xff0c;但最好尽可能自动生成。 为…

Linux fork的写时复制

这个问题是一个同学在知识星球里面提问的看下面的代码#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/wait.h> #includ…

从单片机工程师的角度看嵌入式Linux

前言 这篇文章简单我们来一起梳理嵌入式Linux的一些知识&#xff0c;方便于一些想跟我一样想要由单片机进阶到嵌入式Linux的朋友做一些参考学习。现在随着嵌入式Linux的教程不断增多&#xff0c;相信应该有不少学单片机的朋友开始折腾这个了吧~嵌入式Linux学哪些东西 1、认识Li…

智能硬件开发神器免费送!距离产品智能化,只差一个“三明治”的距离

重磅资料包免费领取 针对人群&#xff1a;如果您对“人工智能物联网”感兴趣&#xff0c;尤其是您的企业想做产品/行业智能化&#xff0c;一定不能错过这份“物联网人必备的终极大礼包”哦&#xff5e;这几类行业玩家必看&#xff01;&#xff01;&#xff01;制造商、方案商、…

你们班上的同学现在都怎么样了?

今天跟朋友聊天&#xff0c;聊到这个话题&#xff0c;觉的有点意思&#xff0c;所以想拿出来讨论一下。小学小学的时候&#xff0c;我们读书最厉害的应该是我们班上几个老师的孩子&#xff0c;他们像是得到了老师的武功秘籍&#xff0c;读书对他们来说就是家常便饭&#xff0c;…

如何把一个float存到一个长度为4的char数组中?

我以前以为它是可以这样的看代码#include "stdio.h"int main(void) {float fa 123.56;char farray[4] {0};farray[0] ((int)fa>> 24)&0xFF;farray[1] ((int)fa>> 16)&0xFF;farray[2] ((int)fa>> 8 )&0xFF;farray[3] ((int)fa>…

OSPF次末节区域配置 201

【实验拓扑】 【实验基本配置】1、按照上图配置相应接口以及OSPF【实验要求】 1、配置Area 1 为NSSA区域2、在R6上配置1条静态路由160.1.60.0/24指向 Null0&#xff0c;并充分发到OSPF中3、将路由器1的ID修改为150.1.100.100【实验分析】次末节区域&#xff08;NSSA&#xff09…

MTK联发科2021 嵌入式C笔试题分析

题目-分割字符串因为题目是考试的同学凭记忆记下来的&#xff0c;没有记得特别仔细&#xff0c;题目只是写了个大概&#xff0c;我也是凭自己的想法来理解。输入aaa;bbb;ccc输出aaa bbb ccc /*--------------------------------------------*/ 输入,hello,hello,,输出hello hel…

DEVICE_ATTR设置0777引发血案

这个宏我们在内核里面使用非常频繁&#xff0c;这个宏的作用可以抛出sys设备节点给用户使用。用户可以读写sys/class下面的文件节点&#xff0c;以达到控制内核驱动的功效。比如&#xff0c;像这样的设备节点weiqifa:/sys/class/zigbee/onoff $ ls gpio_en power subsystem uev…

「任性」的C语言之父:因拒付论文装订费错失博士学位,论文52年后重见天日...

他是C语言之父、1983年图灵奖得主&#xff0c;还是Unix的关键开发者。然而&#xff0c;他却因为「任性」没有拿到博士学位&#xff0c;而且当年写的博士论文一丢就是半个世纪。如今&#xff0c;这一神秘的博士论文终于重见天日。很多人可能听说过 Dennis Ritchie 这个人。上世纪…

CS224n笔记3 高级词向量表示

本文转自&#xff1a;http://www.hankcs.com/nlp/cs224n-advanced-word-vector-representations.html 这节课从传统的基于计数的全局方法出发&#xff0c;过渡到结合两者优势的GloVe&#xff0c;并介绍了词向量的调参与评测方法。 复习&#xff1a;word2vec的主要思路 遍历整个…

我在深圳,但是家里托人在老家找了一份工作

最近&#xff0c;在微信公众号后台收到一份读者的留言&#xff0c;而且这位读者也是我们GX的&#xff0c;而且更幸运的是&#xff0c;跟我是一个地方的。她是疑惑如下~前辈你好~ 今天看到最新一篇有关读书的推文发现同是HC老乡&#xff0c;斗胆向您请教一些问题&#xff0c;有点…

Django之项目搭建和配置总结(一)

安装和创建虚拟环境 参考&#xff1a;linux系统下Python虚拟环境的安装和使用安装Django包 先进入虚拟环境&#xff0c;在联网下执行&#xff1a;pip install django1.8.7 1.8.7表示django的版本&#xff0c;如果不指定&#xff0c;会默认安装最新版的django。包会被安装到/usr…

怎么把一个bool数组转成char?

这个是在知乎上看到的问题&#xff0c;分享给大家&#xff0c;如果有不同的答案&#xff0c;欢迎评论回复。知乎惯例谢邀人在厕所&#xff0c;刚刚蹲下因为最近都流行长文&#xff0c;但是作为日更而且更喜欢表达自己看法的我&#xff0c;力争文章是自己想发的&#xff0c;而且…

mysql的高阶用法_MySQL的经典用法(十四)-高级优化

mysql的经典用法(十四)----高级优化基于/application/search/mysql/mysql-5.5.28/support-files/my-innodb-heavy-4G.cnf二次优化【删除--如果不使用主从同步】注释&#xff0c;去除无用日志文件# log-binmysql-bin# binlog_formatmixed【修改链接】# 最大链接值从100增加到512…

Kotlin——初级篇(二):变量、常量、注释

在Kotlin中的变量、常量以及注释多多少少和Java语言是有着不同之处的。不管是变量、常量的定义方式&#xff0c;还是注释的使用。下面详细的介绍Kotlin中的变量、常量、注释的使用。以及和Java的对比。 如果您还没有搭建环境和不了解Kotlin的&#xff0c;请看我的上一篇博文Kot…