本文转载自: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. kafka 单机配置

    http://blog.csdn.net/jingshuigg/article/details/24439637 . su root : chown -R hadoop:hadoop version- ...

  2. mac install wget

    没有Wget的日子是非常难过的,强大的Mac OS 下安装Wget非常简单 下载一个Wget的源码包,http://www.gnu.org/software/wget/ ftp下载地址:ftp://f ...

  3. 3.用Thead子类及Runnable接口类实现车站购票的一个场景(static关键字)

    如上图所示,我们这里模拟一下去车站买票的情形:这里有3个柜台同时售票,总共是1000张票,这三个柜台同时买票,但是只能一个柜台卖同一张票,也就是说1号票卖了之后我们就只能买2号票,2号票卖了之后我们只 ...

  4. Sitecore 9有什么新功能

    在这个新版本中有很多值得爱的东西.每个人都会有自己喜欢的新功能,但是,我想与你分享一些地雷: xConnect 正如我们在Sitecore的官方Sitecore 9新闻稿中所见的那样,“新的xConn ...

  5. 编程中的链式调用:Scala示例

    编程中的链式调用与Linux Shell 中的管道类似.Linux Shell 中的管道 ,会将管道连接的上一个程序的结果, 传递给管道连接的下一个程序作为参数进行处理,依次串联起N个实用程序形成流水 ...

  6. win10 常用设置 桌面出来计算机图标,固定桌面摆好的图标设置方法,电脑设备ID方法

    win10 常用设置 桌面出来计算机图标,固定桌面摆好的图标设置方法 桌面右键-->显示设置-->桌面图标设置 电脑设备ID:xxx查看方法:桌面右键-->显示设置-->关于

  7. RESTful API 设计指南,RESTful API 设计最佳实践

    RESTful API 设计指南,RESTful API 设计最佳实践 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). ...

  8. 1069: 统计字符gets函数

    题目描述 编制程序,统计文本stdin中字符$出现的次数,并将结果写入文件stdout 输入 字符文本 输出 $次数 样例输入 as$dfkjhkjkjdhf asdfkj$lskdfj werijw ...

  9. Porsche Piwis Tester 2 Online Coding Guide

    Porsche Piwis online programming account service is piwis porsche subscription and piwis tester 2 on ...

  10. 介绍Python中6个序列的内置类型

    1.Python中6个序列的内置类型分别是什么? Python包含6中内建的序列,即列表.元组.字符串.Unicode字符串.buffer对象和 xrange 对象.序列通用的操作包括:索引.长度.组 ...