Chinaunix首页 | 论坛 | 博客
  • 博客访问: 289728
  • 博文数量: 186
  • 博客积分: 1531
  • 博客等级: 上尉
  • 技术积分: 1275
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-06 16:56
文章分类

全部博文(186)

文章存档

2013年(2)

2012年(184)

分类:

2012-11-09 10:15:00

原文地址:linux同步机制应用 作者:linux_hope

驱动模块
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define NAME "sync_test"

static int chardev_var = 0;
static int chardev_count = 0;
static struct semaphore sem;
static spinlock_t spin;
static struct cdev boardid_cdev;
static struct class *boardid_class;
static struct device *boardid_device;
static int device_major = 0;
static ssize_t boardid_read(struct file *file, char __user *buf, size_t len, loff_t *offset)
{
 ssize_t ret;
 if(down_interruptible(&sem)){
  return -ERESTARTSYS;
 }
 ret = copy_to_user(buf, &chardev_var, len);  
 if(ret)
 {
  up(&sem);
  printk("read error\n");
  return -EFAULT;
 }
 up(&sem);
 return sizeof(int);
}
static ssize_t boardid_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos)
{
 ssize_t ret;
 if(down_interruptible(&sem)){
  return -ERESTARTSYS;
 }
 ret = copy_from_user(&chardev_var, buf, len);  
 if(ret)
 {
  up(&sem);
  printk("read error\n");
  return -EFAULT;
 }
 up(&sem);
 return sizeof(int);
}
static int boardid_open(struct inode *inode, struct file *file)

 spin_lock(&spin);
 printk("get spinlock\n");
 if(chardev_count){
  spin_unlock(&spin);
  return -EBUSY;
 }
 chardev_count++;
 spin_unlock(&spin);
 return 0;
}
static int boardid_release(struct inode *inode, struct file *file)
{
 chardev_count--;
 return 0;
}
static const struct file_operations boardid_fops = {
 .owner  = THIS_MODULE,
 .open  = boardid_open,
 .read  = boardid_read,
 .write   = boardid_write,
 .release = boardid_release
};
static int __init boardid_init(void)
{
 dev_t dev_id;
 int retval;
 if (device_major) {
  dev_id = MKDEV(device_major, 0);
  retval = register_chrdev_region(dev_id, 1, NAME);
 } else {
  retval = alloc_chrdev_region(&dev_id, 0, 1, NAME);
  device_major = MAJOR(dev_id);
 }
 if(retval){
  printk("boardid chrdev region failed\n"); 
  retval = -EBUSY;
  goto err_chrdev_region;
 }
 cdev_init(&boardid_cdev, &boardid_fops);
 retval = cdev_add(&boardid_cdev, dev_id, 1);
 if (retval) {
  printk("boardid cdev add failed\n");
  retval = -EBUSY;
  goto err_cdev_add;
 }
        boardid_class = class_create(THIS_MODULE, NAME);
        if (IS_ERR(boardid_class)) {
                printk("%s: class_create failed\n", NAME);
                retval = PTR_ERR(boardid_class);
                goto err_class_create;
        }
        boardid_device = device_create(boardid_class, NULL, dev_id,  NULL, "%s", NAME);
        if (IS_ERR(boardid_device)) {
                printk("%s: class_device_create failed\n", NAME);
                retval = PTR_ERR(boardid_device);
                goto err_device_create;
        }
 printk("cdev:board_version:%d\n",chardev_var);
 init_MUTEX(&sem);
 spin_lock_init(&spin); 
 return 0;
err_device_create:
 class_destroy(boardid_class);
err_class_create:
 cdev_del(&boardid_cdev);
err_cdev_add:
 unregister_chrdev_region(dev_id, 1);
err_chrdev_region:
 return retval;
}
static void __exit boardid_exit(void)
{
 dev_t dev_id = MKDEV(device_major, 0);
 device_destroy(boardid_class, dev_id);
 class_destroy(boardid_class);
 cdev_del(&boardid_cdev);
 unregister_chrdev_region(dev_id, 1);
}
module_init(boardid_init);
module_exit(boardid_exit);

MODULE_DESCRIPTION("board_version Driver");
MODULE_LICENSE("GPL");
 
应用测试程序:
 
#include
#include
int main()
{
        int fd;
        int wrbuf = 72;
        int rdbuf;
        int ret = 0;
        fd = open("/dev/sync_test", O_RDWR);
        if (fd < 0){
                printf("open /dev/sync_test devices failed!\n");
        }else{
                printf("sync_test driver open successfully!\n");
        }
        ret=write(fd, &wrbuf, sizeof(int));
        if(ret == sizeof(int)){
                printf("write ok!\n");
        }else{
                printf("write failed!\n");
  close(fd);
  return 0;
        }
 lseek(fd, 0, SEEK_SET);
 ret = read(fd, &rdbuf, sizeof(int));
        if(ret == sizeof(int)){
                printf("read ok!\n");
  printf("rdbuf:%d\n",rdbuf);
        }else{
                printf("read failed!\n");
        }
 
        close(fd);
}
 
注:很好的参考资料---》
阅读(343) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~