编写了一个虚拟的驱动,实现的功能是在读设备时阻塞,直到有数据写入设备,然后才能读出写入的数据。
其中有信号量的操作与阻塞非阻塞IO的操作,
最后写了一个应用程序进行验证
驱动如下:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/device.h>
/*for spinlock and semaphore*/
#include <asm/spinlock.h>
#include <linux/spinlock.h>
#include <linux/semaphore.h>
/*for task management*/
#include <linux/wait.h>
#include <linux/types.h>
#include <linux/sched.h>
#define DEVICE_NAME "pcio"
#define DRIVER_NAME "mypcio"//加载驱动之后会在/dev/目录下发现mypcio,应用程序可以使用
#define PCIO_MAJOR 0 //预设的pcio的主设备号
static int pcio_major = PCIO_MAJOR;
static int pcioOpenCount=0;
static int flag=0;
static int global_var = 0;
struct class *pcio_class;
static struct device *pcioDevice=NULL;
static wait_queue_head_t wqueue;
struct pcio_dev
{
struct cdev cdev;//cdev结构体
//信号量
struct semaphore sem;
//等待队列头
//struct wait_queue_head_t* wqueue;
//unsigned char mem[MYKEY_SIZE];//全局内存
};
struct pcio_dev *pcio_devp;//设备结构体指针
//打开函数
static int pcio_open(struct inode *inode, struct file *file)
{
pcioOpenCount++;
return 0;
}
//关闭函数
static int pcio_close(struct inode *inode, struct file *file)
{
pcioOpenCount--;
return 0;
}
//读函数
static ssize_t pcio_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
//等待事件
if(wait_event_interruptible(wqueue,flag!=0))
{
return -ERESTARTSYS;
}
//获取信号量
if(down_interruptible(&pcio_devp->sem))