内核notifier机制应用

2024-05-15 06:58
文章标签 应用 机制 内核 notifier

本文主要是介绍内核notifier机制应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

最近在Android10.0系统上调试TP驱动,需要增加双击唤醒功能。so easy,在驱动的suspend和early_suspend接口中获取系统待机标志,然后在触摸事件处理函数上根据该标志位进行判断,如果已经待机,则上报POWER事件,如果正常工作状态,则上报触摸事件。

当然,事与愿违的事情很多,不差这一件。在调试的过程中,发现内核中已经没有early_suspend相关的接口,SDK提供方也没做相关实现。那系统进入浅睡眠的时候,TP驱动中如何知道系统已进入待机?

在这个过程中尝试了三种方法:

1.runtime pm机制。但这个跟Android的电源管理没有关联,只是设备自个的电源管理,无法满足当前的需求,弃之;2.在TP驱动中增加一个节点,当系统进入待机的时候,往该节点写入一个标志位,这样驱动就知道系统进入待机了,
满足需求,可用,但涉及修改上层,且后续如果有其他驱动需要获取待机标志,又要新增节点,麻烦,弃之;3.使用内核的事件通知链机制,待机的时候,肯定会灭屏,在背光驱动中发出灭屏事件,TP驱动注册事件通知函数,
这样就能获取到屏的状态,也就可以做出判断了。满足需求,可用。

本文就说下如何使用内核中事件通知链机制。

概述

内核中大多数子系统是相互独立的,如果某个子系统做了一件了不得的事,那么有办法告知其他子系统么?答案是肯定的,内核提供了消息通知机制,维护了一张通知链表。通知链表是一个函数链表,链表上的每一个节点都注册了一个函数。如果内核中A子系统对B子系统发生的事情感兴趣,则可以注册消息回调函数,那么当B子系统发出某个事件时,A就能在回调函数中接收到,从而根据不同的事件进行对应的操作。

涉及的函数和数据结构

notify的使用比较简单,涉及到三个函数和一个数据结构:

1.int fb_register_client(struct notifier_block *nb);
2.int fb_unregister_client(struct notifier_block *nb);
3.int fb_notifier_call_chain(unsigned long val, void *v);
4.struct notifier_block;

其中1,2,4只会在事件注册端使用,而3则是在事件发出端使用。

用法

在事件注册端,即TP driver端,需要声明一个notifier_block类型的结构体,该结构体在如下文件中定义:

./kernel/linux-4.9/include/linux/notifier.h
struct notifier_block {notifier_fn_t notifier_call;struct notifier_block __rcu *next;int priority;
};

这里需要关注的是notifier_call这个成员,这是一个函数指针,TP driver中需要实现一个回调函数,然后赋值给它:

static int tp_notifier_call_handler(struct notifier_block *this,unsigned long event, void *cmd) {return 0;
}
struct notifier_block tp_notifier_block = {.notifier_call = tp_notifier_call_handler,
}

初始化好tp_notifier_block后,需要将tp_notifier_block注册到kernel的notify列表中:

static int xxx_probe(struct platform_device *pdev)
{...int err = fb_register_client(&tp_notifier_block);if (err > 0) {printk("fb_register_client failed...\n");return -1;}return 0;
}

当然,最后不要忘记remove掉:

static int xxx_remove(struct platform_device *pdev)
{...fb_unregister_client(&tp_notifier_block);return 0;
}

如此一来,注册就做好了,只等事件发出端,即LCD driver发出事件。

事件发出也简单,如下:

static void event_notify(int blank) {struct fb_event event;event.data = ␣ //这里定义具体的cmdif (blank > FB_BLANK_POWERDOWN)blank = FB_BLANK_POWERDOWN;fb_notifier_call_chain(FB_EVENT_BLANK, &event); //FB_EVENT_BLANK为事件
}

只需要在合适的场合调用event_notify函数,即可实现屏状态被TP driver获取。

大概原理

notify的原理比较简单,如下图所示:

在这里插入图片描述

在fb_notify中定义了一个notify列表fb_notifier_list,当tp driver通过fb_register_client函数注册一个notifier_block时,其实就是往fb_notifier_list中添加该notifier_block变量。之后当LCD driver调用fb_notifier_call_chain函数发出事件时,其实就是遍历notify列表fb_notifier_list中的各个notifier_block成员,调用里面TP driver初始化好的回调函数。

结语

学习了notify后,去看了early_suspend的实现,发现也是类似的用法,先声明一个early_suspend变量,初始化好early_suspend和late_resume方法,然后再进行注册,其实也是加到内核中early_suspend list中。之后系统进入待机(非深待)状态时,就会通过遍历该list,依次调用里面成员的early_suspend函数,唤醒流程类似。

微信公众号

我在微信公众号也有写文章,更新比较及时,有兴趣者可以扫描如下二维码,或者微信搜索【Android系统实战开发】,关注有惊喜哦!
在这里插入图片描述

这篇关于内核notifier机制应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/991124

相关文章

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

java中反射(Reflection)机制举例详解

《java中反射(Reflection)机制举例详解》Java中的反射机制是指Java程序在运行期间可以获取到一个对象的全部信息,:本文主要介绍java中反射(Reflection)机制的相关资料... 目录一、什么是反射?二、反射的用途三、获取Class对象四、Class类型的对象使用场景1五、Class

新特性抢先看! Ubuntu 25.04 Beta 发布:Linux 6.14 内核

《新特性抢先看!Ubuntu25.04Beta发布:Linux6.14内核》Canonical公司近日发布了Ubuntu25.04Beta版,这一版本被赋予了一个活泼的代号——“Plu... Canonical 昨日(3 月 27 日)放出了 Beta 版 Ubuntu 25.04 系统镜像,代号“Pluc

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Java中&和&&以及|和||的区别、应用场景和代码示例

《Java中&和&&以及|和||的区别、应用场景和代码示例》:本文主要介绍Java中的逻辑运算符&、&&、|和||的区别,包括它们在布尔和整数类型上的应用,文中通过代码介绍的非常详细,需要的朋友可... 目录前言1. & 和 &&代码示例2. | 和 ||代码示例3. 为什么要使用 & 和 | 而不是总是使

Python循环缓冲区的应用详解

《Python循环缓冲区的应用详解》循环缓冲区是一个线性缓冲区,逻辑上被视为一个循环的结构,本文主要为大家介绍了Python中循环缓冲区的相关应用,有兴趣的小伙伴可以了解一下... 目录什么是循环缓冲区循环缓冲区的结构python中的循环缓冲区实现运行循环缓冲区循环缓冲区的优势应用案例Python中的实现库

SpringBoot整合MybatisPlus的基本应用指南

《SpringBoot整合MybatisPlus的基本应用指南》MyBatis-Plus,简称MP,是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,下面小编就来和大家介绍一下... 目录一、MyBATisPlus简介二、SpringBoot整合MybatisPlus1、创建数据库和

python中time模块的常用方法及应用详解

《python中time模块的常用方法及应用详解》在Python开发中,时间处理是绕不开的刚需场景,从性能计时到定时任务,从日志记录到数据同步,时间模块始终是开发者最得力的工具之一,本文将通过真实案例... 目录一、时间基石:time.time()典型场景:程序性能分析进阶技巧:结合上下文管理器实现自动计时