1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <string.h>
8
9 int main(int argc,const char * argv[])
10 {
11 char buf[128] = {0};
12 int fd = -1;
13 fd = open("/dev/myled",O_RDWR);
14 if(fd == -1)
15 {
16 perror("open is error\n");
17 return -1;
18 }
19
20 while(1)
21 {
22 buf[0] = !buf[0];
23 write(fd,buf,1);
24 sleep(1);
25 }
26
27 close(fd);
28 return 0;
29 }
10 #define CNAME "myled"
11 int major;
12
13 int kbuf[128]={};
14 unsigned int* rccp;
15 unsigned int* led1moderp;
16 unsigned int* led1odp;
17
18 unsigned int* led2moderp;
19 unsigned int* led2odp;
20
21 unsigned int* led3moderp;
22 unsigned int* led3odp;
23
24 int (myled_open) (struct inode *inode, struct file *file)
25 {
26 printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
27 return 0;
28 }
29
30 ssize_t (myled_read) (struct file *file, char __user *ubuf, size_t size,loff_t *loff)
31 {
32
33 printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
34 int ret;
35 if(size > sizeof(kbuf)) size = sizeof(kbuf);
36
37 ret=copy_to_user(ubuf,kbuf,size);
38 if(ret)
39 {
40 printk("copy to user is error\n");
41 return -EIO;
42 }
43 return size;
44
45 }
46
47 ssize_t (myled_write) (struct file *file, const char __user *ubuf, size_t size,loff_t *loff)
48 {
49
50 int ret;
51 printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
52 //1.校验传输数据的大小,如果用户空间写的数据比内核空间数据大小大,需要更正大小
53 if(size > sizeof(kbuf)) size = sizeof(kbuf);
54 //2.将数据从用户空间拷贝到内核空间
55 ret = copy_from_user(kbuf,ubuf,size);
56 if(ret) //3.判断是否错误
57 {
58 printk("copy from user is error\n");
59 return -EIO;
60 }
61 //4.打印传递数据内容
62 printk("copy from user kbuf:%s\n",kbuf);
63 if(kbuf[0] == 1)
64 {
65 *led1odp |= (0x1 << 10); //LED1点亮
66 *led2odp |= (0x1 << 10); //LED1点亮
67 *led3odp |= (0x1 << 8); //LED1点亮
68 }
69 else
70 {
71 *led1odp &= (~(0x1 << 10)); //LED1写灭;
72 *led2odp &= (~(0x1 << 10)); //LED1写灭;
73 *led3odp &= (~(0x1 << 8)); //LED1写灭;
74 }
75
76 return size; //5.返回拷贝数据大小
77 }
78
79 int (myled_release) (struct inode *inode, struct file *file)
80 {
81
82 printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
83 }
84
85 const struct file_operations fops=
86 {
87
88 .open=myled_open,
89 .read=myled_read,
90 .write=myled_write,
91 .release=myled_release,
92 };
93
94
95 static int __init demo_init(void)
96 {
97 major=register_chrdev(0,CNAME,&fops);
98
99 if(major<0)
100 {
101 printk("register_chrdev is error\n");
102 }
103 else
104 {
105 printk("register_chrdev is %d\n",major);
106 }
107
108
109
110 rccp=ioremap(RCC,4);
111
112 led1moderp=ioremap(GPIOE_MOD,4);
113
114 led1odp=ioremap(GPIOE_ODR,4);
115
116 led2moderp=ioremap(GPIOF_MOD,4);
117
118 led2odp=ioremap(GPIOF_ODR,4);
119
120 led3moderp=ioremap(GPIOE_MOD,4);
121
122 led3odp=ioremap(GPIOE_ODR,4);
123
124 *rccp |= 0x3<<4;
125 *led1moderp &= (~(0x3<<20));
126 *led1moderp |= ((0x1<<20));
127 *led1odp &= (~(0x1<<10));
128
129 *led2moderp &= (~(0x3<<20));
130 *led2moderp |= ((0x1<<20));
131 *led2odp &= (~(0x1<<10));
132
133 *led3moderp &= (~(0x3<<16));
134 *led3moderp |= ((0x1<<16));
135 *led3odp &= (~(0x1<<8));
136
137
138 return 0;
139 }
140
141 static void __exit demo_exit(void)
142 {
143 iounmap(rccp);
144 iounmap(led1moderp);
145 iounmap(led1odp);
146 iounmap(led2moderp);
147 iounmap(led2odp);
148 iounmap(led3moderp);
149 iounmap(led3odp);
150 unregister_chrdev(major,CNAME);
151 }
152
153
154
155
156
157 module_init(demo_init);
158 module_exit(demo_exit);
159
160 MODULE_LICENSE("GPL");
161
162
这段代码是一个简单的Linux内核设备驱动程序,用于控制LED状态。它打开名为/myled的字符设备,读写操作用于切换LED的状态。内核函数如open、read、write和release被实现。驱动程序还使用ioremap进行内存映射来访问GPIO寄存器以控制LED的亮灭。
167

被折叠的 条评论
为什么被折叠?



