本文转载自:https://blog.csdn.net/u010444107/article/details/78328807

1)查看内核配置
wujun@wj-vBox:~/freescale/linux-imx$ cat arch/arm/configs/imx_v7_defconfig | grep LEDS
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_GPIO=y
已经开启了LED并且使能了几种触发模式:timer oneshot heartbeat backlight gpio

(2)设备树增加LED相关设定
wujun@wj-vBox:~/freescale/linux-imx$ vi arch/arm/boot/dts/imx6ul-14x14-evk.dts
leds {
compatible = “gpio-leds”;
pinctrl-names = “default”;
pinctrl-0 = <&pinctrl_leds>;

led0: user {
label = "user";
gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
default-state = "off";
};

led1: cpu {
label = "cpu";
gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
default-state = "on";
linux,default-trigger = "heartbeat";
};
};
1
2
3
4
5
6
7
8
9
10
11
12
13
pinctrl放在 &iomuxc下
pinctrl_leds: ledgrp {
fsl,pins = <
MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x1b0b0
MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x1b0b0

;
};

共设定两个灯,
一个是GPIO5 IO01 用户灯
一个是GPIO5 IO02 CPU心跳灯

(3)查找驱动
wujun@wj-vBox:~/freescale/linux-imxgrep−rn“gpio−leds”driversdrivers/leds/leds−gpio.c:237:.compatible=“gpio−leds”,,触发方式源码在trigger目录下wujun@wj−vBox: /freescale/linux−imx/drivers/ledsgrep−rn“gpio−leds”driversdrivers/leds/leds−gpio.c:237:.compatible=“gpio−leds”,,触发方式源码在trigger目录下wujun@wj−vBox: /freescale/linux−imx/drivers/leds ls trigger/
built-in.o ledtrig-cpu.c ledtrig-heartbeat.c ledtrig-timer.o
Kconfig ledtrig-cpu.o ledtrig-heartbeat.o ledtrig-transient.c
ledtrig-backlight.c ledtrig-default-on.c ledtrig-ide-disk.c ledtrig-transient.o
ledtrig-backlight.o ledtrig-default-on.o ledtrig-oneshot.c Makefile
ledtrig-camera.c ledtrig-gpio.c ledtrig-oneshot.o modules.builtin
ledtrig-camera.o ledtrig-gpio.o ledtrig-timer.c modules.order
这些的编译时通过内核配置项来确定的。

(4)启动系统
通过查看LED的trigger文件,就能知道当前LED支持的触发器和目前设定的触发器
root@imx6ulevk:~# cat /sys/class/leds/user/trigger
[none] rc-feedback nand-disk mmc0 mmc1 timer oneshot heartbeat backlight gpio
root@imx6ulevk:~# cat /sys/class/leds/cpu/trigger
none rc-feedback nand-disk mmc0 mmc1 timer oneshot [heartbeat] backlight gpio

user led没有设定trigger
cpu led设定为heartbeat trigger

设置触发器也很简单,使用echo将触发器名称写入trigger文件即可。
写入的字符串一定是trigger文件已经存在的,否则会提示参数非法。
这里将user灯也设定为心跳灯。
root@imx6ulevk:~# echo heartbeat > /sys/class/leds/user/trigger
此时user灯与cpu灯同时闪烁。不过不是同步的。

再次查看用户灯的触发方式
root@imx6ulevk:~# cat /sys/class/leds/user/trigger
none rc-feedback nand-disk mmc0 mmc1 timer oneshot [heartbeat] backlight gpio
已经设定成心跳灯了。

(5)心跳灯控制源码
因为比较好奇心跳灯闪的频率,查看了驱动源码。
wujun@wj-vBox:~/freescale/linux-imx/drivers/leds$ vi trigger/ledtrig-heartbeat.c
找到了控制闪灯时序的代码。

