异步通知机制的总结

    xiaoxiao2021-03-26  21

    异步通知机制可以达到这样一个效果:应用程序不用主动查询,而是当事件发生时,驱动程序主动给应用程序发信号,然后应用程序再进行处理。

    要实现这一个目的,需要解决以下几个问题: ①注册信号处理函数 ②谁发? ③发给谁? ④怎么发?

    先贴出应用程序:

    int fd;

    void my_signal_fun(int signum) { unsigned char key_values; read(fd,&key_values,1); printf(“key_values: 0x%x\n”,key_values); }

    int main(int argc,char **argv) { int Oflags;

    signal(SIGIO,my_signal_fun); fd = open("/dev/buttons", O_RDWR); if (fd < 0) printf("can't open\n"); fcntl(fd,F_SETOWN,getpid()); Oflags = fcntl(fd,F_GETFL); fcntl(fd,F_SETFL,Oflags | FASYNC); while(1){ sleep(1000); } return 0;

    }

    先解决第一个问题和第三个问题,自然是要在应用程序里注册信号处理函数,需要用到signal(int signum, sighandler_t handler);其中的handler自然就是我们自己的信号处理函数了。我们把它设为void my_signal_fun(int signum),当收到信号之后即调用,在这个函数里完成read操作,并把键值打印出来。

    第二个问题和第四个问题,自然是跟驱动程序有关。我们可以在中断处理程序中完成发送,需要用到kill_fasync(&button_async_queue, SIGIO, POLL_IN);其中button_async_queue是一个队列,在struct fasync_struct *button_async_queue中定义,但并没有初始化。

    如何初始化呢?这个初始化并不是驱动程序主动的,所以这个步骤要在应用程序引导。

    fcntl(fd,F_SETOWN,getpid()); Oflags = fcntl(fd,F_GETFL); fcntl(fd,F_SETFL,Oflags | FASYNC);

    第一句话的目的是将应用程序的进程号发给驱动程序,后两句话的目的是调用系统调用sys_fasync(因为有一旦flag发生改变就调用fasync的设定)。这就需要在驱动程序里的file_operation结构里添加.fasync = fifth_drv_fasync,然后在fifth_drv_fasyncz()中调用fasync_helper(fd, file, on, &button_async_queue),这个fasync_helper函数是内核提供的,可以完成对button_async_queue的初始化。

    大概的流程及实现就是这样。

    转载请注明原文地址: https://ju.6miu.com/read-660570.html

    最新回复(0)