zoukankan      html  css  js  c++  java
  • 04lock_03rwlock

    #include <linux/module.h>  //MODULE_LICENSE("GPL"); 
    #include <linux/init.h>   //module_init  module_exit
    #include <linux/kernel.h>  //printk
    #include <linux/io.h>    //ioremap  iounremap
    #include <linux/ioport.h>  //request_mem_region
    
    
    #include <linux/miscdevice.h>
    #include <linux/fs.h>   //file_operations  结构体的定义
    #include <linux/slab.h>  //kmalloc
    #include <linux/delay.h>
    
    #include <asm/uaccess.h>    //copy_to_user  copy_form_user
    
    #include <linux/spinlock.h>  //自旋锁
    #include <linux/rwlock.h>  //读写自旋锁
    
    /*
    该设备只能同时被一个进程打开
    */
    
    
    #define   DEVNAME  "my_led"
    #define  MEMSIZE  100
    
    
    int test = 1;
    
    struct ldm_info
    {
        struct  miscdevice dev;       //设备节点
        struct  file_operations  ops;  //文件操作
        unsigned char mem[MEMSIZE] ;  //数组, 内核的空间
        rwlock_t  myrwlock;
    };
    
    //struct ldm_info  ldm;
    struct ldm_info  ldm;  //结构体的指针,分配空间
    
    static  int ldm_open(struct inode * inode, struct file * file)
    {
        //printk("kernel: ldm_open
    ");
        test++;
        //如何传递私有变量
        //Linux任何一个文件,都会有一个file指针,
        //有一个成员  private_data  void *   通用指针
        file->private_data =    (void *)&test;
    
        return 0;
    }
    
    /*
    copy_to_user
    copy_form_user
    */
    
    static  ssize_t ldm_write(struct file * file, const char __user * buf, size_t size, loff_t *   offt)
    {
        int i =0;
    
        int val = *(int *)file->private_data;
    
        write_lock(&ldm.myrwlock);
        for(;i < size; i++) {
            //每拷贝一个字节,睡眠1s
            copy_from_user(ldm.mem + i, buf + i, 1);
            printk("write:%c  val = %d
    ",  ldm.mem[i], val);
            ssleep(1); //延迟1s
        }
        write_unlock(&ldm.myrwlock);
    
    
        return 0;
    }
    
    
    ssize_t ldm_read(struct file * file, char __user *  buf, size_t size, loff_t * offt)
    {
        //每隔一秒拷贝一个字节到用户层
        int i =0;
    
        int val = *(int *)file->private_data;
    
        read_lock(&ldm.myrwlock);
        for(;i < size; i++) {
            //每拷贝一个字节,睡眠1s
            copy_to_user(buf + i, ldm.mem + i, 1);
            printk("read:%c, val = %d
    ",  ldm.mem[i], val);
            ssleep(1); //延迟1s
        }
        read_unlock(&ldm.myrwlock);
        return 0;
    }
    
    int ldm_release(struct inode * inode, struct file *file)
    {
        //printk("kernel: close
    ");
        test--;
        return 0;
    }
    
    static int test_init(void)
    {
        int ret = 0;
    
        printk("%s:%s:%d   init
    ", __FILE__, __FUNCTION__, __LINE__);
    
    
        ldm.dev.minor  = MISC_DYNAMIC_MINOR;  //系统自动分配次设备
        ldm.dev.name = DEVNAME;//该名称将决定节点名称, 成功注册 linux 系统中
        ldm.dev.fops = &ldm.ops;  //关联文件操作
        ldm.ops.open = ldm_open;
        ldm.ops.write = ldm_write;
        ldm.ops.read = ldm_read;
        ldm.ops.release = ldm_release;
    
    
        ret = misc_register(&ldm.dev);
    
        rwlock_init(&ldm.myrwlock);
    
        if(ret < 0) {
            printk("misc_register  failed
    ");
            goto  err_misc_register;
        }
    
        return 0;
    err_misc_register:
        return ret;
    
    }
    
    //卸载
    static void test_exit(void)
    {
        printk("%s:%s:%d   init
    ", __FILE__, __FUNCTION__, __LINE__);
    
    
        //注销misc 
        misc_deregister(&ldm.dev);
        //释放映射的虚拟地址
    
    }
    
    module_init(test_init);
    module_exit(test_exit);
    
    
    MODULE_LICENSE("GPL");  //加入GPL许可
  • 相关阅读:
    2020牛客暑期多校训练营(第八场)解题报告
    2020牛客暑期多校训练营(第七场)解题报告
    2020 Multi-University Training Contest 3 解题报告
    2020牛客暑期多校训练营(第五场)解题报告
    2020 Multi-University Training Contest 2 解题报告
    Android应用开发基础 学习笔记(一)
    Java基础:JUC包学习笔记
    Java基础:枚举学习笔记
    Java基础:反射学习笔记
    Java基础:Stream流学习笔记
  • 原文地址:https://www.cnblogs.com/baoshulin/p/6416296.html
Copyright © 2011-2022 走看看