static void led_heartbeat_function(unsigned long data)
{
struct led_classdev led_cdev = (struct led_classdev ) data;
struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
unsigned long brightness = LED_OFF;
unsigned long delay = 0;

if (unlikely(panic_heartbeats)) {
led_set_brightness(led_cdev, LED_OFF);
return;
}

/* acts like an actual heart beat -- ie thump-thump-pause... */
switch (heartbeat_data->phase) {
case 0:
/*
* The hyperbolic function below modifies the
* heartbeat period length in dependency of the
* current (1min) load. It goes through the points
* f(0)=1260, f(1)=860, f(5)=510, f(inf)->300.
*/
heartbeat_data->period = 300 +
(6720 << FSHIFT) / (5 * avenrun[0] + (7 << FSHIFT));
heartbeat_data->period =
msecs_to_jiffies(heartbeat_data->period);
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
brightness = led_cdev->max_brightness;
break;
case 1:
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
heartbeat_data->phase++;
break;
case 2:
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
brightness = led_cdev->max_brightness;
break;
default:
delay = heartbeat_data->period - heartbeat_data->period / 4 -
msecs_to_jiffies(70);
heartbeat_data->phase = 0;
break;
}

led_set_brightness_async(led_cdev, brightness);
mod_timer(&heartbeat_data->timer, jiffies + delay);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
}

代码比较简单,不过里面有个细节
/* acts like an actual heart beat – ie thump-thump-pause… */
这个意思是说,模拟人的心跳,从这点上看,写这段代码的工程师是具有追求极致的精神。心跳灯都要模拟心跳的频率。
另外一个点就是周期的计算方法。
/*
* The hyperbolic function below modifies the
* heartbeat period length in dependency of the
* current (1min) load. It goes through the points
* f(0)=1260, f(1)=860, f(5)=510, f(inf)->300.
*/
heartbeat_data->period = 300 +
(6720 << FSHIFT) / (5 * avenrun[0] + (7 << FSHIFT));
从代码的意思上看,是根据当前的系统load来决定周期。
如果系统load是0,周期就是1260,其他类推。
300 + (6270 << 11) / (5 * 0) + (7 << 11) = 300 + 6270 / 7 = 300 + 960 = 1260;

其中FSHIFT可以从下面路径找到定义
wujun@wj-vBox:~/freescale/linux-imx/include/linux$ grep -rn “FSHIFT” .
./sched.h:153:#define FSHIFT 11 /* nr of bits of precision */
这个是因为linux内核避免使用浮点运算所以用整数来计算。

linux内核定义了unsigned long avenrun[3];三个长整型数据。
wujun@wj-vBox:~/freescale/linux-imx$ vi ./kernel/sched/proc.c +61
61 unsigned long avenrun[3];
在32位的cpu上,long对应的就是32bit,其中低11位用于存放负载的小数部分,高21位用于存放整数部分。
之所以是三个变量,是因为内核要记录cpu的load有三个变量,分别是1min,5min和15min。
运行top的时候能够看到这三个变量的值。
load average: 0.00, 0.02, 0.00

运行uptime也可以看到
wujun@wj-vBox:~/freescale/linux-imx$ uptime
11:44:08 up 21:23, 1 user, load average: 0.00, 0.02, 0.00

这三个值是从/proc/loadavg中获得的。
wujun@wj-vBox:~/freescale/linux-imx$ cat /proc/loadavg
0.00 0.02 0.00 1/167 5038

得出结论是在cpu load为0的情况下,闪灯周期是1260ms。
总共闪两次,每次亮70ms,两次亮之间的时间差是周期的1/4.
也就是在cpu load = 0情况下:
|70 | |70 |
| 415ms |
| 415ms | 415ms | 415ms | 415ms |

(6)最后用示波器看一下波形是否如预期。
因为GPIO的驱动能力有限,一般LED控制都是选择灌电流。这样逻辑上是反向的,低电平亮,高电平灭。
上图

