注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

瘋人院

lunatic asylum

 
 
 

日志

 
 

阻塞实例  

2010-10-07 21:54:15|  分类: 操作系統 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
/**************************************************************************************/
/*文件:chardev_block.c */
/*简介:阻塞。           */
/*************************************************************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/wait.h>
#include <asm/semaphore.h> 
MODULE_LICENSE("GPL");

#define MAJOR_NUM 254

static ssize_t chardev_read(struct file *, char *, size_t, loff_t*);
static ssize_t chardev_write(struct file *, const char *, size_t, loff_t*);

struct file_operations chardev_fops =
{
 read: chardev_read, write: chardev_write,
};

static int chardev_var = 0;
static struct semaphore sem;
static wait_queue_head_t outq;
static int flag = 0;

static int __init chardev_init(void)
{
 int ret;
 /*注册设备驱动*/
 ret = register_chrdev(MAJOR_NUM, "chardev", &chardev_fops);
 if (ret)
 {
  printk("chardev register failure");
 }
 else
 {
  printk("chardev register success");
  init_MUTEX(&sem);
  init_waitqueue_head(&outq);
 }
 return ret;
}

static void __exit chardev_exit(void)
{
 int ret;
 /*注销设备驱动*/
 ret = unregister_chrdev(MAJOR_NUM, "chardev");
 if (ret)
 {
  printk("chardev unregister failure");
 }
 else
 {
  printk("chardev unregister success");
 }
}

static ssize_t chardev_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
 /*等待数据可获得*/
 if (wait_event_interruptible(outq, flag != 0))
 {
  return - ERESTARTSYS;
 }
 /*获得信号量*/
 if (down_interruptible(&sem))
 {
  return - ERESTARTSYS;
 }

 flag = 0;
 if (copy_to_user(buf, &chardev_var, sizeof(int)))
 {
 /*释放信号量*/
  up(&sem);
  return - EFAULT;
 }
 /*释放信号量*/
 up(&sem);
 return sizeof(int);
}

static ssize_t chardev_write(struct file *filp, const char *buf, size_t len,loff_t *off)
{
 /*获得信号量*/
 if (down_interruptible(&sem))
 {
  return - ERESTARTSYS;
 }
 if (copy_from_user(&chardev_var, buf, sizeof(int)))
 {
  up(&sem);
  return - EFAULT;
 }
 /*释放信号量*/
 up(&sem);
 flag = 1;
 /*通知数据可获得*/
 wake_up_interruptible(&outq);
 return sizeof(int);
}

module_init(chardev_init);
module_exit(chardev_exit); 
  评论这张
 
阅读(250)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017