zoukankan      html  css  js  c++  java
  • 04lock_02atomic

      1 #include <linux/module.h>  //MODULE_LICENSE("GPL"); 
      2 #include <linux/init.h>   //module_init  module_exit
      3 #include <linux/kernel.h>  //printk
      4 #include <linux/io.h>    //ioremap  iounremap
      5 #include <linux/ioport.h>  //request_mem_region
      6 
      7 
      8 #include <linux/miscdevice.h>
      9 #include <linux/fs.h>   //file_operations  结构体的定义
     10 #include <linux/slab.h>  //kmalloc
     11 #include <linux/delay.h>
     12 
     13 #include <asm/uaccess.h>    //copy_to_user  copy_form_user
     14 #include <asm/atomic.h>  
     15 
     16 /*
     17 该设备只能同时被一个进程打开
     18 */
     19 
     20 
     21 #define   DEVNAME  "my_led"
     22 #define  MEMSIZE  100
     23 
     24 struct ldm_info
     25 {
     26     struct  miscdevice dev;       //设备节点
     27     struct  file_operations  ops;  //文件操作
     28     unsigned char mem[MEMSIZE] ;  //数组, 内核的空间
     29     atomic_t   atomic; //原子变量,用于防止多个进程同时打开
     30 };
     31 
     32 //struct ldm_info  ldm;
     33 struct ldm_info  ldm;  //结构体的指针,分配空间
     34 
     35 static  int ldm_open(struct inode * inode, struct file * file)
     36 {
     37     printk("kernel: ldm_open
    ");
     38     //先自减  test
     39     if(!atomic_dec_and_test(&ldm.atomic)) {
     40         atomic_inc(&ldm.atomic);
     41         return -1;
     42     }
     43 
     44     return 0;
     45 }
     46 
     47 /*
     48 copy_to_user
     49 copy_form_user
     50 */
     51 
     52 static  ssize_t ldm_write(struct file * file, const char __user * buf, size_t size, loff_t *   offt)
     53 {
     54     int i =0;
     55     for(;i < size; i++) {
     56         //每拷贝一个字节,睡眠1s
     57         copy_from_user(ldm.mem + i, buf + i, 1);
     58         printk("write:%c
    ",  ldm.mem[i]);
     59         ssleep(1); //延迟1s
     60     }
     61 
     62     return 0;
     63 }
     64 
     65 
     66 ssize_t ldm_read(struct file * file, char __user *  buf, size_t size, loff_t * offt)
     67 {
     68     //每隔一秒拷贝一个字节到用户层
     69     int i =0;
     70     for(;i < size; i++) {
     71         //每拷贝一个字节,睡眠1s
     72         copy_to_user(buf + i, ldm.mem + i, 1);
     73         printk("read:%c
    ",  ldm.mem[i]);
     74         ssleep(1); //延迟1s
     75     }
     76 
     77     return 0;
     78 }
     79 
     80 int ldm_release(struct inode * inode, struct file *file)
     81 {
     82     printk("kernel: close
    ");
     83     atomic_inc(&ldm.atomic);  //+1
     84     return 0;
     85 }
     86 
     87 static int test_init(void)
     88 {
     89     int ret = 0;
     90 
     91     printk("%s:%s:%d   init
    ", __FILE__, __FUNCTION__, __LINE__);
     92 
     93 
     94     ldm.dev.minor  = MISC_DYNAMIC_MINOR;  //系统自动分配次设备
     95     ldm.dev.name = DEVNAME;//该名称将决定节点名称, 成功注册 linux 系统中
     96     ldm.dev.fops = &ldm.ops;  //关联文件操作
     97     ldm.ops.open = ldm_open;
     98     ldm.ops.write = ldm_write;
     99     ldm.ops.read = ldm_read;
    100     ldm.ops.release = ldm_release;
    101 
    102 
    103     ret = misc_register(&ldm.dev);
    104 
    105     //原子变量 初始化为1
    106     atomic_set(&ldm.atomic, 1);
    107 
    108     if(ret < 0) {
    109         printk("misc_register  failed
    ");
    110         goto  err_misc_register;
    111     }
    112 
    113     return 0;
    114 err_misc_register:
    115     return ret;
    116 
    117 }
    118 
    119 //卸载
    120 static void test_exit(void)
    121 {
    122     printk("%s:%s:%d   init
    ", __FILE__, __FUNCTION__, __LINE__);
    123 
    124 
    125     //注销misc 
    126     misc_deregister(&ldm.dev);
    127     //释放映射的虚拟地址
    128 
    129 }
    130 
    131 module_init(test_init);
    132 module_exit(test_exit);
    133 
    134 
    135 MODULE_LICENSE("GPL");  //加入GPL许可
  • 相关阅读:
    Android OpenGL ES和OpenGL一起学(二)------理解Viewport(视口)和坐标系Android OpenGL ES篇(转帖)
    CSOM中如何取到managed metadata类型字段的类型信息
    "Value does not fall within the expected range" with managed metadata fields
    GLFW_KEY_KP_ADD和GLFW_KEY_KP_SUBTRACT
    OPENGL: WHY IS YOUR CODE PRODUCING A BLACK WINDOW?
    (转)真正的中国天气api接口xml,json(求加精) ...
    Mongo如何在多个字段中查询某个关键字?
    VS2010整合NUnit进行单元测试
    ASP.NET MVC3 学习心得------路由机制
    MVC3中 ViewBag、ViewData和TempData的使用和区别
  • 原文地址:https://www.cnblogs.com/baoshulin/p/6416282.html
Copyright © 2011-2022 走看看