linux led子系统(二)
对于led子系统中,有那么多得trigger,下面就来简单了解下。
1、default-on
static void defon_trig_activate(struct led_classdev *led_cdev)
{
led_set_brightness(led_cdev, led_cdev->max_brightness);
}
static struct led_trigger defon_led_trigger = {
.name = "default-on",
.activate = defon_trig_activate,
};
static int __init defon_trig_init(void)
{
return led_trigger_register(&defon_led_trigger);
}
static void __exit defon_trig_exit(void)
{
led_trigger_unregister(&defon_led_trigger);
}
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子系统(二)【转】
本文转载自:http://blog.csdn.net/eastmoon502136/article/details/37606487 巴西世界杯,德国7比1东道主,那个惨不忍睹啊,早上起来看新闻,第一 ...
- linux led子系统(一)
就像学编程第一个范例helloworld一样,学嵌入式,单片机.fpga之类的第一个范例就是点亮一盏灯.对于庞大的linux系统,当然可以编写一个字符设备驱动来实现我们需要的led灯,也可以直接利用g ...
- Linux时间子系统(二) 软件架构
一.前言 本文的主要内容是描述内核时间子系统的软件框架.首先介绍了从旧的时间子系统迁移到新的时间子系统的源由,介绍新的时间子系统的优势.第三章汇整了时间子系统的相关文件以及内核配置.最后描述各种内核配 ...
- (linux)LED子系统
数据结构(/include/linux/leds.h) enum led_brightness { LED_OFF = 0, LED_HALF = 127, LED_FULL = 255, }; le ...
- Linux usb子系统(二) _usb-skeleton.c精析
"./drivers/usb/usb-skeleton.c"是内核提供给usb设备驱动开发者的海量存储usb设备的模板程序, 程序不长, 通用性却很强,十分经典, 深入理解这个文件 ...
- Linux i2c子系统(二) _通过i2c-dev.c访问设备的方法
另外一种驱动 应用层除了使用上述的使用i2c_driver接口来访问i2c设备,Linux内核还提供了一种简单粗暴的方式--直接通过虚拟i2c设备驱动的方式,即上一篇中的i2c-dev提供的方式,这种 ...
- 初探linux子系统集之led子系统(一)
就像学编程第一个范例helloworld一样,学嵌入式,单片机.fpga之类的第一个范例就是点亮一盏灯.对于庞大的linux系统,当然可以编写一个字符设备驱动来实现我们需要的led灯,也可以直接利用g ...
- Linux时间子系统之(二):软件架构
专题文档汇总目录 Notes:从框架上讲解了时间子系统,从底向上包括CPU Local TImer.Global Counter.Clock Souce/Clock Events模块管理.Tick D ...
随机推荐
- STM32F407 SPI 个人笔记
概述 SPI ,Serial Peripheral interface,串行外围设备接口 全双工,同步的通信总线,四根线 主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器 ...
- python类可以截获Python运算符
类可以截获Python运算符 现在,让我们来看类和模块的第三个主要差别: 运算符重载.简而言之,运算符重载就是让用类写成的对象,可截获并响应用在内置类型上的运算:加法.切片.打印和点号运算等.这只是自 ...
- matlab中函数学习——11月14日
1.记录数组元素个数函数:numel() 解释:number of array 相当于 prod(size(A)) 2.添加路径: addpath('.\3rdparty\ksvd'); 3.pada ...
- EXPDP/IMPDP任务的查看与管理
EXPDP/IMPDP相比传统的exp/imp的最本质区别在于服务器端执行,客户端发出指定后,通过API启动服务器的备份job,在执行过程中,可以拿下Ctrl+C组合键,退出当前交互模式,退出之后,导 ...
- Python之FTP传输
访问FTP,无非两件事情:upload和download,最近在项目中需要从ftp下载大量文件,然后我就试着去实验自己的ftp操作类,如下(PS:此段有问题,别复制使用,可以参考去试验自己的ftp类! ...
- [BZOJ1582] [Usaco2009 Hol]Holiday Painting 节日画画(线段树)
传送门 线段树区间修改傻题 #include <cstdio> #include <cstring> #include <iostream> #define N 5 ...
- BZOJ3926 [Zjoi2015]诸神眷顾的幻想乡 【广义后缀自动机】
题目 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看.幽香当然也非常高兴 ...
- bzoj3743 [Coci2015]Kamp 常州模拟赛d6t2
3743: [Coci2015]Kamp Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 484 Solved: 229[Submit][Status ...
- P1736 创意吃鱼法 (动态规划)
题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...
- 【DFS求树的最大二分匹配+输入外挂】HDU 6178 Monkeys
http://acm.hdu.edu.cn/showproblem.php?pid=6178 [题意] 给定一棵有n个结点的树,现在有k个猴子分布在k个结点上,我们可以删去树上的一些边,使得k个猴子每 ...