notify机制
通知链技术可以概括为:事件的被通知者将事件发生时应该执行的操作通过函数指针方式保存在链表(通知链)中,然后当事件发生时通知者依次执行链表中每一个元素的回调函数完成通知。
一、notify定义
struct notifier_block {
notifier_fn_t notifier_call;
struct notifier_block __rcu *next;
int priority;
};
由宏BLOCKING_NOTIFIER_HEAD来初始化notifier_block链表头
#define BLOCKING_NOTIFIER_HEAD(name)
struct blocking_notifier_head name =
BLOCKING_NOTIFIER_INIT(name)
其注册、注销、通知接口分别为
extern int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
struct notifier_block *nb);
extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
struct notifier_block *nb);
extern int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
unsigned long val, void *v);
这几个接口实际上是再封装(针对阻塞,不可阻塞等),通常在不同的内核子系统中,会做不同的封装。注册、注销、通知接口实质原型为:
static int notifier_chain_register(struct notifier_block **nl,
struct notifier_block *n);
static int notifier_chain_unregister(struct notifier_block **nl,
struct notifier_block *n);
static int __kprobes notifier_call_chain(struct notifier_block **nl,
unsigned long val, void *v,int nr_to_call, int *nr_calls);
通常会对这些接口再封装,比如,在FB子系统中,做了如下的封装处理:
static BLOCKING_NOTIFIER_HEAD(fb_notifier_list);
/**
* fb_register_client - register a client notifier
* @nb: notifier block to callback on events
*/
int fb_register_client(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&fb_notifier_list, nb);
}
EXPORT_SYMBOL(fb_register_client);
/**
* fb_unregister_client - unregister a client notifier
* @nb: notifier block to callback on events
*/
int fb_unregister_client(struct notifier_block *nb)
{
return blocking_notifier_chain_unregister(&fb_notifier_list, nb);
}
EXPORT_SYMBOL(fb_unregister_client);
/**
* fb_notifier_call_chain - notify clients of fb_events
*
*/
int fb_notifier_call_chain(unsigned long val, void *v)
{
return blocking_notifier_call_chain(&fb_notifier_list, val, v);
}
EXPORT_SYMBOL_GPL(fb_notifier_call_chain);
- 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
注册notify:
fb_register_client() ---->
blocking_notifier_chain_register() ---->
notifier_chain_register()
注销notify:
fb_unregister_client() ---->
blocking_notifier_chain_unregister() --->
notifier_chain_unregister()
通知notify:
fb_notifier_call_chain() ---->
blocking_notifier_call_chain() ---->
__blocking_notifier_call_chain() ---->
notifier_call_chain()
二、示例
例如在RK平台下,编写notify接口的驱动:
static void knock_input_later_resume(void)
{
DBG("%s :enter
", __func__);
gpio_set_value(gpio_info->gpio3,1);
return;
}
static void knock_input_early_suspend(
void)
{
DBG(
“%s :enter
”,
func);
gpio_set_value(gpio_info->gpio3,
0);
return;
}
static int knock_input_event_notify(
struct notifier_block *self,
unsigned
long action,
void *data)
{
struct fb_event *event = data;
int blank_mode = *((int *)event->data);
switch (blank_mode) {
case FB_BLANK_UNBLANK:
knock_input_later_resume();
break;
case FB_BLANK_NORMAL:
knock_input_early_suspend();
break;
default:
knock_input_early_suspend();
break;
}
return 0;
}
static struct notifier_block knock_input_fb_notifier = {
.notifier_call = knock_input_event_notify,
};
static int xxxx_probe(
struct platform_device *pdev){
…..
fb_register_client(&knock_input_fb_notifier);
…..
}
- 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
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52