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许可