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\n"); 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\n", 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\n", 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\n"); 71 return 0; 72 } 73 74 static int test_init(void) 75 { 76 int ret = 0; 77 78 printk("%s:%s:%d init\n", __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\n"); 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\n", __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许可