1. complete.c 只是一个简单的字符驱动,但是我加进去了completion来同步读写操作
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h> /* everything... */
#include <linux/types.h> /* size_t */
#include <linux/completion.h>
#include <linux/cdev.h>
MODULE_AUTHOR("victorsummer");
MODULE_LICENSE("Dual BSD/GPL");
static int complete_major = 0;
DECLARE_COMPLETION(comp);
ssize_t complete_read (struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
wait_for_completion(&comp);
return 0;
}
ssize_t complete_write (struct file *filp, const char __user *buf, size_t count,
loff_t *pos)
{
complete(&comp);
return count;
}
struct file_operations complete_fops = {
.owner = THIS_MODULE,
.read = complete_read,
.write = complete_write,
};
int complete_init(void)
{
int result;
dev_t dev = 0;
struct cdev *complete_cdev = cdev_alloc();
if (complete_major) {
dev = MKDEV(complete_major, 0);
result = register_chrdev_region(dev, 1, "completion");
} else {
result = alloc_chrdev_region(&dev, 0, 1, "completion");
complete_major = MAJOR(dev);
}
if (result < 0) {
return result;
}
cdev_init(complete_cdev, &complete_fops);
complete_cdev->owner = THIS_MODULE;
cdev_add(complete_cdev, dev, 1);
return 0;
}
void complete_cleanup(void)
{
dev_t devno = MKDEV(complete_major, 0);
unregister_chrdev_region(devno, 1);
}
module_init(complete_init);
module_exit(complete_cleanup);
2. Makefile
ifneq ($(KERNELRELEASE),)
obj-m := complete.o
else
KERNELDIR ?= /usr/src/linux-headers-2.6.31-14-generic
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
3. completion_testr.c 调用read函数
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
int completion_fd;
int code;
completion_fd = open("/dev/completion",O_RDONLY );
if ((code=read(completion_fd, NULL, 0)) < 0)
printf("read err! code=%d /n",code);
else
printf("read ok! code=%d /n",code);
close(completion_fd);
exit(0);
}
4. completion_testw.c 调用write函数
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
int completion_fd;
int code;
completion_fd = open("/dev/completion",O_WRONLY );
if ((code=write(completion_fd, NULL, 0)) < 0 )
printf("write error! code=%d /n",code);
else
printf("write ok! code=%d /n",code);
close(completion_fd);
exit(0);
}
5. Makefile 使用make all编译读写程序
all : completion_testw.o completion_testr.o
gcc -o completion_testw.o completion_testw.c
gcc -o completion_testr.o completion_testr.c
6. 开始测试啦
装载completion驱动
sudo insmod complete.ko
查看主设备号,假设为251
cat /proc/devices
建立设备节点
sudo mknod /dev/completion c 251 0
更改权限
sudo chgrp staff /dev/completion
sudo chmod 664 /dev/completion
实验1: 先运行completion_testw,再运行completion_testr
结果: write ok! code=0
read ok! code=0
实验2: 先运行两个completion_testr,再运行两个completion_testw
结果: completion_testr 1 阻塞
completion_testr 2 阻塞
completion_testw 1 打印 write ok! code=0
同时 completion_testr 1 打印 read ok! code=0
completion_testw 2 打印 write ok! code=0
同时 completion_testr 2 打印 read ok! code=0
转自:http://blog.csdn.net/victorsummer/article/details/6094637