码迷,mamicode.com
首页 > 其他好文 > 详细

十一、编写按键混杂设备驱动(轮询)

时间:2019-01-25 11:36:55      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:image   NPU   temp   寄存器   while   fcntl   轮询   gcc   高电平   

1. 确定硬件连接

  主要电路连接如下:

技术分享图片技术分享图片

  从电路图中可以发现开发板上6个按键连接到了GPN0~5,当按键弹起时IO状态应为高电平,当按键按下时IO口状态为低电平。

2. 确定寄存器

  下图为寄存器的名称和地址:

  技术分享图片

  下图为配置寄存器的描述:

  技术分享图片

  下图为数据寄存器和上/下拉寄存器:

  技术分享图片

  需要注意的是,GPN默认是下拉使能,从电路图中判断按键应该配置为上拉使能,其他没什么好说的。

3. 编写代码

  key.c

 1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/io.h>
 4 #include <linux/fs.h>
 5 #include <linux/miscdevice.h>
 6 #include <asm/uaccess.h>
 7 
 8 #define GPNCON    0x7F008830
 9 #define GPNDAT    0x7F008834
10 #define GPNPUD    0x7F008838
11 
12 static int *__gp_gpndat = NULL;
13 
14 static int key_open (struct inode *p_node, struct file *p_file)
15 {
16     int *p_gpncon = NULL;
17     int *p_gpnpud = NULL;
18     int temp;
19 
20     p_gpncon = ioremap(GPNCON, 4);
21     __gp_gpndat = ioremap(GPNDAT, 4);
22     p_gpnpud = ioremap(GPNPUD, 4);
23 
24     temp = readl(p_gpncon);
25     temp &= ~(0xFFF);
26     writel(temp, p_gpncon);
27 
28     temp = readl(p_gpnpud);
29     temp &= ~(0xFFF);
30     temp |= 0xAAA;
31     writel(temp, p_gpnpud);
32 
33     return 0;
34 }
35 
36 static ssize_t key_read (struct file *p_file, char *p_dat, size_t size, loff_t *p_loff)
37 {
38     int key;
39     char i;
40 
41     key = readl(__gp_gpndat);
42     if ((key & 0x3F) != 0x3F) {
43         for (i = 1; i <= 6; i++) {
44             if ((key & 1) == 0) {
45                 if (copy_to_user(p_dat, &i, 1)) {
46                     return -1;
47                 }
48                 return 1;
49             }
50             key >>= 1;
51         }
52     }
53 
54     return 0;
55 }
56 
57 static struct file_operations fops = {
58     .owner = THIS_MODULE,
59     .open = key_open,
60     .read = key_read,
61 };
62 
63 static struct miscdevice key_dev = {
64     .minor = MISC_DYNAMIC_MINOR,
65     .name = "mykey",
66     .fops = &fops,
67 };
68 
69 static int __init key_init (void)
70 {
71     misc_register(&key_dev);
72 
73     return 0;
74 }
75 
76 static void __exit key_exit (void)
77 {
78     misc_deregister(&key_dev);
79 }
80 
81 module_init(key_init);
82 module_exit(key_exit);
83 
84 MODULE_LICENSE("GPL");

  key_app.c

 1 #include <stdio.h>
 2 #include <sys/types.h>
 3 #include <sys/stat.h>
 4 #include <fcntl.h>
 5 
 6 int main(int argc, const char *argv[])
 7 {
 8     int fd;
 9     char key_val;
10     int key_push_flag = 0;
11     int key_val_temp;
12     int cnt;
13 
14     fd = open("/dev/mykey", O_RDWR);
15 
16     while (1) {
17         cnt = read(fd, &key_val, 1);
18         if ((key_push_flag == 0) && (1 == cnt)) {
19             key_push_flag = 1;
20 
21             key_val_temp = key_val;
22             printf("key %d down\n", key_val_temp);
23         } else if (cnt == 0) {
24             key_push_flag = 0;
25         }
26     }
27 
28     return 0;
29 }

Makefile

 1 obj-m := key.o
 2 KDIR = /home/linux/zkf/6410/urbetter-linux2.6.28-v1.0    
 3 
 4 all:
 5     make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm
 6     arm-none-linux-gnueabi-gcc key_app.c -o key_app
 7     sudo cp key_app ~/zkf/6410/rootfs/home/test
 8     sudo cp key.ko ~/zkf/6410/rootfs/home/test
 9 clean:
10     rm *.o *.mod.c *.symvers *.order

4. 运行

  加载模块:insmod key.ko

  运行key_app,现象如下图:

  技术分享图片

 

十一、编写按键混杂设备驱动(轮询)

标签:image   NPU   temp   寄存器   while   fcntl   轮询   gcc   高电平   

原文地址:https://www.cnblogs.com/Suzkfly/p/10317763.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!