内核异步通知的例子

来源:互联网 发布:php面试常见问题 编辑:程序博客网 时间:2024/05/07 23:35

       内核异步IO的介绍见http://blog.chinaunix.net/uid-25014876-id-62725.html,本文讲原文的例子进行了一定的改造,通过定义器的方法,定时时间一到就通过异步通知的方法发给上层的应用,应用捕捉到相应的信号后,执行相应的操作。

#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/wait.h>#include <linux/sched.h>#include <asm/uaccess.h>#include <linux/errno.h>#include <linux/device.h>#include <linux/timer.h>#define DEBUG_SWITCH    1#if DEBUG_SWITCH#define P_DEBUG(fmt, args...)   printk("<1>" "<kernel>[%s]"fmt, __FUNCTION__, ##args)#else#define P_DEBUG(fmt, args...)   printk("<7>" "<kernel>[%s]"fmt, __FUNCTION__, ##args)#endif#define DEV_SIZE 100struct test_t{char kbuf[DEV_SIZE];unsigned int major;unsigned int minor; dev_t devno;struct timer_list timer;struct cdev test_cdev;struct fasync_struct *async_queue;struct class *asyn_class;};static struct test_t my_dev;int test_open(struct inode *node, struct file *filp){struct test_t *dev;dev = container_of(node->i_cdev, struct test_t, test_cdev);filp->private_data = dev;return 0;}int test_fasync (int fd, struct file *filp, int mode){struct test_t *dev = filp->private_data;return fasync_helper(fd, filp, mode, &dev->async_queue);}int test_close(struct inode *node, struct file *filp){test_fasync(-1, filp, 0);return 0;}struct file_operations test_fops = {.open    = test_open,.release = test_close,.fasync  = test_fasync,};static void timer_function(unsigned long arg) { mod_timer(&my_dev.timer, jiffies + 2*HZ);if (my_dev.async_queue)kill_fasync(&my_dev.async_queue, SIGIO, POLL_IN);}static void timer_init(void){init_timer(&my_dev.timer);my_dev.timer.data=0;my_dev.timer.function=timer_function;my_dev.timer.expires=jiffies+2*HZ;add_timer(&my_dev.timer);}static int __init test_init(void){int result = 0;P_DEBUG("%s\n",__FUNCTION__);my_dev.major = 0;my_dev.minor = 0;if(my_dev.major){my_dev.devno = MKDEV(my_dev.major, my_dev.minor);result = register_chrdev_region(my_dev.devno, 1, "asynchronous_notification");}else{result = alloc_chrdev_region(&my_dev.devno, my_dev.minor, 1, "asynchronous_notification");my_dev.major = MAJOR(my_dev.devno);my_dev.minor = MINOR(my_dev.devno);}if(result < 0){P_DEBUG("register devno errno!\n");goto err0;}printk("major[%d] minor[%d]\n", my_dev.major, my_dev.minor);cdev_init(&my_dev.test_cdev, &test_fops);my_dev.test_cdev.owner = THIS_MODULE;result = cdev_add(&my_dev.test_cdev, my_dev.devno, 1);if(result < 0){P_DEBUG("cdev_add errno!\n");goto err1;}my_dev.asyn_class=class_create(THIS_MODULE,"asyn_class");if(IS_ERR(my_dev.asyn_class)){result=PTR_ERR(my_dev.asyn_class);goto err2;}device_create(my_dev.asyn_class,NULL,my_dev.devno,NULL,"asynchronous_notification");timer_init();P_DEBUG("%s successful\n",__FUNCTION__);return 0;err2:cdev_del(&my_dev.test_cdev);err1:unregister_chrdev_region(my_dev.devno, 1);err0:return result;}static void __exit test_exit(void){printk("%s\n",__FUNCTION__);my_dev.async_queue=NULL;del_timer(&my_dev.timer);device_destroy(my_dev.asyn_class,my_dev.devno);      class_destroy(my_dev.asyn_class);  cdev_del(&my_dev.test_cdev);unregister_chrdev_region(my_dev.devno, 1);}module_init(test_init);module_exit(test_exit);MODULE_LICENSE("GPL");

相应的APP为app.c

#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/select.h>#include <unistd.h>#include <signal.h>unsigned int flag;void sig_handler(int sig){printf("%s\n", __FUNCTION__);}int main(void){char buf[20];int fd;int f_flags;flag = 0;fd = open("/dev/asynchronous_notification", O_RDWR);if(fd < 0){perror("open");return -1;}signal(SIGIO, sig_handler);fcntl(fd, F_SETOWN, getpid());f_flags = fcntl(fd, F_GETFL);fcntl(fd, F_SETFL, FASYNC | f_flags);while(1){printf("waiting \n");sleep(4);}printf("finish\n");close(fd);return 0;}

把Makefile文件也附上

ifeq ($(KERNELRELEASE),)  KERNELDIR ?= /Android源码根路径/kernel/DBG_CROSS_COMPILE ?= /Android源码根路径/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-EXTRA_LIBS += -lpthread -staticCC=arm-linux-gccEXEC =  appOBJS =  app.oPWD :=$(shell pwd)  all: $(EXEC)  modules$(EXEC): $(OBJS)$(CC) $(LDFLAGS) -o $@ $(OBJS)  $(EXTRA_LIBS)modules:  $(MAKE) -C $(KERNELDIR) M=$(PWD) modules  modules_install:  $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install  clear:  rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.order  Module.symvers  *.elf *.elf2flt *.gdb *.o else       obj-m:= asynchronous_notification.o  endif  


0 0
原创粉丝点击