【Linux设备驱动程序(第三版)】----完成量completion
complete.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>//file_operations, file
#include <linux/completion.h>
#include <asm/uaccess.h>//copy_to_user & copy_from_user
MODULE_LICENSE("Dual BSD/GPL");
#define MEMSIZE 100
int complete_major = 250;
DECLARE_COMPLETION(comp);
unsigned char s[MEMSIZE];
ssize_t complete_read(struct file *filp, char __user *buf, size_t size, loff_t *pos)
{
unsigned long p = *pos;
unsigned int count = size;
int ret = 0;
if(p >= MEMSIZE)
return 0;
if(count > MEMSIZE - p)
count = MEMSIZE -p;
wait_for_completion(&comp);
if(copy_to_user(buf, (void*)(s + p), count)){
return -EFAULT;
}
*pos += count;
ret = count;
return ret;
}
ssize_t complete_write(struct file *filp, char __user *buf, size_t size, loff_t *pos)
{
unsigned long p = *pos;
unsigned int count = size;
int ret = 0;
if(p >= MEMSIZE)
return 0;
if(count > MEMSIZE - p)
count = MEMSIZE -p;
if(copy_from_user(s + p, buf, count)){
return -EFAULT;
}
*pos += count;
ret = count;
complete(&comp);
return ret;
}
struct file_operations complete_fops = {
.owner = THIS_MODULE,
.read = complete_read,
.write = complete_write,
};
int complete_init(void)
{
int result;
result = register_chrdev(complete_major, "complete", &complete_fops);
if(result < 0)
return result;
return 0;
}
void complete_exit(void)
{
unregister_chrdev(complete_major, "complete");
}
module_init(complete_init);
module_exit(complete_exit);
Makefie
obj-m:= complete.o
modules-objs:= complete.o
KDIR:= /usr/src/linux-headers-2.6.31-14-generic/
PWD:= $(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.ko *.mod.c *.mod.o *.o *.markers *.symvers *.order
创建设备节点
mknod /dev/complete c 250 0
装载
insmod complete.ko
测试
cat /dev/complete
此时,读线程会进入休眠。
打开另一个终端输入:
echo "Test" > /dev/complete
此时,读线程运行,并输出结果:“Test”
卸载
rmmod complete