[Linux]查询方式按键驱动
查询方式按键驱动
艾恩凝 2021/3/23
序
按键和led差不多,只不过按键换成了读取操作
程序
驱动程序
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#define BUTTON_MAJOR_NUMBER 200
13#define DEVICE_NAME "button_drv"
14
15static struct class *button_drv_class;
16static struct class_device *button_drv_class_dev;
17
18volatile unsigned long *GPFCON;
19volatile unsigned long *GPFDAT;
20
21volatile unsigned long *GPGCON;
22volatile unsigned long *GPGDAT;
23
24
25static int button_drv_open(struct inode *inode,struct file *file){
26 *GPFCON &= ~((0x3<<(0*2)) | (0x3<<(2*2)));
27 *GPGCON &= ~((0x3<<(3*2)) | (0x3<<(11*2)));
28 return 0;
29}
30
31static ssize_t button_drv_read(struct file *file, const char __user *buf, size_t count, loff_t * ppos){
32 unsigned char key_vals[4];
33 if (count != sizeof(key_vals))
34 return -EINVAL;
35 key_vals[0] = (*GPFDAT & (1<<0)) ? 1 : 0;
36 key_vals[1] = (*GPFDAT & (1<<2)) ? 1 : 0;
37
38 key_vals[2] = (*GPGDAT & (1<<3)) ? 1 : 0;
39 key_vals[3] = (*GPGDAT & (1<<11)) ? 1 : 0;
40
41 copy_to_user(buf, key_vals, sizeof(key_vals));
42 return sizeof(key_vals);
43}
44
45static struct file_operations button_drv_fops = {
46 .owner = THIS_MODULE,
47 .open = button_drv_open,
48 .read = button_drv_read,
49};
50
51static int button_drv_init(void){
52 register_chrdev(BUTTON_MAJOR_NUMBER,DEVICE_NAME, &button_drv_fops);//register tell kernel
53 button_drv_class = class_create(THIS_MODULE, DEVICE_NAME);
54 button_drv_class_dev = class_device_create(button_drv_class, NULL, MKDEV(BUTTON_MAJOR_NUMBER, 0), NULL, DEVICE_NAME);
55
56 GPFCON = (volatile unsigned long *)ioremap(0x56000050, 16);
57 GPFDAT = GPFCON + 1;
58
59 GPGCON = (volatile unsigned long *)ioremap(0x56000060, 16);
60 GPGDAT = GPGCON + 1;
61
62 return 0;
63}
64
65static void button_drv_exit(void){
66 unregister_chrdev(BUTTON_MAJOR_NUMBER, DEVICE_NAME);//unregister tell kernel
67 class_device_unregister(button_drv_class_dev);
68 class_destroy(button_drv_class);
69 iounmap(GPFCON);
70 iounmap(GPGCON);
71}
72
73module_init(button_drv_init);
74module_exit(button_drv_exit);
75MODULE_AUTHOR("https://aeneag.xyz");
76MODULE_VERSION("0.1");
77MODULE_DESCRIPTION("S3C2440 Button Driver");
78MODULE_LICENSE("GPL");
79
测试程序
1
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5#include <stdio.h>
6
7int main(int argc, char **argv)
8{
9 int fd;
10 unsigned char key_vals[4];
11 int cnt = 0;
12 printf("please use ./test_button_drv /dev/button_drv");
13 fd = open(argv[1], O_RDWR);
14 if (fd < 0)
15 {
16 printf("can't open!\n");
17 }
18
19 while (1)
20 {
21 read(fd, key_vals, sizeof(key_vals));
22 if (!key_vals[0] || !key_vals[1] || !key_vals[2] || !key_vals[3])
23 {
24 printf("%04d key pressed: %d %d %d %d\n", cnt++, key_vals[0], key_vals[1], key_vals[2], key_vals[3]);
25 }
26 }
27
28 return 0;
29}
30
31
慢慢搞
吾心信其可行,
则移山填海之难,
终有成功之日!
——孙文
则移山填海之难,
终有成功之日!
——孙文
评论
0 评论