高级字符驱动程序操作之异步通知IO(实践篇)基于内核2.6.35-30

1. async.c 主要展示异步通知机制在驱动程序中的实现

#include <linux/module.h>
#include <linux/init.h>

#include <linux/fs.h>     /* everything... */
#include <linux/types.h>  /* size_t */
#include <linux/cdev.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h> /* copy user */
#include <linux/poll.h> /* POLL_IN */

#include <linux/sched.h>
#include <linux/slab.h>

MODULE_AUTHOR("victorsummer");
MODULE_LICENSE("Dual BSD/GPL");


static int async_major = 0;
struct fasync_struct *async_queue;
static char *buffer = NULL;

ssize_t async_read (struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
	if(buffer)
		copy_to_user(buf, buffer, count); 

	return count; 
}

ssize_t async_write (struct file *filp, const char __user *buf, size_t count,
		loff_t *pos)
{
	if(buffer)
		copy_from_user(buffer, buf, count);
	if(async_queue)
		kill_fasync(&async_queue, SIGIO, POLL_IN);
	return count;
}

static int async_fasync(int fd, struct file *filp, int mode)
{
	return fasync_helper(fd, filp, mode, &async_queue);
}

int async_release(struct inode *inode, struct file *filp)
{
	async_fasync(-1, filp, 0);
	return 0;
}

static int async_open(struct inode *inode, struct file *filp)
{
	return nonseekable_open(inode, filp);
}


struct file_operations async_fops = {
	.owner = THIS_MODULE,
	.read =  async_read,
	.write = async_write,
	.fasync = async_fasync,
	.release = async_release,
	.open = async_open,
};

int async_init(void)
{
	int result;
	dev_t dev = 0;
  
	struct cdev *async_cdev = cdev_alloc();

	if (async_major) {
		dev = MKDEV(async_major, 0);
		result = register_chrdev_region(dev, 1, "async");
	} else {
		result = alloc_chrdev_region(&dev, 0, 1, "async");
		async_major = MAJOR(dev);
	}
	if (result < 0) {
		return result;
	}

	if(!buffer)
		buffer = kmalloc(1024*sizeof(char), GFP_KERNEL);

	cdev_init(async_cdev, &async_fops);
	async_cdev->owner = THIS_MODULE;
	cdev_add(async_cdev, dev, 1);

	return 0;
}

void async_cleanup(void)
{
	dev_t devno;
	if(buffer)
	{
		kfree(buffer);
		buffer = NULL;
	}
	devno = MKDEV(async_major, 0);
	unregister_chrdev_region(devno, 1);
}

module_init(async_init);
module_exit(async_cleanup);
2. Makefile

KERNELDIR = /usr/src/linux-headers-2.6.35-30-generic
PWD := $(shell pwd)

obj-m := async.o 

modules:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
3. async_testr.c 异步读取程序

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>

int async_fd;
void sig_handler(int signo)
{
	int code;

    	if (signo==SIGIO)
    	{
		char *buf = malloc(30*sizeof(char));

		if ((code=read(async_fd, buf, 24)) == -1) 
			printf("read err! code=%d /n", code);

		else   
			printf("read ok! code=%d /n", code);
		printf("Read %s from async module /n", buf);
		free(buf);
    	}
    	return;
}

int main()
{
    	struct sigaction action;

    	memset(&action, 0, sizeof(action));
    	action.sa_handler = sig_handler;
    	action.sa_flags = 0;	

	sigaction(SIGIO, &action, NULL);

	async_fd = open("/dev/async", O_RDONLY);
	fcntl(async_fd, F_SETOWN, getpid());
	fcntl(async_fd, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | FASYNC);

	while(1)
	{
        	sleep(86400);
	}

	close(async_fd);
	exit(0);
}
4. async_testw.c 写入程序

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>

int main()
{
	char *write_buffer = "Hello, Character driver!";

	int async_fd;

	int code;

	

	async_fd = open("/dev/async",O_WRONLY );



	while(*write_buffer != '\0')
	{  
		code = write(async_fd , write_buffer , 24);
		printf("Write %d bytes to async_fd/n", code);
		write_buffer += code;
	}

	close(async_fd);

  	exit(0);
}
5. Makefile

all : async_testw.o async_testr.o
		gcc -o async_testw.o async_testw.c
		gcc -o async_testr.o async_testr.c

6. 开始测试

 

装载驱动程序

sudo insmod ./async.ko

查看主设备号,假设为249

cat /proc/devices

建立设备节点

sudo mknod /dev/async c 249 0

更改权限

sudo chgrp staff /dev/async

sudo chmod 664 /dev/async

 

在终端1中打开异步读取程序,程序开始sleep

sudo ./async_testr.o

在终端2中打开写入程序

sudo ./async_testw.o

 

结果:

终端2打印:

Write 24 bytes to async_fd

终端1打印:

read ok! code=24
Read Hello, Character driver! from async module





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值