初探linux子系统集之led子系统(二)【转】
本文转载自:http://blog.csdn.net/eastmoon502136/article/details/37606487
巴西世界杯,德国7比1东道主,那个惨不忍睹啊,早上起来看新闻,第一眼看到7:1还以为点球也能踢成这样,后来想想,点球对多嘛6比1啊,接着就是各种新闻铺天盖地的来了。其实失败并没有什么,人生若是能够成功一次,那么再多的失败也是值得的,脚踏实地,失败了再次爬起来。很多时候,在一切都那么顺利的情况下,反而觉得没有啥意思,有一些挑战,一些失败,一些打击,接着,就会很努力很努力地去做,慢慢地就会被自己征服,很喜欢这种感受,废话说多了,还是接着研究led子系统吧。
对于led子系统中,有那么多得trigger,下面就来简单了解下。
1、default-on
- <pre name="code" class="html">static voiddefon_trig_activate(struct led_classdev *led_cdev)
- {
- led_set_brightness(led_cdev,led_cdev->max_brightness);
- }
- static structled_trigger defon_led_trigger = {
- .name = "default-on",
- .activate = defon_trig_activate,
- };
- static voiddefon_trig_activate(struct led_classdev *led_cdev)
- {
- led_set_brightness(led_cdev,led_cdev->max_brightness);
- }
- static structled_trigger defon_led_trigger = {
- .name = "default-on",
- .activate = defon_trig_activate,
- };
Default-on主要是设置led为最大亮度。
2、backlight
- struct bl_trig_notifier {
- structled_classdev *led; //led子系统设备
- intbrightness; //亮度
- intold_status;
- structnotifier_block notifier; //内核通知链
- unsignedinvert;
- };
- static struct led_trigger bl_led_trigger ={
- .name = "backlight",
- .activate = bl_trig_activate,
- .deactivate = bl_trig_deactivate
- };
- static void bl_trig_activate(structled_classdev *led)
- {
- intret;
- structbl_trig_notifier *n;
- n= kzalloc(sizeof(struct bl_trig_notifier), GFP_KERNEL);
- led->trigger_data= n;
- if(!n) {
- dev_err(led->dev,"unable to allocate backlight trigger\n");
- return;
- }
- ret= device_create_file(led->dev, &dev_attr_inverted);
- if(ret)
- gotoerr_invert;
- n->led= led;
- n->brightness= led->brightness;
- n->old_status= UNBLANK;
- n->notifier.notifier_call= fb_notifier_callback;
- ret= fb_register_client(&n->notifier);
- if(ret)
- dev_err(led->dev,"unable to register backlight trigger\n");
- return;
- err_invert:
- led->trigger_data= NULL;
- kfree(n);
- }
其中fb_register_client注册到了framebuffer中的fb_notifier_list中,一旦framebuffer驱动中有事件,就会调用内核通知链中注册好的函数fb_notifier_callback。
关于内核通知链,这里就插播一曲来自网络的摘抄了:
大多数内核子系统都是相互独立的,因此某个子系统可能对其它子系统产生的事件感兴趣。为了满足这个需求,也即是让某个子系统在发生某个事件时通知其它的子系统,Linux内核提供了通知链的机制。通知链表只能够在内核的子系统之间使用,而不能够在内核与用户空间之间进行事件的通知。
通知链表是一个函数链表,链表上的每一个节点都注册了一个函数。当某个事情发生时,链表上所有节点对应的函数就会被执行。所以对于通知链表来说有一个通知方与一个接收方。在通知这个事件时所运行的函数由被通知方决定,实际上也即是被通知方注册了某个函数,在发生某个事件时这些函数就得到执行。其实和系统调用signal的思想差不多。
通知链技术可以概括为:事件的被通知者将事件发生时应该执行的操作通过函数指针方式保存在链表(通知链)中,然后当事件发生时通知者依次执行链表中每一个元素的回调函数完成通知。
- static int fb_notifier_callback(struct notifier_block *p,
- unsignedlong event, void *data)
- {
- structbl_trig_notifier *n = container_of(p,
- structbl_trig_notifier, notifier);
- struct led_classdev*led = n->led;
- struct fb_event*fb_event = data;
- int *blank =fb_event->data;
- int new_status =*blank ? BLANK : UNBLANK;
- switch (event) {
- case FB_EVENT_BLANK :
- if(new_status == n->old_status)
- break;
- if((n->old_status == UNBLANK) ^ n->invert) {
- n->brightness= led->brightness;
- led_set_brightness(led,LED_OFF);
- } else {
- led_set_brightness(led,n->brightness);
- }
- n->old_status= new_status;
- break;
- }
- return 0;
- }
如果触发了FB_EVENT_BLANK,那么就执行相应的操作。
3、timer
- static structled_trigger timer_led_trigger = {
- .name = "timer",
- .activate =timer_trig_activate,
- .deactivate =timer_trig_deactivate,
- };
- static voidtimer_trig_activate(struct led_classdev *led_cdev)
- {
- int rc;
- led_cdev->trigger_data= NULL;
- rc =device_create_file(led_cdev->dev, &dev_attr_delay_on);
- if (rc)
- return;
- rc =device_create_file(led_cdev->dev, &dev_attr_delay_off);
- if (rc)
- gotoerr_out_delayon;
- led_blink_set(led_cdev,&led_cdev->blink_delay_on,
- &led_cdev->blink_delay_off);
- led_cdev->trigger_data= (void *)1;
- return;
- err_out_delayon:
- device_remove_file(led_cdev->dev,&dev_attr_delay_on);
- }
当某个led_classdev与之连接后,这个触发器会在/sys/class/leds/<device>/下创建两个文件delay_on和delay_off。用户空间往这两个文件中写入数据后,相应的led会按照设置的高低电平的时间(ms)来闪烁。如果led_classdev注册了硬件闪烁的接口led_cdev->blink_set就是用硬件控制闪烁,否则用软件定时器来控制闪烁。
4、heatbeat
- static structled_trigger heartbeat_led_trigger = {
- .name = "heartbeat",
- .activate =heartbeat_trig_activate,
- .deactivate = heartbeat_trig_deactivate,
- };
- structheartbeat_trig_data {
- unsigned int phase;
- unsigned int period;
- struct timer_listtimer;
- };
- static voidheartbeat_trig_activate(struct led_classdev *led_cdev)
- {
- structheartbeat_trig_data *heartbeat_data;
- heartbeat_data =kzalloc(sizeof(*heartbeat_data), GFP_KERNEL);
- if (!heartbeat_data)
- return;
- led_cdev->trigger_data= heartbeat_data;
- setup_timer(&heartbeat_data->timer,
- led_heartbeat_function, (unsigned long)led_cdev);
- heartbeat_data->phase= 0;
- led_heartbeat_function(heartbeat_data->timer.data);
- }
设置了heartbeat_data->phase,然后调用led_heartbeat_function。
- static voidled_heartbeat_function(unsigned long data)
- {
- struct led_classdev*led_cdev = (struct led_classdev *) data;
- structheartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
- unsigned longbrightness = LED_OFF;
- unsigned long delay =0;
- /* acts like anactual 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 thepoints
- * 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(led_cdev,brightness);
- mod_timer(&heartbeat_data->timer,jiffies + delay);
- }
通过定时来实现类似于心跳的led灯。
5、ide-disk
- static voidledtrig_ide_timerfunc(unsigned long data)
- {
- if (ide_lastactivity!= ide_activity) {
- ide_lastactivity =ide_activity;
- /* INT_MAX will seteach LED to its maximum brightness */
- led_trigger_event(ledtrig_ide,INT_MAX);
- mod_timer(&ledtrig_ide_timer,jiffies + msecs_to_jiffies(10));
- } else {
- led_trigger_event(ledtrig_ide,LED_OFF);
- }
- }
- static int __initledtrig_ide_init(void)
- {
- led_trigger_register_simple("ide-disk",&ledtrig_ide);
- return 0;
- }
通过定时器实现类似于硬盘灯的指示。
以上便是led子系统中的trigger的一些简单介绍。
初探linux子系统集之led子系统(二)【转】的更多相关文章
- 初探linux子系统集之led子系统(二)
巴西世界杯,德国7比1东道主,那个惨不忍睹啊,早上起来看新闻,第一眼看到7:1还以为点球也能踢成这样,后来想想,点球对多嘛6比1啊,接着就是各种新闻铺天盖地的来了.其实失败并没有什么,人生若是能够成功 ...
- 初探linux子系统集之led子系统(一)
就像学编程第一个范例helloworld一样,学嵌入式,单片机.fpga之类的第一个范例就是点亮一盏灯.对于庞大的linux系统,当然可以编写一个字符设备驱动来实现我们需要的led灯,也可以直接利用g ...
- 初探linux子系统集之led子系统(一)【转】
本文转载自:http://blog.csdn.net/eastmoon502136/article/details/37569789 就像学编程第一个范例helloworld一样,学嵌入式,单片机.f ...
- 初探linux子系统集之led子系统(三)
世界杯结束了,德国战车夺得了大力神杯,阿根廷最终还是失败了.也许3年,5年,或者10年后,人们就不知道巴西世界杯的亚军是谁,但是总是会记得冠军是谁.就像什么考试,比赛,第一永远会被人们所记住,所以我们 ...
- 初探linux子系统集之led子系统(三)【转】
本文转载自:http://blog.csdn.net/eastmoon502136/article/details/37822837 世界杯结束了,德国战车夺得了大力神杯,阿根廷最终还是失败了.也许3 ...
- 转载-lvs官方文档-Linux服务器集群系统(二)
Linux服务器集群系统(二) LVS集群的体系结构 章文嵩 (wensong@linux-vs.org) 2002 年 4 月 本文主要介绍了LVS集群的体系结构.先给出LVS集群的通用体系结构,并 ...
- 初探linux子系统集之timer子系统(二)
想着博客中还没有翻译过一篇文章,虽然英文水平有限,但是借助google翻译慢慢地翻译出一篇文章也是不错的选择.那就来学习下hrtimer的文档吧,翻译的略搓,可以直接跳过这篇,这里仅作为学习的过程!^ ...
- 初探linux子系统集之i2c子系统(二)
大概也是前年了,一直没有把那个i2c的子系统讲解完,这里偷个懒,把以前整理的i2c相关的知识再梳理一下,做个了结,然后再去学习timer子系统. 先看下i2c在内核中的代码分布: obj-$(CONF ...
- 初探linux子系统集之timer子系统(三)
因为现在的linux虽然还是可以使用低精度的timer,但是趋势是高精度hrtimer,所以上一篇试着翻译一下hrtimer的一些介绍,翻译的不是很好,看来英语还得好好学习啊,下面还是好好学习下lin ...
随机推荐
- VS2015 “GENERATERESOURCE”任务意外失败 解决方法
昨天把项目解决方案Copy到另外的机器上执行,遭遇了一场"任务意外失败",网上搜索一下,顺利解决了,在此记录一下. Visual Studio.net 工程更换机器编译时遇到”Ge ...
- SHoj 420 购买装备
购买装备 发布时间: 2017年7月9日 18:17 最后更新: 2017年7月9日 21:05 时间限制: 1000ms 内存限制: 128M 描述 最近盛大的一款游戏传奇世界极其火爆. ...
- 洛谷 [P3224] 永无乡
Treap 的合并 首先感谢 @Capella 的DeBug 其次,这是由一个 & 号引发的血案 注意对于所有修改操作都要 & Treap的合并, 启发式合并,对于每一个节点都 ins ...
- 自动化测试框架之robot framework的应用分析
序言:很多人都对自动化测试框架痴迷,我曾经也痴迷过一段时间,以前觉得自己对框架说的头头是道,现在回过头来看以前,说归说,但在如何应用还是欠缺,这一段时间,自己经历了一系列框架的构建和应用的时期,所以, ...
- 标准C程序设计七---02
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- Python入门--1--基本中的基本
一. 1.这是一个面向对面的编程,一种解释性语言. 2.缩进是python的灵魂,使代码变得非常简洁,正确使用冒号“:”,IDLE的 下一行会自动缩进 3.if语句中 python拒绝接受 ...
- CentOS配置TFTP服务器
服务器端 软件包 tftp-server 启动脚本 /usr/sbin/in.tftpd 启动服务 /usr/lib/systemd/system/tftp.service 配置文件 /etc/xin ...
- Linux下多线程编程-信号量
今天来谈谈线程的同步--信号量. 首先来看看一些概念性的东西: 如进程.线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行:B依言执行,再将结果给 ...
- 前端进阶之路:初涉Less
阅读目录 一.Less介绍 1.官方介绍 2.自己理解 3.Less.Sass.Stylus 二.Less使用入门 1.开发模式下使用Less 2.运行模式下使用Less 三.常见用法示例 1.从第一 ...
- pomelo加入定时任务
需求:在arenaserver下添加一个rank定时任务,每一分钟对对玩家进行一次排行. 首先在game-server/app/servers/arena文件夹下添加cron文件夹. 在game-se ...