字符设备驱动之按键驱动(轮询)

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! ");
13
14         fd = open("/dev/myKey", O_RDWR);
15         if(fd < 0)
16         {
17                 printf("open failed! %d ", 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! ");
27                         continue;
28                 }
29                 if (!(keyVal[0] && keyVal[1] && keyVal[2]))
30                 {
31                         if (!keyVal[0])
32                         {
33                                 printf("S1 ");
34                         }
35                         else if (!keyVal[1])
36                         {
37                                 printf("S2 ");
38                         }
39                         else {
40                                 printf("S3 ");
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

原文地址:https://www.cnblogs.com/lilto/p/11878121.html