linux内核notifier机制 linux通知链
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); }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。