字符设备驱动之按键驱动(轮询)
driver.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/fs.h>
4 #include <linux/init.h>
5 #include <linux/delay.h>
6 #include <asm/uaccess.h>
7 #include <asm/irq.h>
8 #include <asm/io.h>
9 #include <asm/arch/regs-gpio.h>
10 #include <asm/hardware.h>
11
12 static int major;
13
14 static struct class *myKey_class;
15 static struct class_device *myKey_class_dev;
16
17 volatile unsigned long *gpfcon;
18 volatile unsigned long *gpfdat;
19
20 volatile unsigned long *gpgcon;
21 volatile unsigned long *gpgdat;
22
23 static int myKey_open(struct inode *inode, struct file *file);
24 static ssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos);
25
26 static struct file_operations myKey_fops = {
27 .open = myKey_open,
28 .read = myKey_read,
29 .owner = THIS_MODULE,
30 };
31
32 static int myKey_open(struct inode *inode, struct file *file)
33 {
34 /* 初始化Key硬件 —— GPF0、GPF2、GPG11设置为输入 */
35 *gpfcon &= ~((0x3<<(0*2)) | (0x3<<(2*2)));
36 *gpgcon &= ~(0x3<<(11*2));
37
38 return 0;
39 }
40
41
42 static ssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
43 {
44 int regVal;
45 char keyVal[3];
46
47 regVal = *gpfdat;
48 keyVal[0] = (regVal&(1<<0)) ? 1 : 0;
49 keyVal[1] = (regVal&(1<<2)) ? 1 : 0;
50
51 regVal = *gpgdat;
52 keyVal[2] = (regVal&(1<<11)) ? 1 : 0;
53
54 copy_to_user(buf, keyVal, sizeof(keyVal));
55 return 0;
56 }
57
58 static int __init myKey_init(void)
59 {
60 /* 物理地址映射成虚拟地址 */
61 gpfcon = (volatile unsigned long*)ioremap(0x56000050, 16);
62 gpfdat = gpfcon + 1;
63
64 gpgcon = (volatile unsigned long*)ioremap(0x56000060, 16);
65 gpgdat = gpgcon + 1;
6
67 major = register_chrdev(0, "myKey", &myKey_fops);
68
69 myKey_class = class_create(THIS_MODULE, "myKeyclass");
70 myKey_class_dev = class_device_create(myKey_class, NULL, MKDEV(major, 0), NULL, "myKey");
71
72 return 0;
73 }
74
75 static void __exit myKey_exit(void)
76 {
77 /* 释放虚拟地址映射 */
78 iounmap(0x56000050);
79 iounmap(0x56000060);
80
81 unregister_chrdev(major, "myKey");
82
83 class_device_unregister(myKey_class_dev);
84 class_destroy(myKey_class);
85 return;
86 }
87
88 module_init(myKey_init);
89 module_exit(myKey_exit);
90
91 MODULE_LICENSE("GPL"
app.c
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <fcntl.h>
4 #include <stdio.h>
5
6 int main (void)
7 {
8 int fd;
9 char keyVal[3];
10 ssize_t rst;
11
12 printf("test app!\n");
13
14 fd = open("/dev/myKey", O_RDWR);
15 if(fd < 0)
16 {
17 printf("open failed! %d\n", fd);
18 return -1;
19 }
20
21 while(1)
22 {
23 rst = read(fd, keyVal, sizeof(keyVal));
24 if (rst < 0)
25 {
26 printf("read failed!\n");
27 continue;
28 }
29 if (!(keyVal[0] && keyVal[1] && keyVal[2]))
30 {
31 if (!keyVal[0])
32 {
33 printf("S1\n");
34 }
35 else if (!keyVal[1])
36 {
37 printf("S2\n");
38 }
39 else {
40 printf("S3\n");
41 }
42 }
43 }
44 return 0;
45 }
Makefile
1 KERN_DIR = /work/system/linux-2.6.22.6
2
3 all:
4 make -C $(KERN_DIR) M=`pwd` modules
5
6 clean:
7 make -C $(KERN_DIR) M=`pwd` modules clean
8 rm -rf modules.order
9
10 obj-m += myKey_poll.o