04clock_01misc_device

  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 
 16 #define   DEVNAME  "my_led"
 17 #define  MEMSIZE  100
 18 
 19 struct ldm_info
 20 {
 21     struct  miscdevice dev;       //设备节点
 22     struct  file_operations  ops;  //文件操作
 23     unsigned char mem[MEMSIZE] ;  //数组, 内核的空间
 24 };
 25 
 26 //struct ldm_info  ldm;
 27 struct ldm_info  ldm;  //结构体的指针,分配空间
 28 
 29 static  int ldm_open(struct inode * inode, struct file * file)
 30 {
 31     printk("kernel: ldm_open
");
 32     return 0;
 33 }
 34 
 35 /*
 36 copy_to_user
 37 copy_form_user
 38 */
 39 
 40 static  ssize_t ldm_write(struct file * file, const char __user * buf, size_t size, loff_t *   offt)
 41 {
 42     int i =0;
 43     for(;i < size; i++) {
 44         //每拷贝一个字节,睡眠1s
 45         copy_from_user(ldm.mem + i, buf + i, 1);
 46         printk("write:%c
",  ldm.mem[i]);
 47         ssleep(1); //延迟1s
 48     }
 49 
 50     return 0;
 51 }
 52 
 53 
 54 ssize_t ldm_read(struct file * file, char __user *  buf, size_t size, loff_t * offt)
 55 {
 56     //每隔一秒拷贝一个字节到用户层
 57     int i =0;
 58     for(;i < size; i++) {
 59         //每拷贝一个字节,睡眠1s
 60         copy_to_user(buf + i, ldm.mem + i, 1);
 61         printk("read:%c
",  ldm.mem[i]);
 62         ssleep(1); //延迟1s
 63     }
 64 
 65     return 0;
 66 }
 67 
 68 int ldm_release(struct inode * inode, struct file *file)
 69 {
 70     printk("kernel: close
");
 71     return 0;
 72 }
 73 
 74 static int test_init(void)
 75 {
 76     int ret = 0;
 77 
 78     printk("%s:%s:%d   init
", __FILE__, __FUNCTION__, __LINE__);
 79 
 80 
 81     ldm.dev.minor  = MISC_DYNAMIC_MINOR;  //系统自动分配次设备
 82     ldm.dev.name = DEVNAME;//该名称将决定节点名称, 成功注册 linux 系统中
 83     ldm.dev.fops = &ldm.ops;  //关联文件操作
 84     ldm.ops.open = ldm_open;
 85     ldm.ops.write = ldm_write;
 86     ldm.ops.read = ldm_read;
 87     ldm.ops.release = ldm_release;
 88 
 89 
 90     ret = misc_register(&ldm.dev);
 91 
 92     if(ret < 0) {
 93         printk("misc_register  failed
");
 94         goto  err_misc_register;
 95     }
 96 
 97     return 0;
 98 err_misc_register:
 99     return ret;
100 
101 }
102 
103 //卸载
104 static void test_exit(void)
105 {
106     printk("%s:%s:%d   init
", __FILE__, __FUNCTION__, __LINE__);
107 
108 
109     //注销misc 
110     misc_deregister(&ldm.dev);
111     //释放映射的虚拟地址
112 
113 }
114 
115 module_init(test_init);
116 module_exit(test_exit);
117 
118 
119 MODULE_LICENSE("GPL");  //加入GPL许可
原文地址:https://www.cnblogs.com/baoshulin/p/6416251.html