imx6ul linux4.1.15 LED驱动配置及heartbeat源码分析【转】的更多相关文章

  1. Spring Boot从入门到精通(五)多数据源配置实现及源码分析

    多数据源配置在项目软件中是比较常见的开发需求,Spring和Spring Boot中对此都有相应的解决方案可供大家参考.在Spring Boot中,如MyBatis.JdbcTemplate以及Jpa ...

  2. (九)uboot配置编译、源码分析

    一.X210官方uboot配置编译实践1.找到官方移植好的uboot(BSP概念)(1)源头的源代码是uboot官网下载的.这个下载的源代码可能没有你当前使用的开发板的移植,甚至找不到当前开发板使用的 ...

  3. 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入

    使用react全家桶制作博客后台管理系统   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...

  4. C++STL内存配置的设计思想与关键源码分析

    说明:我认为要读懂STL中allocator部分的源码,并汲取它的思想,至少以下几点知识你要了解:operator new和operator delete.handler函数以及一点模板知识.否则,下 ...

  5. Spring Boot JDBC:加载DataSource过程的源码分析及yml中DataSource的配置

    装载至:https://www.cnblogs.com/storml/p/8611388.html Spring Boot实现了自动加载DataSource及相关配置.当然,使用时加上@EnableA ...

  6. spring cloud EurekaClient 多网卡 ip 配置 和 源码分析(转)

    https://blog.csdn.net/qq_30062125/article/details/83856655 1.前言对于spring cloud,各个服务实例需要注册到Eureka注册中心. ...

  7. (转)Linux设备驱动之HID驱动 源码分析

    //Linux设备驱动之HID驱动 源码分析 http://blog.chinaunix.net/uid-20543183-id-1930836.html HID是Human Interface De ...

  8. Linux MMC 驱动子系统简述(源码剖析)

    1. Linux MMC 驱动子系统 块设备是Linux系统中的基础外设之一,而 MMC/SD 存储设备是一种典型的块设备.Linux内核设计了 MMC子系统,用于管理 MMC/SD 设备. MMC ...

  9. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

随机推荐

  1. c#之如何计算哈希值字符串

    代码如下: /// <summary> /// 计算哈希值字符串 /// </summary> public static string ComputeHash(byte[] ...

  2. SEO经验-如何做到新站上线半个月谷歌收录3万

    一个网站在做搜索引擎优化的时候,首先考虑的肯定是百度,这个是毋庸置疑的,毕竟百度占领者差不多七成的搜索市场份额. 第二考虑的是360搜索,这个也是毋庸置疑的,因为360搜索占领者差不多两成的搜索市场份 ...

  3. jQuery事件--change([[data],fn])、on(events,[selector],[data],fn)和hover([over,]out)

    change([[data],fn]) 概述 当元素的值发生改变时,会发生 change 事件. 该事件仅适用于文本域(text field),以及 textarea 和 select 元素.当用于 ...

  4. laravel中使用的PDF扩展包——laravel-dompdf和laravel-snappy

    这两天项目中需要将HTML页面转换为PDF文件方便打印,我在网上搜了很多资料.先后尝试了laravel-dompdf和laravel-snappy两种扩展包,个人感觉laravel-snappy比较好 ...

  5. ETL面试题集锦

    1. What is a logical data mapping and what does it mean to the ETL team? 什么是逻辑数据映射?它对ETL项目组的作用是什么? 答 ...

  6. python模板字符串和格式化字符串

    模板字符串:用string模块里的Template Template()里面把字符串中某个值用设置变量${key}的方式先写好,然后在substitute()的方式把变量用其他值代替,就完成了字符串的 ...

  7. Subversion客户端接受服务器证书出现“The certificate hostname does not match”的问题

    当使用https://形式的URL连接Apache时,Subversion客户端将会受到两个类型的响应: 1.一个服务器证书 2.一个针对客户端证书的请求 在本人的应用场景主要涉及SVN仓库迁移的操作 ...

  8. Linux服务器配置---安装nfs

    安装nfs NFS是Network File System的缩写,即网络文件系统.客户端通过挂载的方式将NFS服务器端共享的数据目录挂载到本地目录下. 由于NFS支持的功能很多,不同功能会使用不同程序 ...

  9. 2018年Android面试题含答案--适合中高级

    1.java中==和equals和hashCode的区别  基本数据类型的==比较的值相等. 类的==比较的内存的地址,即是否是同一个对象,在不覆盖equals的情况下,同比较内存地址,原实现也为 = ...

  10. こだわり者いろはちゃん / Iroha's Obsession (暴力枚举)

    题目链接:http://abc042.contest.atcoder.jp/tasks/arc058_a Time limit : 2sec / Memory limit : 256MB Score ...