linux 2.6内核编程-设备驱动中的并发控制

<script type="text/javascript"> document.body.oncopy = function() { if (window.clipboardData) { setTimeout(function() { var text = clipboardData.getData("text"); if (text && text.length > 300) { text = text + "/r/n/n本文来自CSDN博客,转载请标明出处:" + location.href; clipboardData.setData("text", text); } }, 100); } } </script>

/**************************************************************

 test bingfa program

**************************************************************/

 

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#include <string.h>

int main()
{
    int fd,nwrite,nread;
    char *buf="hello laq/n";
    char read_buf[20]={0};
        printf("11111111111aaaaaaaaaaaaaaaaaaaaaaaaaaaaa/n");
    fd=open("/dev/bingfa_5",O_RDWR);
    if(fd<0)
    {   
        perror("Open");
        exit(1);
    }
    else
        printf("Open success/n");
        nwrite=write(fd,buf,strlen(buf));
    if(nwrite<0)
    {
        perror("write");
        exit(1);
    }
        printf("/n/n/nnwrite=%d/n",nwrite);
    nread=read(fd,read_buf,20);
    if(nwrite<0)
    {
        perror("read");
        exit(1);
    }
    else
        printf("read is %s/n",read_buf);
    //close(fd);
    exit(0);
}

 

 

<script type="text/javascript"> document.body.oncopy = function() { if (window.clipboardData) { setTimeout(function() { var text = clipboardData.getData("text"); if (text && text.length > 300) { text = text + "/r/n/n本文来自CSDN博客,转载请标明出处:" + location.href; clipboardData.setData("text", text); } }, 100); } } </script>

/**************************************************************

 bingfa program

**************************************************************/

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fd.h>
#include <linux/kernel.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>

#include <linux/errno.h>
#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/console.h>
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/jiffies.h>
#include <linux/smp_lock.h>

#include <linux/parport.h>
#undef LP_STATS
#include <linux/lp.h>

#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/system.h>
//#include <sys/stat.h>

MODULE_LICENSE("GPL");

#define REG_NAME "bingfa_5"


static int global_var=0;
static int globalvar_count=0;
static struct semaphore sem;
static spinlock_t spin=SPIN_LOCK_UNLOCKED;

unsigned int fs_major=0;

static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*);
static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);

static int globalvar_open(struct inode *inode,struct file *filp);
static int globalvar_release(struct inode *inode,struct file *filp);

struct file_operations globalvar_fops=
{
 .read=globalvar_read,
 .write=globalvar_write,
 .open=globalvar_open,
 .release=globalvar_release,
};
//static int global_var = 0;
static struct semaphore sem;

static int __init globalvar_init(void)
{
  int ret;
  ret = register_chrdev(0, REG_NAME, &globalvar_fops);
  printk("++++++++++++++++ret=%d++++++++++++++++++/n",ret);
  if(ret<0)
  {
    printk("/n/n/nglobalvar register failure %s   %s/n/n/n",__TIME__,__DATE__);
  }
  else
  {
    printk("/n/n/nglobalvar register success %d %s/n/n/n",__LINE__,__TIME__);
    fs_major=ret;
    //init_MUTEX(&sem);
    //该函数用于初始化一个互斥锁,即它把信号量sem的值设置为1,
    //等同于sema_init (struct semaphore *sem, 1);
    printk("/n/n/nrrrrrrrrrrrrrrrrrrinit sem/n/n/n");
    sema_init(&sem,1);
  }
  return ret;
}

static void __exit globalvar_exit(void)
{
  unregister_chrdev(fs_major,REG_NAME);
  printk("/n/n/nglobalvar unregister success %s/n/n/n",__TIME__);
}

static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
  //获得信号量
  if(down_interruptible(&sem))
  {
   return - ERESTARTSYS;
  }
  //将global_var从内核空间复制到用户空间
  if (copy_to_user(buf, &global_var, sizeof(int)))
  {
   up(&sem);
   printk("/n/n释放信号量 in %s/n/n/n",__TIME__);
   return - EFAULT;
  }
  //释放信号量
  up(&sem);
  printk("/n/n释放信号量 out %d/n/n/n",__LINE__);
  return sizeof(int);
}

ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off)
{
 //获得信号量

 printk("/n/n/nwwwwwwwwwwwwwwwwwwwwwwwww %s/n/n/n",__FILE__);
 if (down_interruptible(&sem))
 {
   return - ERESTARTSYS;
 }
 //将用户空间的数据复制到内核空间的global_var
 if (copy_from_user(&global_var, buf, sizeof(int)))
 {
   up(&sem);
   return - EFAULT;
 }

  //释放信号量
  up(&sem);
  return sizeof(int);
}

static int globalvar_open(struct inode *inode, struct file *filp)
{
  //获得自选锁
  printk("/n/n/n获得自选锁 open %d/n/n/n",__LINE__);
  spin_lock(&spin);
  //临界资源访问
  if (globalvar_count)
 {
   spin_unlock(&spin);
   return -EBUSY;
 }
 globalvar_count++;
 //释放自选锁
 spin_unlock(&spin);
 return 0;
}

static int globalvar_release(struct inode *inode, struct file *filp)
{
  printk("/n/n/n释放 release %d/n/n/n",__LINE__);
  globalvar_count--;
  return 0;
}


module_init(globalvar_init);
module_exit(globalvar_exit);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值