(Sysfs_notify唤醒用户面进程)
概述
这是一个很有用的内核与用户面交互的机制。
简单而言就是:sysfs_notify()可以唤醒在读写属性文件上时因调用select()、poll()、epoll()而阻塞的用户面进程。(sysfs_notify_dirent()也可以唤醒,但我没有实际测试过)。内核借助于sysfs创建了属性文件,用户面程序可以读写这些属性文件实现与内核的交互。
项目模型
在本项目中,处理器是xilinx的ZYNQ MPSOC,它是一款高性能、AMP架构的处理器,内部集成了FPGA、4个A53核、2个R5核。在应用中,A53使用嵌入式linux操作系统,R5使用实时多任务操作系统FreeOS,我们使用IPI邮箱机制来实现A53与R5核之间的通信:当A53收到R5的邮箱消息时,就通知用户面的进程去作相应处理。在用户面的进程中,我们选择epoll()来监测文件描述符,之所以选择epoll而没有选择selec、poll,是因为在绝大多数情况下,epoll有更好的性能。
(关于深入理解并熟练使用epoll,如下的这篇文章总结得很透彻:blog.chinaunix.net/uid-28541347-id-4273856.html )。
A53的linux内核使用sysfs创建了两个属性文件,这两个属性文件是:
remote_kick:文件属性是-rw-r–r--,当A53接收到R5的中断时,在该文件中写入“1”;
remote_pending_message:文件属性是-r–r--r–,当A53接收到R5的中断时,将邮箱消息写入该文件,等待用户面进程读取;
A53上用户面与内核的交互机制如下:
1、用户面进程通过fd_remote_kick = open(“remote_kick”,O_RDNOLY)打开“remote_kick”文件的描述符;
2、用户面进程通过epoll()监测fd_remote_kick,当监测条件未满足时,epoll()阻塞、进入睡眠;
3、当R5向A53发送中断时,内核读取邮箱消息并写入到remote_pending_message文件,同时内核调用sysfs_notify()。由于内核调用了sysfs_notify(),唤醒了阻塞在其上的epoll();
4、epoll()唤醒后,用户面进程读取remote_pending_message文件的内容,并进行相应处理。
参考代码
用户面代码:
#include <sys/epoll.h>
struct epoll_event PollEvent, *pEvent = NULL;
int fd_epoll &#