驱动代码如下:
scull.c
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/gfp.h>
#include <linux/poll.h>
#include <asm/uaccess.h>
#define SCULL_MAJOR 252
#define SCULL_NAME "scull"
#define MAX_DATA 0x10
static int scull_major = SCULL_MAJOR;
struct scull_dev {
struct cdev cdev;
unsigned char data[MAX_DATA];
struct semaphore sem;
unsigned int current_len;
wait_queue_head_t r_wait;
wait_queue_head_t w_wait;
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("BG2BKK");
struct scull_dev *scull_devp;
int scull_open(struct inode *inode, struct file *filp)
{
struct scull_dev *dev = container_of(inode->i_cdev, struct scull_dev, cdev);
filp->private_data = dev;
printk(KERN_ALERT "open the scull device\n");
return 0;
}
int scull_release(struct inode *inode, struct file *filp)
{
printk(KERN_ALERT "close the scull device\n");
return 0;
}
ssize_t scull_read(struct file *filp, char __user *buf, size_t count, loff_t *f_ops)
{
struct scull_dev *dev = filp->private_data;
int ret = 0;
DECLARE_WAITQUEUE(wait, current);
down(&dev->sem);
add_wait_queue(&dev->r_wait, &wait);
while(dev->current_len == 0)
{
if(filp->f_flags & O_NONBLOCK)
{
ret = -EAGAIN;
goto out;
}
__set_current_state(TASK_INTERRUPTIBLE);
up(&de