在linux内核系统中,各个模块、子系统之间是相互独立的。Linux内核可以通过通
知链机制来获取由其它模块或子系统产生的它感兴趣的某些事件。
使用notifier由通知者
可以传递给被通知者长整型参数与指针。在linux中有许多地
方用到,比如reboot通知,cpu调频通知,网卡事件,电池低电警报等等。熟
悉使用notifier有助于linux内核驱动开发。
notifier_block结构:
其中,
1. notifier_call:通知链回调函数,由被通知方提供,第一个 参数notifier_block结构体指针,第二第三个参数分别是由call chain, 也就是通知链发起者传递过来的;
2. notifier_block *next:用于链接成链表的指针;
3. priority:回调函数的优先级,一般默认为0。
何时调用到notifier_call?通常在通知链register与unregister定义文件中就有 notifier call发起函数;
下面是具体应用实例:
被通知文件中:
1:在被通知链文件定义一个notifier call函数:
3:注册alarm_notifier通知链:
probe函数里面:
通知文件中:
1:定义notifier register函数,提供给被通知链调用:
2:notifier call发起的地方,这里是在中断的queue work里面调用
srcu_notifier_call_chain(),其被内核定义在
notifier.c,注意后面的2个参数会传递给回调函数。
notifier_block结构:
struct notifier_block {
int (*notifier_call)(struct notifier_block *, unsigned long, void *);
struct notifier_block __rcu *next;
int priority;
};
其中,
1. notifier_call:通知链回调函数,由被通知方提供,第一个 参数notifier_block结构体指针,第二第三个参数分别是由call chain, 也就是通知链发起者传递过来的;
2. notifier_block *next:用于链接成链表的指针;
3. priority:回调函数的优先级,一般默认为0。
何时调用到notifier_call?通常在通知链register与unregister定义文件中就有 notifier call发起函数;
下面是具体应用实例:
被通知文件中:
1:在被通知链文件定义一个notifier call函数:
static int xxxx_notify(struct notifier_block *nb,
unsigned long status, void *unused)
{
int rc;
if (!the_chip) {
pr_err("not initialized\n");
return -EINVAL;
}
switch (status) {
case 0:
pr_debug("0 received\n");
break;
case 1:
pr_debug("1 received\n");
break;
case 2:
break;
default:
pr_err("error received\n");
break;
}
return 0;
};
2:定义alarm_notifier通知链,将上面定义的函数入口赋值给函数指针
notifier_call;
static struct notifier_block xxxx_notifier = {
.notifier_call = xxxx_notify,
};
3:注册alarm_notifier通知链:
probe函数里面:
{
-----
rc = xxxx_register_notifier(&alarm_notifier);
if (rc) {
pr_err("unable to register alarm notifier rc=%d\n", rc);
return rc;
------
}
通知文件中:
1:定义notifier register函数,提供给被通知链调用:
int xxxx_register_notifier(struct notifier_block *nb)
{
-------
rc = srcu_notifier_chain_register(&chip->irq_notifier_list, nb);
-------
return rc;
}
EXPORT_SYMBOL(xxxx_register_notifier);
2:notifier call发起的地方,这里是在中断的queue work里面调用
srcu_notifier_call_chain(),其被内核定义在
notifier.c,注意后面的2个参数会传递给回调函数。
static void xxxx_isr_work(struct work_struct *work)
{
struct xxxx_chip *chip
= container_of(work, struct xxxx_chip, irq_work);
int status;
if (!chip)
return;
status = xxxx_status_read();
srcu_notifier_call_chain(&chip->irq_notifier_list,
status, NULL);
}