您的位置:首页 > 其它

内核异步通知的例子

2016-07-12 15:38 295 查看
       内核异步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 100

struct 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 -static
CC=arm-linux-gcc
EXEC = app
OBJS = app.o
PWD :=$(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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: