首页 > 代码库 > 04clock_06semqphore

04clock_06semqphore

  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  15 #include <linux/spinlock.h>  //自旋锁 16 #include <linux/rwlock.h>  //读写自旋锁 17 #include <linux/semaphore.h> 18  19 /* 20 该设备只能同时被一个进程打开 21 */ 22  23  24 #define   DEVNAME  "my_led" 25 #define  MEMSIZE  100 26  27  28 int test = 1; 29  30 struct ldm_info 31 { 32     struct  miscdevice dev;       //设备节点 33     struct  file_operations  ops;  //文件操作 34     unsigned char mem[MEMSIZE] ;  //数组, 内核的空间 35     //rwlock_t  myrwlock; 36     struct semaphore sema; 37 }; 38  39 //struct ldm_info  ldm; 40 struct ldm_info  ldm;  //结构体的指针,分配空间 41  42 static  int ldm_open(struct inode * inode, struct file * file) 43 { 44     //printk("kernel: ldm_open\n"); 45     test++; 46     //如何传递私有变量 47     //Linux任何一个文件,都会有一个file指针, 48     //有一个成员  private_data  void *   通用指针 49     file->private_data =    http://www.mamicode.com/(void *)&test; 50  51     return 0; 52 } 53  54 /* 55 copy_to_user 56 copy_form_user 57 */ 58  59 static  ssize_t ldm_write(struct file * file, const char __user * buf, size_t size, loff_t *   offt) 60 { 61     int i =0; 62  63     int val = *(int *)file->private_data; 64  65     //write_lock(&ldm.myrwlock); 66     down(&ldm.sema); 67     for(;i < size; i++) { 68         //每拷贝一个字节,睡眠1s 69         copy_from_user(ldm.mem + i, buf + i, 1); 70         printk("write:%c  val = %d\n",  ldm.mem[i], val); 71         ssleep(1); //延迟1s 72     } 73     //write_unlock(&ldm.myrwlock); 74     up(&ldm.sema); 75  76  77     return 0; 78 } 79  80  81 ssize_t ldm_read(struct file * file, char __user *  buf, size_t size, loff_t * offt) 82 { 83     //每隔一秒拷贝一个字节到用户层 84     int i =0; 85  86     int val = *(int *)file->private_data; 87  88     //read_lock(&ldm.myrwlock); 89     down(&ldm.sema); 90     for(;i < size; i++) { 91         //每拷贝一个字节,睡眠1s 92         copy_to_user(buf + i, ldm.mem + i, 1); 93         printk("read:%c, val = %d\n",  ldm.mem[i], val); 94         ssleep(1); //延迟1s 95     } 96     //read_unlock(&ldm.myrwlock); 97     up(&ldm.sema); 98     return 0; 99 }100 101 int ldm_release(struct inode * inode, struct file *file)102 {103     //printk("kernel: close\n");104     test--;105     return 0;106 }107 108 static int test_init(void)109 {110     int ret = 0;111 112     printk("%s:%s:%d   init\n", __FILE__, __FUNCTION__, __LINE__);113 114 115     ldm.dev.minor  = MISC_DYNAMIC_MINOR;  //系统自动分配次设备116     ldm.dev.name = DEVNAME;//该名称将决定节点名称, 成功注册 linux 系统中117     ldm.dev.fops = &ldm.ops;  //关联文件操作118     ldm.ops.open = ldm_open;119     ldm.ops.write = ldm_write;120     ldm.ops.read = ldm_read;121     ldm.ops.release = ldm_release;122 123 124     ret = misc_register(&ldm.dev);125 126     //rwlock_init(&ldm.myrwlock);127     sema_init(&ldm.sema, 1); 128 129     if(ret < 0) {130         printk("misc_register  failed\n");131         goto  err_misc_register;132     }133 134     return 0;135 err_misc_register:136     return ret;137 138 }139 140 //卸载141 static void test_exit(void)142 {143     printk("%s:%s:%d   init\n", __FILE__, __FUNCTION__, __LINE__);144 145 146     //注销misc 147     misc_deregister(&ldm.dev);148     //释放映射的虚拟地址149 150 }151 152 module_init(test_init);153 module_exit(test_exit);154 155 156 MODULE_LICENSE("GPL");  //加入GPL许可

 

04clock_06semqphore